]> git.sur5r.net Git - openldap/commitdiff
plug memory leak: bsi_attrs member
authorPierangelo Masarati <ando@openldap.org>
Fri, 14 Jan 2005 00:39:24 +0000 (00:39 +0000)
committerPierangelo Masarati <ando@openldap.org>
Fri, 14 Jan 2005 00:39:24 +0000 (00:39 +0000)
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)

servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/bind.c
servers/slapd/back-sql/compare.c
servers/slapd/back-sql/config.c
servers/slapd/back-sql/init.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/operational.c
servers/slapd/back-sql/search.c

index b44bf0701dfc5c992bfb120989711f551380e269..e3dad04a34f4e10c70c89059cb0c910b18ee41b5 100644 (file)
@@ -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
index 6044cdf7b890a9b7f19cdc0b786e0368940b52b8..96c06fdd1e735863194bc9df5cbe100c03e5e6a1 100644 (file)
@@ -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;
index 7381ecc057baff1bef90de0db869211d53bb44a2..0f581374669f152d5084d3992e83e8389b9b0029 100644 (file)
@@ -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:
index 9efdb0ae5216af11d0efebbc56f71a37e6234b81..c45c70716eb84d2bbf2f6707d935a09371cd959c 100644 (file)
@@ -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 <attrlist>"
+                               "in \"fetch_all_attrs <attrlist>\" 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;
        }
index 48eb0f2f72c976dac5f56ab41186f32c9c451bf7..cf5de2117ffc099d95453b2857f1241f16a3aa23 100644 (file)
@@ -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 );
        }
index 29b20f130d63dc96abb9b01b3789707e874a822a..2f4199d8539051bddb21f512335e325c77242acf 100644 (file)
@@ -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;
index 1ffa97915865eb5c9178da522251724652d48cc0..d48ccd14f8b49523acb363c0695323aa6626e833 100644 (file)
@@ -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 ) ) {
index 72f73017a152e42fbf6c99a3f264b70c287afee1..dbc1d88b6871814a5507eb8fc83ec150de4539e3 100644 (file)
@@ -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(): "
index 879379d03979afdf76065df0a01afbab6c4082d1..d74d896c9eb1c208dd78663a1b7c62d8ff00a6b0 100644 (file)
@@ -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 );