From cdb11fc5ebea67dfba4a403075dc9600cfb62792 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 1 Dec 2003 08:04:51 +0000 Subject: [PATCH] add administrative bind and proxyAuthz control to enable bound operations in distributed directories (need to manually #define LDAP_BACK_PROXY_AUTHZ and patches from ITS#2851 and ITS#2852) --- servers/slapd/back-ldap/add.c | 34 ++++++- servers/slapd/back-ldap/back-ldap.h | 9 ++ servers/slapd/back-ldap/bind.c | 138 +++++++++++++++++++++++++++- servers/slapd/back-ldap/compare.c | 41 ++++++++- servers/slapd/back-ldap/delete.c | 37 +++++++- servers/slapd/back-ldap/extended.c | 33 +++++++ servers/slapd/back-ldap/modify.c | 31 ++++++- servers/slapd/back-ldap/modrdn.c | 35 ++++++- servers/slapd/back-ldap/search.c | 51 ++++++---- 9 files changed, 376 insertions(+), 33 deletions(-) diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c index c3ab9f3d2c..cdb33521aa 100644 --- a/servers/slapd/back-ldap/add.c +++ b/servers/slapd/back-ldap/add.c @@ -73,6 +73,10 @@ ldap_back_add( struct berval mdn = { 0, NULL }; ber_int_t msgid; dncookie dc; +#ifdef LDAP_BACK_PROXY_AUTHZ + LDAPControl **ctrls = NULL; + int rc = LDAP_SUCCESS; +#endif /* LDAP_BACK_PROXY_AUTHZ */ #ifdef NEW_LOGGING LDAP_LOG( BACK_LDAP, ENTRY, "ldap_back_add: %s\n", op->o_req_dn.bv_val, 0, 0 ); @@ -149,8 +153,29 @@ ldap_back_add( } attrs[i] = NULL; +#ifdef LDAP_BACK_PROXY_AUTHZ + rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls ); + if ( rc != LDAP_SUCCESS ) { + goto cleanup; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + rs->sr_err = ldap_add_ext(lc->ld, mdn.bv_val, attrs, - op->o_ctrls, NULL, &msgid); +#ifdef LDAP_BACK_PROXY_AUTHZ + ctrls, +#else /* ! LDAP_BACK_PROXY_AUTHZ */ + op->o_ctrls, +#endif /* ! LDAP_BACK_PROXY_AUTHZ */ + NULL, &msgid); + +#ifdef LDAP_BACK_PROXY_AUTHZ +cleanup: + if ( ctrls && ctrls != op->o_ctrls ) { + free( ctrls[ 0 ] ); + free( ctrls ); + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + for (--i; i>= 0; --i) { ch_free(attrs[i]->mod_vals.modv_bvals); ch_free(attrs[i]); @@ -159,7 +184,12 @@ ldap_back_add( if ( mdn.bv_val != op->o_req_dn.bv_val ) { free( mdn.bv_val ); } - +#ifdef LDAP_BACK_PROXY_AUTHZ + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( op, rs ); + return -1; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ return ldap_back_op_result( lc, op, rs, msgid, 1 ) != LDAP_SUCCESS; } diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index d7ded8a64b..cc6f2ecbde 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -210,6 +210,15 @@ extern int ldap_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals ); extern int ldap_chain_setup(); +#ifdef LDAP_BACK_PROXY_AUTHZ +extern int +ldap_back_proxy_authz_ctrl( + struct ldapconn *lc, + Operation *op, + SlapReply *rs, + LDAPControl ***pctrls ); +#endif /* LDAP_BACK_PROXY_AUTHZ */ + LDAP_END_DECL #endif /* SLAPD_LDAP_H */ diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 91f5be651c..483f0771f5 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -404,13 +404,52 @@ ldap_back_getconn(Operation *op, SlapReply *rs) int ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs ) { + struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; int rc; ber_int_t msgid; ldap_pvt_thread_mutex_lock( &lc->lc_mutex ); if ( !lc->bound ) { - rs->sr_err = ldap_sasl_bind(lc->ld, lc->bound_dn.bv_val, - LDAP_SASL_SIMPLE, &lc->cred, NULL, NULL, &msgid); +#ifdef LDAP_BACK_PROXY_AUTHZ + int gotit = 0; +#if 0 + int i; + + /* + * FIXME: we need to let clients use proxyAuthz + * otherwise we cannot do symmetric pools of servers; + * we have to live with the fact that a user can + * authorize itself as any ID that is allowed + * by the saslAuthzTo directive of the "binddn". + */ + for ( i = 0; op->o_ctrls && op->o_ctrls[ i ]; i++ ) { + if ( strcmp( op->o_ctrls[i]->ldctl_oid, LDAP_CONTROL_PROXY_AUTHZ ) == 0 ) { + gotit = 1; + break; + } + } +#endif + + /* + * if no bind took place yet, but the connection is bound + * and the binddn is set, then bind with binddn and + * explicitly add proxyAuthz control to every operation + * with the dn bound to the connection as control value. + */ + if ( ( lc->bound_dn.bv_val == NULL || lc->bound_dn.bv_len == 0 ) + && ( op->o_conn && op->o_conn->c_dn.bv_val != NULL && op->o_conn->c_dn.bv_len != 0 ) + && ( li->binddn.bv_val != NULL && li->binddn.bv_len != 0 ) + && ! gotit ) { + rs->sr_err = ldap_sasl_bind(lc->ld, li->binddn.bv_val, + LDAP_SASL_SIMPLE, &li->bindpw, NULL, NULL, &msgid); + + } else +#endif /* LDAP_BACK_PROXY_AUTHZ */ + { + rs->sr_err = ldap_sasl_bind(lc->ld, lc->bound_dn.bv_val, + LDAP_SASL_SIMPLE, &lc->cred, NULL, NULL, &msgid); + } + rc = ldap_back_op_result( lc, op, rs, msgid, 0 ); if (rc == LDAP_SUCCESS) { lc->bound = 1; @@ -550,3 +589,98 @@ ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs, return( (rs->sr_err == LDAP_SUCCESS) ? 0 : -1 ); } +#ifdef LDAP_BACK_PROXY_AUTHZ +/* + * ldap_back_proxy_authz_ctrl() prepends a proxyAuthz control + * to existing server-side controls if required; if not, + * the existing server-side controls are placed in *pctrls. + * The caller, after using the controls in client API + * operations, if ( *pctrls != op->o_ctrls ), should + * free( (*pctrls)[ 0 ] ) and free( *pctrls ). + * The function returns success if the control could + * be added if required, or if it did nothing; in the future, + * it might return some error if it failed. + * + * if no bind took place yet, but the connection is bound + * and the binddn is set, then bind with binddn and + * explicitly add proxyAuthz control to every operation + * with the dn bound to the connection as control value. + * + * If no server-side controls are defined for the operation, + * simply add the proxyAuthz control; otherwise, if the + * proxyAuthz control is not already set, add it as + * the first one (FIXME: is controls order significant + * for security?). + */ +int +ldap_back_proxy_authz_ctrl( + struct ldapconn *lc, + Operation *op, + SlapReply *rs, + LDAPControl ***pctrls ) +{ + struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; + LDAPControl **ctrls = NULL; + + *pctrls = NULL; + + if ( ( lc->bound_dn.bv_val == NULL || lc->bound_dn.bv_len == 0 ) + && ( op->o_conn && op->o_conn->c_dn.bv_val != NULL && op->o_conn->c_dn.bv_len != 0 ) + && ( li->binddn.bv_val != NULL && li->binddn.bv_len != 0 ) ) { + int i = 0, gotit = 0; + + if ( op->o_ctrls ) { + for ( i = 0; op->o_ctrls[i]; i++ ) { + if ( strcmp( op->o_ctrls[i]->ldctl_oid, LDAP_CONTROL_PROXY_AUTHZ ) == 0 ) { + gotit = 1; + break; + } + } + } + + if ( ! gotit ) { + ctrls = ch_malloc( sizeof( LDAPControl * ) * (i + 2) ); + ctrls[ 0 ] = ch_malloc( sizeof( LDAPControl ) ); + + ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ; + ctrls[ 0 ]->ldctl_iscritical = 1; + ctrls[ 0 ]->ldctl_value.bv_len = op->o_conn->c_dn.bv_len + 3; + ctrls[ 0 ]->ldctl_value.bv_val = ch_malloc( ctrls[ 0 ]->ldctl_value.bv_len + 1 ); + AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val, "dn:", sizeof( "dn:" ) - 1 ); + AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val + sizeof( "dn:") - 1, + op->o_conn->c_dn.bv_val, op->o_conn->c_dn.bv_len + 1 ); + + if ( op->o_ctrls ) { + for ( i = 0; op->o_ctrls[ i ]; i++ ) { + ctrls[ i + 1 ] = op->o_ctrls[ i ]; + } + } + ctrls[ i + 1 ] = NULL; + + } else { + /* + * FIXME: we do not want to perform proxyAuthz + * on behalf of the client, because this would + * be performed with "binddn" privileges. + * + * This might actually be too strict, since + * the "binddn" saslAuthzTo, and each entry's + * saslAuthzFrom attributes may be crafted + * to avoid unwanted proxyAuthz to take place. + */ +#if 0 + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + rs->sr_text = "proxyAuthz not allowed within namingContext"; +#endif + } + } + + if ( ctrls == NULL ) { + ctrls = op->o_ctrls; + } + + *pctrls = ctrls; + + return rs->sr_err; +} +#endif /* LDAP_BACK_PROXY_AUTHZ */ diff --git a/servers/slapd/back-ldap/compare.c b/servers/slapd/back-ldap/compare.c index 9ca34771c7..8a6f8396b1 100644 --- a/servers/slapd/back-ldap/compare.c +++ b/servers/slapd/back-ldap/compare.c @@ -66,11 +66,15 @@ ldap_back_compare( { struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; struct ldapconn *lc; - struct berval mapped_at, mapped_val; + struct berval mapped_at = { 0, NULL }, mapped_val = { 0, NULL }; struct berval mdn = { 0, NULL }; ber_int_t msgid; int freeval = 0; dncookie dc; +#ifdef LDAP_BACK_PROXY_AUTHZ + LDAPControl **ctrls = NULL; + int rc = LDAP_SUCCESS; +#endif /* LDAP_BACK_PROXY_AUTHZ */ lc = ldap_back_getconn(op, rs); if (!lc || !ldap_back_dobind( lc, op, rs ) ) { @@ -119,18 +123,47 @@ ldap_back_compare( } else if (mapped_val.bv_val != op->orc_ava->aa_value.bv_val) { freeval = 1; } + } else { + mapped_val = op->orc_ava->aa_value; } } - rs->sr_err = ldap_compare_ext( lc->ld, mdn.bv_val, mapped_at.bv_val, - &mapped_val, op->o_ctrls, NULL, &msgid ); +#ifdef LDAP_BACK_PROXY_AUTHZ + rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls ); + if ( rc != LDAP_SUCCESS ) { + goto cleanup; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + + rs->sr_err = ldap_compare_ext( lc->ld, mdn.bv_val, + mapped_at.bv_val, &mapped_val, +#ifdef LDAP_BACK_PROXY_AUTHZ + ctrls, +#else /* ! LDAP_BACK_PROXY_AUTHZ */ + op->o_ctrls, +#endif /* ! LDAP_BACK_PROXY_AUTHZ */ + NULL, &msgid ); +#ifdef LDAP_BACK_PROXY_AUTHZ +cleanup: + if ( ctrls && ctrls != op->o_ctrls ) { + free( ctrls[ 0 ] ); + free( ctrls ); + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + if ( mdn.bv_val != op->o_req_dn.bv_val ) { free( mdn.bv_val ); } if ( freeval ) { free( mapped_val.bv_val ); } - + +#ifdef LDAP_BACK_PROXY_AUTHZ + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( op, rs ); + return -1; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ return( ldap_back_op_result( lc, op, rs, msgid, 1 ) ); } diff --git a/servers/slapd/back-ldap/delete.c b/servers/slapd/back-ldap/delete.c index 6db914ffd9..a624eeae23 100644 --- a/servers/slapd/back-ldap/delete.c +++ b/servers/slapd/back-ldap/delete.c @@ -68,6 +68,10 @@ ldap_back_delete( struct ldapconn *lc; ber_int_t msgid; dncookie dc; +#ifdef LDAP_BACK_PROXY_AUTHZ + LDAPControl **ctrls = NULL; + int rc = LDAP_SUCCESS; +#endif /* LDAP_BACK_PROXY_AUTHZ */ struct berval mdn = { 0, NULL }; @@ -93,13 +97,40 @@ ldap_back_delete( send_ldap_result( op, rs ); return -1; } - - rs->sr_err = ldap_delete_ext( lc->ld, mdn.bv_val, op->o_ctrls, + +#ifdef LDAP_BACK_PROXY_AUTHZ + rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls ); + if ( rc != LDAP_SUCCESS ) { + goto cleanup; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + + rs->sr_err = ldap_delete_ext( lc->ld, mdn.bv_val, +#ifdef LDAP_BACK_PROXY_AUTHZ + ctrls, +#else /* ! LDAP_BACK_PROXY_AUTHZ */ + op->o_ctrls, +#endif /* ! LDAP_BACK_PROXY_AUTHZ */ NULL, &msgid ); +#ifdef LDAP_BACK_PROXY_AUTHZ +cleanup: + if ( ctrls && ctrls != op->o_ctrls ) { + free( ctrls[ 0 ] ); + free( ctrls ); + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + if ( mdn.bv_val != op->o_req_dn.bv_val ) { free( mdn.bv_val ); } - + +#ifdef LDAP_BACK_PROXY_AUTHZ + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( op, rs ); + return -1; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + return( ldap_back_op_result( lc, op, rs, msgid, 1 ) ); } diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index caac505823..364d8905f9 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -48,7 +48,40 @@ ldap_back_extended( for( i=0; exop_table[i].extended != NULL; i++ ) { if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) { +#ifdef LDAP_BACK_PROXY_AUTHZ + struct ldapconn *lc; + LDAPControl **oldctrls = NULL; + int rc; + + /* FIXME: this needs to be called here, so it is + * called twice; maybe we could avoid the + * ldap_back_dobind() call inside each extended() + * call ... */ + lc = ldap_back_getconn(op, rs); + if (!lc || !ldap_back_dobind(lc, op, rs) ) { + return -1; + } + + oldctrls = op->o_ctrls; + if ( ldap_back_proxy_authz_ctrl( lc, op, rs, &op->o_ctrls ) ) { + op->o_ctrls = oldctrls; + send_ldap_result( op, rs ); + rs->sr_text = NULL; + return rs->sr_err; + } + + rc = (exop_table[i].extended)( op, rs ); + + if ( op->o_ctrls && op->o_ctrls != oldctrls ) { + free( op->o_ctrls[ 0 ] ); + free( op->o_ctrls ); + } + op->o_ctrls = oldctrls; + + return rc; +#else /* ! LDAP_BACK_PROXY_AUTHZ */ return (exop_table[i].extended)( op, rs ); +#endif /* ! LDAP_BACK_PROXY_AUTHZ */ } } diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c index fa1b8625e0..c6a45a8e98 100644 --- a/servers/slapd/back-ldap/modify.c +++ b/servers/slapd/back-ldap/modify.c @@ -74,6 +74,9 @@ ldap_back_modify( struct berval mdn = { 0, NULL }; ber_int_t msgid; dncookie dc; +#ifdef LDAP_BACK_PROXY_AUTHZ + LDAPControl **ctrls = NULL; +#endif /* LDAP_BACK_PROXY_AUTHZ */ lc = ldap_back_getconn(op, rs); if ( !lc || !ldap_back_dobind( lc, op, rs ) ) { @@ -181,10 +184,29 @@ ldap_back_modify( } modv[i] = 0; +#ifdef LDAP_BACK_PROXY_AUTHZ + rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls ); + if ( rc != LDAP_SUCCESS ) { + goto cleanup; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + rs->sr_err = ldap_modify_ext( lc->ld, mdn.bv_val, modv, - op->o_ctrls, NULL, &msgid ); +#ifdef LDAP_BACK_PROXY_AUTHZ + ctrls, +#else /* ! LDAP_BACK_PROXY_AUTHZ */ + op->o_ctrls, +#endif /* ! LDAP_BACK_PROXY_AUTHZ */ + NULL, &msgid ); cleanup:; +#ifdef LDAP_BACK_PROXY_AUTHZ + if ( ctrls && ctrls != op->o_ctrls ) { + free( ctrls[ 0 ] ); + free( ctrls ); + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + if ( mdn.bv_val != op->o_req_dn.bv_val ) { free( mdn.bv_val ); } @@ -194,6 +216,13 @@ cleanup:; ch_free( mods ); ch_free( modv ); +#ifdef LDAP_BACK_PROXY_AUTHZ + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( op, rs ); + return -1; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + return ldap_back_op_result( lc, op, rs, msgid, 1 ); } diff --git a/servers/slapd/back-ldap/modrdn.c b/servers/slapd/back-ldap/modrdn.c index 6039c919ad..cf5154560f 100644 --- a/servers/slapd/back-ldap/modrdn.c +++ b/servers/slapd/back-ldap/modrdn.c @@ -68,6 +68,10 @@ ldap_back_modrdn( struct ldapconn *lc; ber_int_t msgid; dncookie dc; +#ifdef LDAP_BACK_PROXY_AUTHZ + LDAPControl **ctrls = NULL; + int rc = LDAP_SUCCESS; +#endif /* LDAP_BACK_PROXY_AUTHZ */ struct berval mdn = { 0, NULL }, mnewSuperior = { 0, NULL }; @@ -112,11 +116,31 @@ ldap_back_modrdn( return -1; } +#ifdef LDAP_BACK_PROXY_AUTHZ + rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls ); + if ( rc != LDAP_SUCCESS ) { + goto cleanup; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + rs->sr_err = ldap_rename( lc->ld, mdn.bv_val, op->orr_newrdn.bv_val, mnewSuperior.bv_val, - op->orr_deleteoldrdn, op->o_ctrls, + op->orr_deleteoldrdn, +#ifdef LDAP_BACK_PROXY_AUTHZ + ctrls, +#else /* ! LDAP_BACK_PROXY_AUTHZ */ + op->o_ctrls, +#endif /* ! LDAP_BACK_PROXY_AUTHZ */ NULL, &msgid ); +#ifdef LDAP_BACK_PROXY_AUTHZ +cleanup: + if ( ctrls && ctrls != op->o_ctrls ) { + free( ctrls[ 0 ] ); + free( ctrls ); + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + if ( mdn.bv_val != op->o_req_dn.bv_val ) { free( mdn.bv_val ); } @@ -124,7 +148,14 @@ ldap_back_modrdn( && mnewSuperior.bv_val != op->oq_modrdn.rs_newSup->bv_val ) { free( mnewSuperior.bv_val ); } - + +#ifdef LDAP_BACK_PROXY_AUTHZ + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( op, rs ); + return -1; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + return( ldap_back_op_result( lc, op, rs, msgid, 1 ) ); } diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index d1a68fcff4..53bd63dd5d 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -88,7 +88,11 @@ ldap_back_search( struct berval mfilter = { 0, NULL }; struct slap_limits_set *limit = NULL; int isroot = 0; + int dontfreetext = 0; dncookie dc; +#ifdef LDAP_BACK_PROXY_AUTHZ + LDAPControl **ctrls = NULL; +#endif /* LDAP_BACK_PROXY_AUTHZ */ lc = ldap_back_getconn(op, rs); if ( !lc ) { @@ -181,6 +185,7 @@ ldap_back_search( if ( rc ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "Rewrite error"; + dontfreetext = 1; rc = -1; goto finish; } @@ -193,27 +198,26 @@ ldap_back_search( goto finish; } -#if 0 - if ( mapped_attrs == NULL && op->oq_search.rs_attrs) { - int count; - - /* this can happen only if ch_calloc() fails - * in ldap_back_map_attrs() */ - for (count=0; op->oq_search.rs_attrs[count].an_name.bv_val; count++); - mapped_attrs = ch_malloc( (count+1) * sizeof(char *)); - for (count=0; op->oq_search.rs_attrs[count].an_name.bv_val; count++) { - mapped_attrs[count] = op->oq_search.rs_attrs[count].an_name.bv_val; - } - mapped_attrs[count] = NULL; +#ifdef LDAP_BACK_PROXY_AUTHZ + rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls ); + if ( rc != LDAP_SUCCESS ) { + dontfreetext = 1; + goto finish; } -#endif - +#endif /* LDAP_BACK_PROXY_AUTHZ */ + rs->sr_err = ldap_search_ext(lc->ld, mbase.bv_val, op->oq_search.rs_scope, mfilter.bv_val, mapped_attrs, op->oq_search.rs_attrsonly, - op->o_ctrls, NULL, +#ifdef LDAP_BACK_PROXY_AUTHZ + ctrls, +#else /* ! LDAP_BACK_PROXY_AUTHZ */ + op->o_ctrls, +#endif /* ! LDAP_BACK_PROXY_AUTHZ */ + NULL, tv.tv_sec ? &tv : NULL, op->oq_search.rs_slimit, - &msgid); + &msgid ); + if ( rs->sr_err != LDAP_SUCCESS ) { fail:; rc = ldap_back_op_result(lc, op, rs, msgid, 0); @@ -347,6 +351,13 @@ fail:; finish:; send_ldap_result( op, rs ); +#ifdef LDAP_BACK_PROXY_AUTHZ + if ( ctrls && ctrls != op->o_ctrls ) { + free( ctrls[ 0 ] ); + free( ctrls ); + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ + if ( match.bv_val ) { if ( rs->sr_matched != match.bv_val ) { free( (char *)rs->sr_matched ); @@ -355,7 +366,9 @@ finish:; LDAP_FREE( match.bv_val ); } if ( rs->sr_text ) { - LDAP_FREE( (char *)rs->sr_text ); + if ( !dontfreetext ) { + LDAP_FREE( (char *)rs->sr_text ); + } rs->sr_text = NULL; } if ( mapped_attrs ) { @@ -536,7 +549,6 @@ ldap_build_entry( } else if ( attr->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) { ldap_dnattr_result_rewrite( &dc, attr->a_vals ); - } if ( normalize && last && attr->a_desc->ad_type->sat_equality && @@ -560,6 +572,7 @@ ldap_build_entry( *attrp = attr; attrp = &attr->a_next; } + /* make sure it's free'able */ if (!private && ent->e_name.bv_val == bdn->bv_val) ber_dupbv( &ent->e_name, bdn ); @@ -646,7 +659,7 @@ ldap_back_entry_get( *ptr++ = ')'; *ptr++ = '\0'; } - + if (ldap_search_ext_s(lc->ld, mdn.bv_val, LDAP_SCOPE_BASE, filter, gattr, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result) != LDAP_SUCCESS) -- 2.39.5