From: Pierangelo Masarati Date: Fri, 14 Jan 2005 00:39:24 +0000 (+0000) Subject: plug memory leak: bsi_attrs member X-Git-Tag: OPENLDAP_REL_ENG_2_3_BP~387 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=014ee81c340d03011ba92d940c7936294f6d12f4;p=openldap plug memory leak: bsi_attrs member use tmpmemctx for bsi_attrs (should be used more for temporaries) fix ITS#3480: allow to fetch all attrs or provide hints fixed access check to entry for rename TODO: fetch entries for access checking in selected code portions (e.g. rename) --- diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index b44bf0701d..e3dad04a34 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -353,14 +353,14 @@ typedef struct backsql_at_map_rec { * (currently broken) */ /* #define BACKSQL_UPPERCASE_FILTER */ -#define BACKSQL_AT_CANUPPERCASE(at) ((at)->bam_sel_expr_u.bv_val) +#define BACKSQL_AT_CANUPPERCASE(at) ( !BER_BVISNULL( &(at)->bam_sel_expr_u ) ) /* defines to support bitmasks above */ #define BACKSQL_ADD 0x1 #define BACKSQL_DEL 0x2 -#define BACKSQL_IS_ADD(x) ( BACKSQL_ADD & (x) ) -#define BACKSQL_IS_DEL(x) ( BACKSQL_DEL & (x) ) +#define BACKSQL_IS_ADD(x) ( ( BACKSQL_ADD & (x) ) == BACKSQL_ADD ) +#define BACKSQL_IS_DEL(x) ( ( BACKSQL_DEL & (x) ) == BACKSQL_DEL ) #define BACKSQL_NCMP(v1,v2) ber_bvcmp((v1),(v2)) @@ -373,7 +373,7 @@ typedef struct berbuf { ber_len_t bb_len; } BerBuffer; -#define BB_NULL { { 0, NULL }, 0 } +#define BB_NULL { BER_BVNULL, 0 } typedef struct backsql_srch_info { Operation *bsi_op; @@ -388,6 +388,10 @@ typedef struct backsql_srch_info { #define BSQL_SF_FILTER_ENTRYUUID 0x0020U #define BSQL_SF_FILTER_ENTRYCSN 0x0040U #define BSQL_SF_RETURN_ENTRYUUID (BSQL_SF_FILTER_ENTRYUUID << 8) +#define BSQL_ISF(bsi, f) ( ( (bsi)->bsi_flags & f ) == f ) +#define BSQL_ISF_ALL_USER(bsi) BSQL_ISF(bsi, BSQL_SF_ALL_USER) +#define BSQL_ISF_ALL_OPER(bsi) BSQL_ISF(bsi, BSQL_SF_ALL_OPER) +#define BSQL_ISF_ALL_ATTRS(bsi) BSQL_ISF(bsi, BSQL_SF_ALL_ATTRS) struct berval *bsi_base_ndn; int bsi_use_subtree_shortcut; @@ -426,7 +430,7 @@ typedef struct backsql_srch_info { /* * Backend private data structure */ -typedef struct { +typedef struct backsql_info { char *sql_dbhost; int sql_dbport; char *sql_dbuser; @@ -456,9 +460,10 @@ typedef struct { struct berval sql_upper_func_open; struct berval sql_upper_func_close; BerVarray sql_concat_func; - struct berval sql_strcast_func; + AttributeName *sql_anlist; + unsigned int sql_flags; #define BSQLF_SCHEMA_LOADED 0x0001 #define BSQLF_UPPER_NEEDS_CAST 0x0002 @@ -469,27 +474,39 @@ typedef struct { #define BSQLF_USE_REVERSE_DN 0x0040 #define BSQLF_ALLOW_ORPHANS 0x0080 #define BSQLF_USE_SUBTREE_SHORTCUT 0x0100 +#define BSQLF_FETCH_ALL_USERATTRS 0x0200 +#define BSQLF_FETCH_ALL_OPATTRS 0x0400 +#define BSQLF_FETCH_ALL_ATTRS (BSQLF_FETCH_ALL_USERATTRS|BSQLF_FETCH_ALL_OPATTRS) + +#define BACKSQL_ISF(si, f) \ + (((si)->sql_flags & f) == f) #define BACKSQL_SCHEMA_LOADED(si) \ - ((si)->sql_flags & BSQLF_SCHEMA_LOADED) + BACKSQL_ISF(si, BSQLF_SCHEMA_LOADED) #define BACKSQL_UPPER_NEEDS_CAST(si) \ - ((si)->sql_flags & BSQLF_UPPER_NEEDS_CAST) + BACKSQL_ISF(si, BSQLF_UPPER_NEEDS_CAST) #define BACKSQL_CREATE_NEEDS_SELECT(si) \ - ((si)->sql_flags & BSQLF_CREATE_NEEDS_SELECT) + BACKSQL_ISF(si, BSQLF_CREATE_NEEDS_SELECT) #define BACKSQL_FAIL_IF_NO_MAPPING(si) \ - ((si)->sql_flags & BSQLF_FAIL_IF_NO_MAPPING) + BACKSQL_ISF(si, BSQLF_FAIL_IF_NO_MAPPING) #define BACKSQL_HAS_LDAPINFO_DN_RU(si) \ - ((si)->sql_flags & BSQLF_HAS_LDAPINFO_DN_RU) + BACKSQL_ISF(si, BSQLF_HAS_LDAPINFO_DN_RU) #define BACKSQL_DONTCHECK_LDAPINFO_DN_RU(si) \ - ((si)->sql_flags & BSQLF_DONTCHECK_LDAPINFO_DN_RU) + BACKSQL_ISF(si, BSQLF_DONTCHECK_LDAPINFO_DN_RU) #define BACKSQL_USE_REVERSE_DN(si) \ - ((si)->sql_flags & BSQLF_USE_REVERSE_DN) + BACKSQL_ISF(si, BSQLF_USE_REVERSE_DN) #define BACKSQL_CANUPPERCASE(si) \ (!BER_BVISNULL( &(si)->sql_upper_func )) #define BACKSQL_ALLOW_ORPHANS(si) \ - ((si)->sql_flags & BSQLF_ALLOW_ORPHANS) + BACKSQL_ISF(si, BSQLF_ALLOW_ORPHANS) #define BACKSQL_USE_SUBTREE_SHORTCUT(si) \ - ((si)->sql_flags & BSQLF_USE_SUBTREE_SHORTCUT) + BACKSQL_ISF(si, BSQLF_USE_SUBTREE_SHORTCUT) +#define BACKSQL_FETCH_ALL_USERATTRS(si) \ + BACKSQL_ISF(si, BSQLF_FETCH_ALL_USERATTRS) +#define BACKSQL_FETCH_ALL_OPATTRS(si) \ + BACKSQL_ISF(si, BSQLF_FETCH_ALL_OPATTRS) +#define BACKSQL_FETCH_ALL_ATTRS(si) \ + BACKSQL_ISF(si, BSQLF_FETCH_ALL_ATTRS) Entry *sql_baseObject; #ifdef BACKSQL_ARBITRARY_KEY diff --git a/servers/slapd/back-sql/bind.c b/servers/slapd/back-sql/bind.c index 6044cdf7b8..96c06fdd1e 100644 --- a/servers/slapd/back-sql/bind.c +++ b/servers/slapd/back-sql/bind.c @@ -118,10 +118,14 @@ error_return:; (void)backsql_free_entryID( &bsi.bsi_base_id, 0 ); } - if ( e ) { + if ( e != NULL ) { entry_clean( e ); } + if ( bsi.bsi_attrs != NULL ) { + op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); + } + if ( rs->sr_err ) { send_ldap_result( op, rs ); return 1; diff --git a/servers/slapd/back-sql/compare.c b/servers/slapd/back-sql/compare.c index 7381ecc057..0f58137466 100644 --- a/servers/slapd/back-sql/compare.c +++ b/servers/slapd/back-sql/compare.c @@ -163,6 +163,10 @@ return_results:; entry_clean( e ); } + if ( bsi.bsi_attrs != NULL ) { + op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); + } + Debug(LDAP_DEBUG_TRACE,"<==backsql_compare()\n",0,0,0); switch ( rs->sr_err ) { case LDAP_COMPARE_TRUE: diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index 9efdb0ae52..c45c70716e 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -496,6 +496,71 @@ backsql_db_config( BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ? "yes" : "no", 0, 0 ); + } else if ( !strcasecmp( argv[ 0 ], "fetch_all_attrs") ) { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing { yes | no }" + "in \"fetch_all_attrs\" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { + bi->sql_flags |= BSQLF_FETCH_ALL_ATTRS; + + } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { + bi->sql_flags &= ~BSQLF_FETCH_ALL_ATTRS; + + } else { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "\"fetch_all_attrs\" directive arg " + "must be \"yes\" or \"no\"\n", + fname, lineno, 0 ); + return 1; + + } + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "fetch_all_attrs=%s\n", + BACKSQL_FETCH_ALL_ATTRS( bi ) ? "yes" : "no", + 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "fetch_attrs") ) { + char *str, *s, *next; + char delimstr[] = ","; + + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing " + "in \"fetch_all_attrs \" directive\n", + fname, lineno, 0 ); + return 1; + } + + str = ch_strdup( argv[ 1 ] ); + for ( s = ldap_pvt_strtok( str, delimstr, &next ); + s != NULL; + s = ldap_pvt_strtok( NULL, delimstr, &next ) ) + { + if ( strlen( s ) == 1 ) { + if ( *s == '*' ) { + bi->sql_flags |= BSQLF_FETCH_ALL_USERATTRS; + argv[ 1 ][ s - str ] = ','; + + } else if ( *s == '+' ) { + bi->sql_flags |= BSQLF_FETCH_ALL_OPATTRS; + argv[ 1 ][ s - str ] = ','; + } + } + } + ch_free( str ); + bi->sql_anlist = str2anlist( bi->sql_anlist, argv[ 1 ], delimstr ); + if ( bi->sql_anlist == NULL ) { + return -1; + } + } else { return SLAP_CONF_UNKNOWN; } diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index 48eb0f2f72..cf5de2117f 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -140,6 +140,16 @@ backsql_db_destroy( free( bi->sql_delobjclasses_stmt ); free( bi->sql_delreferrals_stmt ); + if ( bi->sql_anlist ) { + int i; + + for ( i = 0; !BER_BVISNULL( &bi->sql_anlist[i].an_name ); i++ ) + { + ch_free( bi->sql_anlist[i].an_name.bv_val ); + } + ch_free( bi->sql_anlist ); + } + if ( bi->sql_baseObject ) { entry_free( bi->sql_baseObject ); } diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index 29b20f130d..2f4199d853 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -142,6 +142,10 @@ done:; entry_clean( bsi.bsi_e ); } + if ( bsi.bsi_attrs != NULL ) { + op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); + } + Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 ); return rs->sr_err != LDAP_SUCCESS ? rs->sr_err : op->o_noop; diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index 1ffa979158..d48ccd14f8 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -46,7 +46,7 @@ backsql_modrdn( Operation *op, SlapReply *rs ) realnew_dn = BER_BVNULL; LDAPRDN new_rdn = NULL; LDAPRDN old_rdn = NULL; - Entry e; + Entry e = { 0 }; Modifications *mod = NULL; struct berval *newSuperior = op->oq_modrdn.rs_newSup; char *next; @@ -95,13 +95,26 @@ backsql_modrdn( Operation *op, SlapReply *rs ) return 1; } + /* + * Check for entry access to target + */ + e.e_name = op->o_req_dn; + e.e_nname = op->o_req_ndn; + /* FIXME: need the whole entry (ITS#3480) */ + if ( !access_allowed( op, &e, slap_schema.si_ad_entry, + NULL, ACL_WRITE, NULL ) ) { + Debug( LDAP_DEBUG_TRACE, " no access to entry\n", 0, 0, 0 ); + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + goto modrdn_return; + } + dnParent( &op->o_req_dn, &p_dn ); dnParent( &op->o_req_ndn, &p_ndn ); /* * namingContext "" is not supported */ - if ( p_dn.bv_len == 0 ) { + if ( BER_BVISEMPTY( &p_dn ) ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " "parent is \"\" - aborting\n", 0, 0, 0 ); rs->sr_err = LDAP_UNWILLING_TO_PERFORM; @@ -113,7 +126,6 @@ backsql_modrdn( Operation *op, SlapReply *rs ) /* * Check for children access to parent */ - e.e_attrs = NULL; e.e_name = p_dn; e.e_nname = p_ndn; /* FIXME: need the whole entry (ITS#3480) */ @@ -128,7 +140,7 @@ backsql_modrdn( Operation *op, SlapReply *rs ) /* * namingContext "" is not supported */ - if ( newSuperior->bv_len == 0 ) { + if ( BER_BVISEMPTY( newSuperior ) ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " "newSuperior is \"\" - aborting\n", 0, 0, 0 ); rs->sr_err = LDAP_UNWILLING_TO_PERFORM; @@ -140,12 +152,11 @@ backsql_modrdn( Operation *op, SlapReply *rs ) new_pdn = newSuperior; new_npdn = op->oq_modrdn.rs_nnewSup; - e.e_name = *new_pdn; - e.e_nname = *new_npdn; - /* * Check for children access to new parent */ + e.e_name = *new_pdn; + e.e_nname = *new_npdn; /* FIXME: need the whole entry (ITS#3480) */ if ( !access_allowed( op, &e, slap_schema.si_ad_children, NULL, ACL_WRITE, NULL ) ) { diff --git a/servers/slapd/back-sql/operational.c b/servers/slapd/back-sql/operational.c index 72f73017a1..dbc1d88b68 100644 --- a/servers/slapd/back-sql/operational.c +++ b/servers/slapd/back-sql/operational.c @@ -197,6 +197,9 @@ backsql_operational( *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id ); (void)backsql_free_entryID( &bsi.bsi_base_id, 0 ); + if ( bsi.bsi_attrs != NULL ) { + op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); + } if ( *ap == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 879379d039..d74d896c9e 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -55,7 +55,7 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad ) * clear the list (retrieve all attrs) */ if ( ad == NULL ) { - ch_free( bsi->bsi_attrs ); + bsi->bsi_op->o_tmpfree( bsi->bsi_attrs, bsi->bsi_op->o_tmpmemctx ); bsi->bsi_attrs = NULL; bsi->bsi_flags |= BSQL_SF_ALL_ATTRS; return 1; @@ -79,8 +79,9 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad ) Debug( LDAP_DEBUG_TRACE, "==>backsql_attrlist_add(): " "adding \"%s\" to list\n", ad->ad_cname.bv_val, 0, 0 ); - an = (AttributeName *)ch_realloc( bsi->bsi_attrs, - sizeof( AttributeName ) * ( n_attrs + 2 ) ); + an = (AttributeName *)bsi->bsi_op->o_tmprealloc( bsi->bsi_attrs, + sizeof( AttributeName ) * ( n_attrs + 2 ), + bsi->bsi_op->o_tmpmemctx ); if ( an == NULL ) { return -1; } @@ -118,7 +119,7 @@ backsql_init_search( AttributeName *attrs, unsigned flags ) { - AttributeName *p; + backsql_info *bi = (backsql_info *)op->o_bd->be_private; int rc = LDAP_SUCCESS; bsi->bsi_base_ndn = nbase; @@ -134,49 +135,121 @@ backsql_init_search( bsi->bsi_rs = rs; bsi->bsi_flags = BSQL_SF_NONE; - /* - * handle "*" - */ - if ( attrs == NULL ) { - /* also add request for all operational */ - bsi->bsi_attrs = NULL; - bsi->bsi_flags |= BSQL_SF_ALL_USER; + bsi->bsi_attrs = NULL; + + if ( BACKSQL_FETCH_ALL_ATTRS( bi ) ) { + /* + * if requested, simply try to fetch all attributes + */ + bsi->bsi_flags |= BSQL_SF_ALL_ATTRS; } else { - int got_oc = 0; + if ( BACKSQL_FETCH_ALL_USERATTRS( bi ) ) { + bsi->bsi_flags |= BSQL_SF_ALL_USER; - bsi->bsi_attrs = (AttributeName *)ch_calloc( 1, - sizeof( AttributeName ) ); - BER_BVZERO( &bsi->bsi_attrs[ 0 ].an_name ); - - for ( p = attrs; !BER_BVISNULL( &p->an_name ); p++ ) { - /* - * ignore "1.1"; handle "+" - */ - if ( BACKSQL_NCMP( &p->an_name, &AllUser ) == 0 ) { - bsi->bsi_flags |= BSQL_SF_ALL_USER; - continue; + } else if ( BACKSQL_FETCH_ALL_OPATTRS( bi ) ) { + bsi->bsi_flags |= BSQL_SF_ALL_OPER; + } - } else if ( BACKSQL_NCMP( &p->an_name, &AllOper ) == 0 ) { - bsi->bsi_flags |= BSQL_SF_ALL_OPER; - continue; + if ( attrs == NULL ) { + /* NULL means all user attributes */ + bsi->bsi_flags |= BSQL_SF_ALL_USER; - } else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) { - continue; + } else { + AttributeName *p; + int got_oc = 0; - } else if ( p->an_desc == slap_schema.si_ad_objectClass ) { - got_oc = 1; + bsi->bsi_attrs = (AttributeName *)bsi->bsi_op->o_tmpalloc( + sizeof( AttributeName ), + bsi->bsi_op->o_tmpmemctx ); + BER_BVZERO( &bsi->bsi_attrs[ 0 ].an_name ); + + for ( p = attrs; !BER_BVISNULL( &p->an_name ); p++ ) { + if ( BACKSQL_NCMP( &p->an_name, &AllUser ) == 0 ) { + /* handle "*" */ + bsi->bsi_flags |= BSQL_SF_ALL_USER; + + /* if all attrs are requested, there's + * no need to continue */ + if ( BSQL_ISF_ALL_ATTRS( bsi ) ) { + bsi->bsi_op->o_tmpfree( bsi->bsi_attrs, + bsi->bsi_op->o_tmpmemctx ); + bsi->bsi_attrs = NULL; + break; + } + continue; + + } else if ( BACKSQL_NCMP( &p->an_name, &AllOper ) == 0 ) { + /* handle "+" */ + bsi->bsi_flags |= BSQL_SF_ALL_OPER; + + /* if all attrs are requested, there's + * no need to continue */ + if ( BSQL_ISF_ALL_ATTRS( bsi ) ) { + bsi->bsi_op->o_tmpfree( bsi->bsi_attrs, + bsi->bsi_op->o_tmpmemctx ); + bsi->bsi_attrs = NULL; + break; + } + continue; + + } else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) { + /* ignore "1.1" */ + continue; + + } else if ( p->an_desc == slap_schema.si_ad_objectClass ) { + got_oc = 1; + } + + backsql_attrlist_add( bsi, p->an_desc ); } - backsql_attrlist_add( bsi, p->an_desc ); + if ( got_oc == 0 && !( bsi->bsi_flags & BSQL_SF_ALL_USER ) ) { + /* add objectClass if not present, + * because it is required to understand + * if an entry is a referral, an alias + * or so... */ + backsql_attrlist_add( bsi, slap_schema.si_ad_objectClass ); + } } - if ( got_oc == 0 ) { - /* add objectClass if not present, - * because it is required to understand - * if an entry is a referral, an alias - * or so... */ - backsql_attrlist_add( bsi, slap_schema.si_ad_objectClass ); + if ( !BSQL_ISF_ALL_ATTRS( bsi ) && bi->sql_anlist ) { + AttributeName *p; + + /* use hints if available */ + for ( p = bi->sql_anlist; !BER_BVISNULL( &p->an_name ); p++ ) { + if ( BACKSQL_NCMP( &p->an_name, &AllUser ) == 0 ) { + /* handle "*" */ + bsi->bsi_flags |= BSQL_SF_ALL_USER; + + /* if all attrs are requested, there's + * no need to continue */ + if ( BSQL_ISF_ALL_ATTRS( bsi ) ) { + bsi->bsi_op->o_tmpfree( bsi->bsi_attrs, + bsi->bsi_op->o_tmpmemctx ); + bsi->bsi_attrs = NULL; + break; + } + continue; + + } else if ( BACKSQL_NCMP( &p->an_name, &AllOper ) == 0 ) { + /* handle "+" */ + bsi->bsi_flags |= BSQL_SF_ALL_OPER; + + /* if all attrs are requested, there's + * no need to continue */ + if ( BSQL_ISF_ALL_ATTRS( bsi ) ) { + bsi->bsi_op->o_tmpfree( bsi->bsi_attrs, + bsi->bsi_op->o_tmpmemctx ); + bsi->bsi_attrs = NULL; + break; + } + continue; + } + + backsql_attrlist_add( bsi, p->an_desc ); + } + } } @@ -202,7 +275,14 @@ backsql_init_search( BACKSQL_IS_MATCHED( flags ), 1 ); } - return ( bsi->bsi_status = rc ); + bsi->bsi_status = rc; + + if ( rc != LDAP_SUCCESS ) { + bsi->bsi_op->o_tmpfree( bsi->bsi_attrs, + bsi->bsi_op->o_tmpmemctx ); + } + + return rc; } static int @@ -1907,6 +1987,10 @@ backsql_search( Operation *op, SlapReply *rs ) } /* else: FIXME: inconsistency! */ entry_clean( &user_entry2 ); } + if ( bsi2.bsi_attrs != NULL ) { + op->o_tmpfree( bsi2.bsi_attrs, + op->o_tmpmemctx ); + } } if ( refs ) { @@ -2086,8 +2170,8 @@ done:; (void)backsql_free_entryID( &bsi.bsi_base_id, 0 ); } - if ( bsi.bsi_attrs ) { - ch_free( bsi.bsi_attrs ); + if ( bsi.bsi_attrs != NULL ) { + op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &nbase ) @@ -2186,6 +2270,10 @@ backsql_entry_get( } return_results:; + if ( bsi.bsi_attrs != NULL ) { + op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); + } + if ( rc != LDAP_SUCCESS ) { if ( bsi.bsi_e ) { entry_free( bsi.bsi_e );