]> git.sur5r.net Git - openldap/commitdiff
address ITS#3472/3480/3488/3489
authorPierangelo Masarati <ando@openldap.org>
Sat, 15 Jan 2005 18:43:34 +0000 (18:43 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 15 Jan 2005 18:43:34 +0000 (18:43 +0000)
servers/slapd/back-sql/add.c
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/bind.c
servers/slapd/back-sql/compare.c
servers/slapd/back-sql/delete.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/operational.c
servers/slapd/back-sql/proto-sql.h
servers/slapd/back-sql/search.c

index 051503848f1f7812b35da47384915f3b111065cf..c57d64e1f91eadf00a4becd279b53ad843e2f75b 100644 (file)
@@ -265,7 +265,7 @@ backsql_modify_delete_all_values(
                                        /* SQL procedure executed fine 
                                         * but returned an error */
                                        rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
-                                       rs->sr_text = op->oq_add.rs_e->e_name.bv_val;
+                                       rs->sr_text = op->ora_e->e_name.bv_val;
                                        SQLFreeStmt( sth, SQL_DROP );
                                        return rs->sr_err;
 
@@ -275,7 +275,7 @@ backsql_modify_delete_all_values(
                                        if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) 
                                        {
                                                rs->sr_err = LDAP_OTHER;
-                                               rs->sr_text = op->oq_add.rs_e->e_name.bv_val;
+                                               rs->sr_text = op->ora_e->e_name.bv_val;
                                                SQLFreeStmt( sth, SQL_DROP );
                                                return rs->sr_err;
                                        }
@@ -767,7 +767,7 @@ backsql_add_attr(
                Debug( LDAP_DEBUG_TRACE, "   backsql_add_attr(\"%s\"): "
                        "attribute \"%s\" is not registered "
                        "in objectclass \"%s\"\n",
-                       op->oq_add.rs_e->e_name.bv_val,
+                       op->ora_e->e_name.bv_val,
                        at->a_desc->ad_cname.bv_val,
                        BACKSQL_OC_NAME( oc ) );
 
@@ -785,7 +785,7 @@ backsql_add_attr(
                        "add procedure is not defined "
                        "for attribute \"%s\" "
                        "of structuralObjectClass \"%s\"\n",
-                       op->oq_add.rs_e->e_name.bv_val,
+                       op->ora_e->e_name.bv_val,
                        at->a_desc->ad_cname.bv_val,
                        BACKSQL_OC_NAME( oc ) );
 
@@ -905,7 +905,7 @@ backsql_add_attr(
                                i, new_keyval );
                Debug( LDAP_DEBUG_TRACE, "   backsql_add_attr(\"%s\"): "
                        "executing \"%s\" %s\n", 
-                       op->oq_add.rs_e->e_name.bv_val,
+                       op->ora_e->e_name.bv_val,
                        at_rec->bam_add_proc, logbuf );
 #endif
                rc = SQLExecute( sth );
@@ -916,12 +916,12 @@ backsql_add_attr(
                        Debug( LDAP_DEBUG_TRACE,
                                "   backsql_add_attr(\"%s\"): "
                                "add_proc execution failed (rc=%d, prc=%d)\n", 
-                               op->oq_add.rs_e->e_name.bv_val, rc, prc );
+                               op->ora_e->e_name.bv_val, rc, prc );
                        if ( prc != LDAP_SUCCESS ) {
                                /* SQL procedure executed fine
                                 * but returned an error */
                                rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
-                               rs->sr_text = op->oq_add.rs_e->e_name.bv_val;
+                               rs->sr_text = op->ora_e->e_name.bv_val;
                                SQLFreeStmt( sth, SQL_DROP );
                                return rs->sr_err;
 
@@ -930,7 +930,7 @@ backsql_add_attr(
                                                sth, rc );
                                if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
                                        rs->sr_err = LDAP_OTHER;
-                                       rs->sr_text = op->oq_add.rs_e->e_name.bv_val;
+                                       rs->sr_text = op->ora_e->e_name.bv_val;
                                        SQLFreeStmt( sth, SQL_DROP );
                                        return rs->sr_err;
                                }
@@ -951,13 +951,15 @@ backsql_add( Operation *op, SlapReply *rs )
        unsigned long           new_keyval = 0;
        RETCODE                 rc;
        backsql_oc_map_rec      *oc = NULL;
+       backsql_srch_info       bsi;
        backsql_entryID         parent_id = BACKSQL_ENTRYID_INIT;
-       Entry                   p;
+       Entry                   p = { 0 }, *e = NULL;
        Attribute               *at,
                                *at_objectClass = NULL;
        struct berval           pdn;
        struct berval           realdn = BER_BVNULL;
        int                     colnum;
+       slap_mask_t             mask;
 
 #ifdef BACKSQL_SYNCPROV
        /*
@@ -979,25 +981,26 @@ backsql_add( Operation *op, SlapReply *rs )
 #endif /* BACKSQL_SYNCPROV */
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
-                       op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                       op->ora_e->e_name.bv_val, 0, 0 );
 
        /* check schema */
        if ( global_schemacheck ) {
                char            textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
 
-               rs->sr_err = entry_schema_check( op->o_bd, op->oq_add.rs_e,
+               rs->sr_err = entry_schema_check( op->o_bd, op->ora_e,
                                NULL,
                                &rs->sr_text, textbuf, sizeof( textbuf ) );
                if ( rs->sr_err != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                                "entry failed schema check -- aborting\n",
-                               op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                               op->ora_e->e_name.bv_val, 0, 0 );
+                       e = NULL;
                        goto done;
                }
        }
 
        /* search structural objectClass */
-       for ( at = op->oq_add.rs_e->e_attrs; at != NULL; at = at->a_next ) {
+       for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
                if ( at->a_desc == slap_schema.si_ad_structuralObjectClass ) {
                        break;
                }
@@ -1012,10 +1015,11 @@ backsql_add( Operation *op, SlapReply *rs )
        if ( oc == NULL ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "cannot map structuralObjectClass \"%s\" -- aborting\n",
-                       op->oq_add.rs_e->e_name.bv_val,
+                       op->ora_e->e_name.bv_val,
                        at->a_vals[0].bv_val, 0 );
                rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                rs->sr_text = "operation not permitted within namingContext";
+               e = NULL;
                goto done;
        }
 
@@ -1023,10 +1027,11 @@ backsql_add( Operation *op, SlapReply *rs )
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "create procedure is not defined "
                        "for structuralObjectClass \"%s\" - aborting\n",
-                       op->oq_add.rs_e->e_name.bv_val,
+                       op->ora_e->e_name.bv_val,
                        at->a_vals[0].bv_val, 0 );
                rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                rs->sr_text = "operation not permitted within namingContext";
+               e = NULL;
                goto done;
 
        } else if ( BACKSQL_CREATE_NEEDS_SELECT( bi )
@@ -1035,10 +1040,11 @@ backsql_add( Operation *op, SlapReply *rs )
                        "create procedure needs select procedure, "
                        "but none is defined for structuralObjectClass \"%s\" "
                        "- aborting\n",
-                       op->oq_add.rs_e->e_name.bv_val,
+                       op->ora_e->e_name.bv_val,
                        at->a_vals[0].bv_val, 0 );
                rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                rs->sr_text = "operation not permitted within namingContext";
+               e = NULL;
                goto done;
        }
 
@@ -1046,9 +1052,10 @@ backsql_add( Operation *op, SlapReply *rs )
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "could not get connection handle - exiting\n", 
-                       op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                       op->ora_e->e_name.bv_val, 0, 0 );
                rs->sr_text = ( rs->sr_err == LDAP_OTHER )
                        ?  "SQL-backend error" : NULL;
+               e = NULL;
                goto done;
        }
 
@@ -1058,13 +1065,14 @@ backsql_add( Operation *op, SlapReply *rs )
         * NOTE: backsql_api_dn2odbc() is called explicitly because
         * we need the mucked DN to pass it to the create procedure.
         */
-       realdn = op->oq_add.rs_e->e_name;
+       realdn = op->ora_e->e_name;
        if ( backsql_api_dn2odbc( op, rs, &realdn ) ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "backsql_api_dn2odbc(\"%s\") failed\n", 
-                       op->oq_add.rs_e->e_name.bv_val, realdn.bv_val, 0 );
+                       op->ora_e->e_name.bv_val, realdn.bv_val, 0 );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
@@ -1072,93 +1080,57 @@ backsql_add( Operation *op, SlapReply *rs )
        if ( rs->sr_err == LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "entry exists\n",
-                       op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                       op->ora_e->e_name.bv_val, 0, 0 );
                rs->sr_err = LDAP_ALREADY_EXISTS;
+               e = op->ora_e;
                goto done;
        }
 
        /*
         * Get the parent dn and see if the corresponding entry exists.
         */
-       if ( be_issuffix( op->o_bd, &op->oq_add.rs_e->e_nname ) ) {
+       if ( be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) {
                pdn = slap_empty_bv;
 
        } else {
-               dnParent( &op->oq_add.rs_e->e_nname, &pdn );
+               dnParent( &op->ora_e->e_nname, &pdn );
        }
 
-       rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, &parent_id, 0, 1 );
+       /*
+        * Get the parent
+        */
+       bsi.bsi_e = &p;
+       rs->sr_err = backsql_init_search( &bsi, &pdn,
+                       LDAP_SCOPE_BASE, 
+                       SLAP_NO_LIMIT, SLAP_NO_LIMIT,
+                       (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
+                       ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
        if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
-                       "could not lookup parent entry for new record \"%s\"\n",
-                       op->oq_add.rs_e->e_name.bv_val, pdn.bv_val, 0 );
-
-               if ( rs->sr_err != LDAP_NO_SUCH_OBJECT ) {
-                       goto done;
-               }
-
-               /*
-                * no parent!
-                *  if not attempting to add entry at suffix or with parent ""
-                */
-               if ( ( ( !be_isroot( op ) && !be_shadow_update( op ) )
-                       || !BER_BVISEMPTY( &pdn ) ) && !is_entry_glue( op->oq_add.rs_e )
-                       && !BACKSQL_ALLOW_ORPHANS( bi ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE, "   backsql_add: %s denied\n",
-                               BER_BVISEMPTY( &pdn ) ? "suffix" : "entry at root",
-                               0, 0 );
-                       /*
-                        * Look for matched
-                        */
-                       while ( 1 ) {
-                               struct berval   dn;
-                               char            *matched = NULL;
-       
-                               dn = pdn;
-                               dnParent( &dn, &pdn );
-       
-                               /*
-                                * Empty DN ("") defaults to LDAP_SUCCESS
-                                */
-                               rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, NULL, 0, 1 );
-                               switch ( rs->sr_err ) {
-                               case LDAP_NO_SUCH_OBJECT:
-                                       if ( !BER_BVISEMPTY( &pdn ) ) {
-                                               break;
-                                       }
-                                       /* fail over to next case */
-                                       
-                               case LDAP_SUCCESS:
-                                       matched = pdn.bv_val;
-                                       /* fail over to next case */
-       
-                               default:
-                                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
-                                       rs->sr_matched = matched;
-                                       goto done;
-                               } 
-                       }
-               } else {
-
-#ifdef BACKSQL_ARBITRARY_KEY
-                       ber_str2bv( "SUFFIX", 0, 1, &parent_id.eid_id );
-#else /* ! BACKSQL_ARBITRARY_KEY */
-                       parent_id.eid_id = 0;
-#endif /* ! BACKSQL_ARBITRARY_KEY */
-                       rs->sr_err = LDAP_SUCCESS;
-               }
+               Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                       "could not retrieve addDN parent "
+                       "\"%s\" ID - %s matched=\"%s\"\n", 
+                       pdn.bv_val,
+                       rs->sr_err == LDAP_REFERRAL ? "referral" : "no such entry",
+                       rs->sr_matched ? rs->sr_matched : "(null)" );
+               e = &p;
+               goto done;
        }
 
        /* check "children" pseudo-attribute access to parent */
-       p.e_attrs = NULL;
-       p.e_name = pdn;
-       dnParent( &op->oq_add.rs_e->e_nname, &p.e_nname );
-
-       /* FIXME: need the whole entry (ITS#3480) */
        if ( !access_allowed( op, &p, slap_schema.si_ad_children,
-                               NULL, ACL_WRITE, NULL ) ) {
+                               NULL, ACL_WRITE, NULL ) )
+       {
                rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+               e = &p;
+               goto done;
+       }
+
+       if ( !access_allowed_mask( op, op->ora_e,
+                               slap_schema.si_ad_entry,
+                               NULL, ACL_WRITE, NULL, &mask ) )
+       {
+               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+               e = op->ora_e;
                goto done;
        }
 
@@ -1168,11 +1140,11 @@ backsql_add( Operation *op, SlapReply *rs )
         * the id of the added row; otherwise the procedure
         * is expected to return the id as the first column of a select
         */
-
        rc = SQLAllocStmt( dbh, &sth );
        if ( rc != SQL_SUCCESS ) {
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
@@ -1190,13 +1162,14 @@ backsql_add( Operation *op, SlapReply *rs )
 
                        rs->sr_text = "SQL-backend error";
                        rs->sr_err = LDAP_OTHER;
+                       e = NULL;
                        goto done;
                }
                colnum++;
        }
 
        if ( oc->bom_create_hint ) {
-               at = attr_find( op->oq_add.rs_e->e_attrs, oc->bom_create_hint );
+               at = attr_find( op->ora_e->e_attrs, oc->bom_create_hint );
                if ( at && at->a_vals ) {
                        backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT,
                                        at->a_vals[0].bv_val,
@@ -1216,16 +1189,17 @@ backsql_add( Operation *op, SlapReply *rs )
        }
 
        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): executing \"%s\"\n",
-               op->oq_add.rs_e->e_name.bv_val, oc->bom_create_proc, 0 );
+               op->ora_e->e_name.bv_val, oc->bom_create_proc, 0 );
        rc = SQLExecDirect( sth, oc->bom_create_proc, SQL_NTS );
        if ( rc != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "create_proc execution failed\n",
-                       op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                       op->ora_e->e_name.bv_val, 0, 0 );
                backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
                SQLFreeStmt( sth, SQL_DROP );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
@@ -1243,6 +1217,7 @@ backsql_add( Operation *op, SlapReply *rs )
                        if ( rc != SQL_SUCCESS ) {
                                rs->sr_err = LDAP_OTHER;
                                rs->sr_text = "SQL-backend error";
+                               e = NULL;
                                goto done;
                        }
 
@@ -1250,6 +1225,7 @@ backsql_add( Operation *op, SlapReply *rs )
                        if ( rc != SQL_SUCCESS ) {
                                rs->sr_err = LDAP_OTHER;
                                rs->sr_text = "SQL-backend error";
+                               e = NULL;
                                goto done;
                        }
                }
@@ -1262,21 +1238,23 @@ backsql_add( Operation *op, SlapReply *rs )
                if ( rc != SQL_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                                "create_proc result evaluation failed\n",
-                               op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                               op->ora_e->e_name.bv_val, 0, 0 );
                        backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
                        SQLFreeStmt( sth, SQL_DROP );
                        rs->sr_err = LDAP_OTHER;
                        rs->sr_text = "SQL-backend error";
+                       e = NULL;
                        goto done;
 
                } else if ( ncols != 1 ) {
                        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                                "create_proc result is bogus (ncols=%d)\n",
-                               op->oq_add.rs_e->e_name.bv_val, ncols, 0 );
+                               op->ora_e->e_name.bv_val, ncols, 0 );
                        backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
                        SQLFreeStmt( sth, SQL_DROP );
                        rs->sr_err = LDAP_OTHER;
                        rs->sr_text = "SQL-backend error";
+                       e = NULL;
                        goto done;
                }
 
@@ -1308,11 +1286,12 @@ backsql_add( Operation *op, SlapReply *rs )
                if ( value_len <= 0 ) {
                        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                                "create_proc result is empty?\n",
-                               op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                               op->ora_e->e_name.bv_val, 0, 0 );
                        backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
                        SQLFreeStmt( sth, SQL_DROP );
                        rs->sr_err = LDAP_OTHER;
                        rs->sr_text = "SQL-backend error";
+                       e = NULL;
                        goto done;
                }
        }
@@ -1321,9 +1300,9 @@ backsql_add( Operation *op, SlapReply *rs )
 
        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                "create_proc returned keyval=%ld\n",
-               op->oq_add.rs_e->e_name.bv_val, new_keyval, 0 );
+               op->ora_e->e_name.bv_val, new_keyval, 0 );
 
-       for ( at = op->oq_add.rs_e->e_attrs; at != NULL; at = at->a_next ) {
+       for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(): "
                        "adding attribute \"%s\"\n", 
                        at->a_desc->ad_cname.bv_val, 0, 0 );
@@ -1346,6 +1325,7 @@ backsql_add( Operation *op, SlapReply *rs )
 
                rs->sr_err = backsql_add_attr( op, rs, dbh, oc, at, new_keyval );
                if ( rs->sr_err != LDAP_SUCCESS ) {
+                       e = op->ora_e;
                        goto done;
                }
        }
@@ -1354,6 +1334,7 @@ backsql_add( Operation *op, SlapReply *rs )
        if ( rc != SQL_SUCCESS ) {
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
        
@@ -1369,6 +1350,7 @@ backsql_add( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -1384,6 +1366,7 @@ backsql_add( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -1399,6 +1382,7 @@ backsql_add( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -1414,11 +1398,12 @@ backsql_add( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
        Debug( LDAP_DEBUG_TRACE, "   backsql_add(): executing \"%s\" for dn \"%s\"\n",
-                       bi->sql_insentry_stmt, op->oq_add.rs_e->e_name.bv_val, 0 );
+                       bi->sql_insentry_stmt, op->ora_e->e_name.bv_val, 0 );
 #ifdef BACKSQL_ARBITRARY_KEY
        Debug( LDAP_DEBUG_TRACE, "                  for oc_map_id=%ld, "
                        "parent_id=%s, keyval=%ld\n",
@@ -1432,7 +1417,7 @@ backsql_add( Operation *op, SlapReply *rs )
        if ( rc != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "could not insert ldap_entries record\n",
-                       op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                       op->ora_e->e_name.bv_val, 0, 0 );
                backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
                
                /*
@@ -1441,6 +1426,7 @@ backsql_add( Operation *op, SlapReply *rs )
                SQLFreeStmt( sth, SQL_DROP );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
@@ -1448,6 +1434,7 @@ backsql_add( Operation *op, SlapReply *rs )
        if ( at_objectClass ) {
                rs->sr_err = backsql_add_attr( op, rs, dbh, oc, at_objectClass, new_keyval );
                if ( rs->sr_err != LDAP_SUCCESS ) {
+                       e = op->ora_e;
                        goto done;
                }
        }
@@ -1476,22 +1463,58 @@ done:;
         * in deleting that row.
         */
 
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+       if ( e != NULL ) {
+               int     disclose = 1;
+
+               if ( e == op->ora_e && !ACL_GRANT( mask, ACL_DISCLOSE ) ) {
+                       /* mask already collected */
+                       disclose = 0;
+
+               } else if ( e == &p && !access_allowed( op, &p,
+                                       slap_schema.si_ad_entry, NULL,
+                                       ACL_DISCLOSE, NULL ) )
+               {
+                       disclose = 0;
+               }
+
+               if ( disclose == 0 ) {
+                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                       rs->sr_text = NULL;
+                       rs->sr_matched = NULL;
+                       if ( rs->sr_ref ) {
+                               ber_bvarray_free( rs->sr_ref );
+                               rs->sr_ref = NULL;
+                       }
+               }
+       }
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
+
        send_ldap_result( op, rs );
 
        if ( !BER_BVISNULL( &realdn )
-                       && realdn.bv_val != op->oq_add.rs_e->e_name.bv_val )
+                       && realdn.bv_val != op->ora_e->e_name.bv_val )
        {
                ch_free( realdn.bv_val );
        }
-       if ( !BER_BVISNULL( &parent_id.eid_ndn ) ) {
-               (void)backsql_free_entryID( &parent_id, 0 );
+       (void)backsql_free_entryID( op, &parent_id, 0 );
+
+       if ( !BER_BVISNULL( &p.e_nname ) ) {
+               entry_clean( &p );
        }
 
        Debug( LDAP_DEBUG_TRACE, "<==backsql_add(\"%s\"): %d \"%s\"\n",
-                       op->oq_add.rs_e->e_name.bv_val,
+                       op->ora_e->e_name.bv_val,
                        rs->sr_err,
                        rs->sr_text ? rs->sr_text : "" );
 
-       return ( ( rs->sr_err == LDAP_SUCCESS ) ? op->o_noop : 1 );
+       rs->sr_text = NULL;
+       rs->sr_matched = NULL;
+       if ( rs->sr_ref ) {
+               ber_bvarray_free( rs->sr_ref );
+               rs->sr_ref = NULL;
+       }
+
+       return rs->sr_err;
 }
 
index e3dad04a34f4e10c70c89059cb0c910b18ee41b5..fb285c0c5e860e59ce670d222c90ebd4cb59f03e 100644 (file)
@@ -375,6 +375,16 @@ typedef struct berbuf {
 
 #define BB_NULL                { BER_BVNULL, 0 }
 
+/* the function must collect the entry associated to nbase */
+#define BACKSQL_ISF_GET_ID     0x1U
+#define BACKSQL_ISF_GET_ENTRY  ( 0x2U | BACKSQL_ISF_GET_ID )
+#define BACKSQL_ISF_MATCHED    0x4U
+#define BACKSQL_IS_GET_ID(f) \
+       ( ( (f) & BACKSQL_ISF_GET_ID ) == BACKSQL_ISF_GET_ID )
+#define BACKSQL_IS_GET_ENTRY(f) \
+       ( ( (f) & BACKSQL_ISF_GET_ENTRY ) == BACKSQL_ISF_GET_ENTRY )
+#define BACKSQL_IS_MATCHED(f) \
+       ( ( (f) & BACKSQL_ISF_MATCHED ) == BACKSQL_ISF_MATCHED )
 typedef struct backsql_srch_info {
        Operation               *bsi_op;
        SlapReply               *bsi_rs;
index 96c06fdd1e735863194bc9df5cbe100c03e5e6a1..3ce75c1f08add6db532491bae69e0fb4cc1961e4 100644 (file)
@@ -32,8 +32,7 @@ int
 backsql_bind( Operation *op, SlapReply *rs )
 {
        SQLHDBC                 dbh = SQL_NULL_HDBC;
-       Entry                   *e = NULL,
-                               user_entry = { 0 };
+       Entry                   e = { 0 };
        Attribute               *a;
        backsql_srch_info       bsi;
        AttributeName           anlist[2];
@@ -45,7 +44,7 @@ backsql_bind( Operation *op, SlapReply *rs )
                ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
                Debug( LDAP_DEBUG_TRACE, "<==backsql_bind() root bind\n", 
                                0, 0, 0 );
-               return 0;
+               return LDAP_SUCCESS;
        }
 
        ber_dupbv( &op->oq_bind.rb_edn, &op->o_req_ndn );
@@ -54,7 +53,7 @@ backsql_bind( Operation *op, SlapReply *rs )
                rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
                rs->sr_text = "authentication method not supported"; 
                send_ldap_result( op, rs );
-               return 1;
+               return rs->sr_err;
        }
 
        /*
@@ -68,45 +67,33 @@ backsql_bind( Operation *op, SlapReply *rs )
 
                rs->sr_text = ( rs->sr_err == LDAP_OTHER )
                        ? "SQL-backend error" : NULL;
-               send_ldap_result( op, rs );
-               return 1;
+               goto error_return;
        }
 
        anlist[0].an_name = slap_schema.si_ad_userPassword->ad_cname;
        anlist[0].an_desc = slap_schema.si_ad_userPassword;
        anlist[1].an_name.bv_val = NULL;
 
+       bsi.bsi_e = &e;
        rc = backsql_init_search( &bsi, &op->o_req_ndn, LDAP_SCOPE_BASE, 
                        SLAP_NO_LIMIT, SLAP_NO_LIMIT,
                        (time_t)(-1), NULL, dbh, op, rs, anlist,
-                       BACKSQL_ISF_GET_ID );
+                       BACKSQL_ISF_GET_ENTRY );
        if ( rc != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
                        "could not retrieve bindDN ID - no such entry\n", 
                        0, 0, 0 );
                rs->sr_err = LDAP_INVALID_CREDENTIALS;
-               send_ldap_result( op, rs );
-               return 1;
-       }
-
-       bsi.bsi_e = &user_entry;
-       rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
-       if ( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
-                       "error %d in backsql_id2entry() "
-                       "- auth failed\n", rc, 0, 0 );
-               rs->sr_err = LDAP_INVALID_CREDENTIALS;
                goto error_return;
        }
-       e = &user_entry;
 
-       a = attr_find( e->e_attrs, slap_schema.si_ad_userPassword );
+       a = attr_find( e.e_attrs, slap_schema.si_ad_userPassword );
        if ( a == NULL ) {
                rs->sr_err = LDAP_INVALID_CREDENTIALS;
                goto error_return;
        }
 
-       if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred,
+       if ( slap_passwd_check( op, &e, a, &op->oq_bind.rb_cred,
                                &rs->sr_text ) != 0 )
        {
                rs->sr_err = LDAP_INVALID_CREDENTIALS;
@@ -114,25 +101,22 @@ backsql_bind( Operation *op, SlapReply *rs )
        }
 
 error_return:;
-       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
-       }
+       (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
 
-       if ( e != NULL ) {
-               entry_clean( e );
+       if ( bsi.bsi_e ) {
+               entry_clean( bsi.bsi_e );
        }
 
        if ( bsi.bsi_attrs != NULL ) {
                op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
        }
 
-       if ( rs->sr_err ) {
+       if ( rs->sr_err != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
-               return 1;
        }
        
-       Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0);
+       Debug( LDAP_DEBUG_TRACE,"<==backsql_bind()\n", 0, 0, 0 );
 
-       return 0;
+       return rs->sr_err;
 }
  
index ac23f9e6c17705025dddfe6755699eb23d2fd203..d339009fb671f5db57e46cd67f776ec3ba204c35 100644 (file)
@@ -32,21 +32,17 @@ int
 backsql_compare( Operation *op, SlapReply *rs )
 {
        SQLHDBC                 dbh = SQL_NULL_HDBC;
-       Entry                   *e = NULL, user_entry;
+       Entry                   e = { 0 };
        Attribute               *a = NULL;
        backsql_srch_info       bsi;
        int                     rc;
        AttributeName           anlist[2],
                                *anlistp = NULL;
 
-       BER_BVZERO( &user_entry.e_name );
-       BER_BVZERO( &user_entry.e_nname );
-       user_entry.e_attrs = NULL;
        Debug( LDAP_DEBUG_TRACE, "==>backsql_compare()\n", 0, 0, 0 );
 
        rs->sr_err = backsql_get_db_conn( op, &dbh );
-       if (!dbh) {
+       if ( !dbh ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
                        "could not get connection handle - exiting\n",
                        0, 0, 0 );
@@ -56,9 +52,9 @@ backsql_compare( Operation *op, SlapReply *rs )
                goto return_results;
        }
 
-       memset( &anlist[0], 0, 2 * sizeof( AttributeName ) );
-       anlist[0].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
-       anlist[0].an_desc = op->oq_compare.rs_ava->aa_desc;
+       anlist[ 0 ].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
+       anlist[ 0 ].an_desc = op->oq_compare.rs_ava->aa_desc;
+       BER_BVZERO( &anlist[ 1 ].an_name );
 
        /*
         * Try to get attr as dynamic operational
@@ -68,30 +64,30 @@ backsql_compare( Operation *op, SlapReply *rs )
        }
 
        /*
-        * FIXME: deal with matchedDN/referral?
+        * Get the entry
         */
+       bsi.bsi_e = &e;
        rc = backsql_init_search( &bsi, &op->o_req_ndn,
                        LDAP_SCOPE_BASE, 
                        SLAP_NO_LIMIT, SLAP_NO_LIMIT,
                        (time_t)(-1), NULL, dbh, op, rs, anlistp,
-                       BACKSQL_ISF_GET_ID );
+                       ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
        if ( rc != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
                        "could not retrieve compareDN ID - no such entry\n", 
                        0, 0, 0 );
-               rs->sr_err = LDAP_NO_SUCH_OBJECT;
                goto return_results;
        }
 
        if ( is_at_operational( op->oq_compare.rs_ava->aa_desc->ad_type ) ) {
                SlapReply       nrs = { 0 };
 
-               user_entry.e_attrs = NULL;
-               user_entry.e_name = bsi.bsi_base_id.eid_dn;
-               user_entry.e_nname = bsi.bsi_base_id.eid_ndn;
+               e.e_attrs = NULL;
+               ber_dupbv( &e.e_name, &bsi.bsi_base_id.eid_dn );
+               ber_dupbv( &e.e_nname, &bsi.bsi_base_id.eid_ndn );
 
                nrs.sr_attrs = anlist;
-               nrs.sr_entry = &user_entry;
+               nrs.sr_entry = &e;
                nrs.sr_attr_flags = SLAP_OPATTRS_NO;
                nrs.sr_operational_attrs = NULL;
 
@@ -100,10 +96,9 @@ backsql_compare( Operation *op, SlapReply *rs )
                        goto return_results;
                }
                
-               user_entry.e_attrs = nrs.sr_operational_attrs;
+               e.e_attrs = nrs.sr_operational_attrs;
 
        } else {
-               bsi.bsi_e = &user_entry;
                rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
                if ( rc != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
@@ -113,25 +108,17 @@ backsql_compare( Operation *op, SlapReply *rs )
                        goto return_results;
                }
        }
-       e = &user_entry;
 
-       if ( ! access_allowed( op, e, op->oq_compare.rs_ava->aa_desc, 
+       if ( ! access_allowed( op, &e, op->oq_compare.rs_ava->aa_desc,
                                &op->oq_compare.rs_ava->aa_value,
-                               ACL_COMPARE, NULL ) ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
-               if ( ! access_allowed( op, &e, slap_schema.si_ad_entry, NULL,
-                                       ACL_DISCLOSE, NULL ) ) {
-                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
-               } else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-               {
-                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               }
+                               ACL_COMPARE, NULL ) )
+       {
+               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
                goto return_results;
        }
 
        rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE;
-       for ( a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc );
+       for ( a = attrs_find( e.e_attrs, op->oq_compare.rs_ava->aa_desc );
                        a != NULL;
                        a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ) )
        {
@@ -149,14 +136,40 @@ backsql_compare( Operation *op, SlapReply *rs )
        }
 
 return_results:;
+       switch ( rs->sr_err ) {
+       case LDAP_COMPARE_TRUE:
+       case LDAP_COMPARE_FALSE:
+               break;
+
+       default:
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+               if ( !BER_BVISNULL( &e.e_nname ) &&
+                               ! access_allowed( op, &e,
+                                       slap_schema.si_ad_entry, NULL,
+                                       ACL_DISCLOSE, NULL ) )
+               {
+                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                       rs->sr_text = NULL;
+               }
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
+               break;
+       }
+
        send_ldap_result( op, rs );
 
-       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
+       if ( rs->sr_matched ) {
+               rs->sr_matched = NULL;
        }
 
-       if ( e != NULL ) {
-               entry_clean( e );
+       if ( rs->sr_ref ) {
+               ber_bvarray_free( rs->sr_ref );
+               rs->sr_ref = NULL;
+       }
+
+       (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+
+       if ( bsi.bsi_e ) {
+               entry_clean( bsi.bsi_e );
        }
 
        if ( bsi.bsi_attrs != NULL ) {
@@ -167,10 +180,10 @@ return_results:;
        switch ( rs->sr_err ) {
        case LDAP_COMPARE_TRUE:
        case LDAP_COMPARE_FALSE:
-               return 0;
+               return LDAP_SUCCESS;
 
        default:
-               return 1;
+               return rs->sr_err;
        }
 }
  
index 20bab6dcc546a529728ddea0c00b3ee4d5dce1a4..c07ee3400bf421fb0f36a0b35f587222bcf5244e 100644 (file)
@@ -87,8 +87,11 @@ backsql_delete( Operation *op, SlapReply *rs )
        RETCODE                 rc;
        int                     prc = LDAP_SUCCESS;
        backsql_oc_map_rec      *oc = NULL;
-       backsql_entryID         e_id = BACKSQL_ENTRYID_INIT;
-       Entry                   e;
+       backsql_srch_info       bsi;
+       backsql_entryID         e_id = { 0 };
+       Entry                   d = { 0 }, p = { 0 }, *e = NULL;
+       struct berval           pdn = BER_BVNULL;
+       int                     manageDSAit = get_manageDSAit( op );
        /* first parameter no */
        SQLUSMALLINT            pno;
        SQLUSMALLINT            CompletionType = SQL_ROLLBACK;
@@ -96,22 +99,6 @@ backsql_delete( Operation *op, SlapReply *rs )
        Debug( LDAP_DEBUG_TRACE, "==>backsql_delete(): deleting entry \"%s\"\n",
                        op->o_req_ndn.bv_val, 0, 0 );
 
-       dnParent( &op->o_req_dn, &e.e_name );
-       dnParent( &op->o_req_ndn, &e.e_nname );
-       e.e_attrs = NULL;
-
-       /* check parent for "children" acl */
-       /* FIXME: need the whole entry (ITS#3480) */
-       if ( !access_allowed( op, &e, slap_schema.si_ad_children, 
-                       NULL, ACL_WRITE, NULL ) ) {
-               Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
-                       "no write access to parent\n", 
-                       0, 0, 0 );
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               goto done;
-
-       }
-       
        rs->sr_err = backsql_get_db_conn( op, &dbh );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
@@ -119,13 +106,55 @@ backsql_delete( Operation *op, SlapReply *rs )
                        0, 0, 0 );
                rs->sr_text = ( rs->sr_err == LDAP_OTHER )
                        ? "SQL-backend error" : NULL;
+               e = NULL;
                goto done;
        }
        
-       rs->sr_err = backsql_dn2id( op, rs, dbh, &op->o_req_ndn, &e_id, 0, 1 );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
+       /*
+        * Get the entry
+        */
+       bsi.bsi_e = &d;
+       rc = backsql_init_search( &bsi, &op->o_req_ndn,
+                       LDAP_SCOPE_BASE, 
+                       SLAP_NO_LIMIT, SLAP_NO_LIMIT,
+                       (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
+                       ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
+       switch ( rc ) {
+       case LDAP_SUCCESS:
+               break;
+
+       case LDAP_REFERRAL:
+               if ( !BER_BVISNULL( &bsi.bsi_e->e_nname ) &&
+                               dn_match( &op->o_req_ndn, &bsi.bsi_e->e_nname )
+                               && manageDSAit )
+               {
+                       rs->sr_err = LDAP_SUCCESS;
+                       rs->sr_text = NULL;
+                       rs->sr_matched = NULL;
+                       if ( rs->sr_ref ) {
+                               ber_bvarray_free( rs->sr_ref );
+                               rs->sr_ref = NULL;
+                       }
+                       break;
+               }
+               e = &d;
+               /* fallthru */
+
+       default:
+               Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+                       "could not retrieve deleteDN ID - no such entry\n", 
+                       0, 0, 0 );
+               goto done;
+       }
+
+       if ( !access_allowed( op, &d, slap_schema.si_ad_entry, 
+                       NULL, ACL_WRITE, NULL ) )
+       {
                Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
-                       "could not lookup entry id\n", 0, 0, 0 );
+                       "no write access to entry\n", 
+                       0, 0, 0 );
+               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+               e = &d;
                goto done;
        }
 
@@ -144,16 +173,18 @@ backsql_delete( Operation *op, SlapReply *rs )
                /* fallthru */
 
        default:
+               e = &d;
                goto done;
        }
 
-       oc = backsql_id2oc( bi, e_id.eid_oc_id );
+       oc = backsql_id2oc( bi, bsi.bsi_base_id.eid_oc_id );
        if ( oc == NULL ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
                        "cannot determine objectclass of entry -- aborting\n",
                        0, 0, 0 );
                rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                rs->sr_text = "operation not permitted within namingContext";
+               e = NULL;
                goto done;
        }
 
@@ -163,12 +194,48 @@ backsql_delete( Operation *op, SlapReply *rs )
                        "for this objectclass - aborting\n", 0, 0, 0 );
                rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                rs->sr_text = "operation not permitted within namingContext";
+               e = NULL;
                goto done;
        }
 
+       /*
+        * Get the parent
+        */
+       dnParent( &op->o_req_ndn, &pdn );
+       bsi.bsi_e = &p;
+       e_id = bsi.bsi_base_id;
+       rc = backsql_init_search( &bsi, &pdn,
+                       LDAP_SCOPE_BASE, 
+                       SLAP_NO_LIMIT, SLAP_NO_LIMIT,
+                       (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
+                       BACKSQL_ISF_GET_ENTRY );
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+                       "could not retrieve deleteDN ID - no such entry\n", 
+                       0, 0, 0 );
+               e = &p;
+               goto done;
+       }
+
+       (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+
+       /* check parent for "children" acl */
+       if ( !access_allowed( op, &p, slap_schema.si_ad_children, 
+                       NULL, ACL_WRITE, NULL ) )
+       {
+               Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
+                       "no write access to parent\n", 
+                       0, 0, 0 );
+               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+               e = &p;
+               goto done;
+
+       }
+
        /* avl_apply ... */
        rs->sr_err = backsql_delete_all_attrs( op, rs, dbh, &e_id, oc );
        if ( rs->sr_err != LDAP_SUCCESS ) {
+               e = &d;
                goto done;
        }
 
@@ -182,6 +249,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
@@ -199,6 +267,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                        rs->sr_text = "SQL-backend error";
                        rs->sr_err = LDAP_OTHER;
+                       e = NULL;
                        goto done;
                }
 
@@ -218,6 +287,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -242,6 +312,7 @@ backsql_delete( Operation *op, SlapReply *rs )
                        rs->sr_err = LDAP_OTHER;
                }
                SQLFreeStmt( sth, SQL_DROP );
+               e = &d;
                goto done;
        }
        SQLFreeStmt( sth, SQL_DROP );
@@ -257,6 +328,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
@@ -273,6 +345,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -292,6 +365,7 @@ backsql_delete( Operation *op, SlapReply *rs )
                SQLFreeStmt( sth, SQL_DROP );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
        SQLFreeStmt( sth, SQL_DROP );
@@ -307,6 +381,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
@@ -323,6 +398,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -342,6 +418,7 @@ backsql_delete( Operation *op, SlapReply *rs )
                SQLFreeStmt( sth, SQL_DROP );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
        SQLFreeStmt( sth, SQL_DROP );
@@ -357,6 +434,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
@@ -373,6 +451,7 @@ backsql_delete( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -385,6 +464,7 @@ backsql_delete( Operation *op, SlapReply *rs )
                SQLFreeStmt( sth, SQL_DROP );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
        SQLFreeStmt( sth, SQL_DROP );
@@ -407,10 +487,39 @@ done:;
        }
        SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
 
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+       if ( e != NULL ) {
+               if ( !access_allowed( op, e, slap_schema.si_ad_entry, NULL,
+                                       ACL_DISCLOSE, NULL ) )
+               {
+                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                       rs->sr_text = NULL;
+                       rs->sr_matched = NULL;
+                       if ( rs->sr_ref ) {
+                               ber_bvarray_free( rs->sr_ref );
+                               rs->sr_ref = NULL;
+                       }
+               }
+       }
+
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
+
        send_ldap_result( op, rs );
 
        Debug( LDAP_DEBUG_TRACE, "<==backsql_delete()\n", 0, 0, 0 );
 
-       return ( ( rs->sr_err == LDAP_SUCCESS ) ? op->o_noop : 1 );
+       if ( !BER_BVISNULL( &e_id.eid_ndn ) ) {
+               (void)backsql_free_entryID( op, &e_id, 0 );
+       }
+
+       if ( !BER_BVISNULL( &d.e_nname ) ) {
+               entry_clean( &d );
+       }
+
+       if ( !BER_BVISNULL( &p.e_nname ) ) {
+               entry_clean( &p );
+       }
+
+       return rs->sr_err;
 }
 
index 03e19aa2951113ee3bf74e9c424d72f71eec4e55..18dbba5fd85436fc0cef2ba99b714421fd8c72c6 100644 (file)
@@ -35,7 +35,7 @@ struct berval backsql_baseObject_bv = BER_BVC( BACKSQL_BASEOBJECT_IDSTR );
 #endif /* BACKSQL_ARBITRARY_KEY */
 
 backsql_entryID *
-backsql_free_entryID( backsql_entryID *id, int freeit )
+backsql_free_entryID( Operation *op, backsql_entryID *id, int freeit )
 {
        backsql_entryID         *next;
 
@@ -47,28 +47,28 @@ backsql_free_entryID( backsql_entryID *id, int freeit )
                if ( !BER_BVISNULL( &id->eid_dn )
                                && id->eid_dn.bv_val != id->eid_ndn.bv_val )
                {
-                       free( id->eid_dn.bv_val );
+                       op->o_tmpfree( id->eid_dn.bv_val, op->o_tmpmemctx );
                        BER_BVZERO( &id->eid_dn );
                }
 
-               free( id->eid_ndn.bv_val );
+               op->o_tmpfree( id->eid_ndn.bv_val, op->o_tmpmemctx );
                BER_BVZERO( &id->eid_ndn );
        }
 
 #ifdef BACKSQL_ARBITRARY_KEY
-       if ( id->eid_id.bv_val ) {
-               free( id->eid_id.bv_val );
+       if ( !BER_BVISNULL( &id->eid_id ) ) {
+               op->o_tmpfree( id->eid_id.bv_val, op->o_tmpmemctx );
                BER_BVZERO( &id->eid_id );
        }
 
-       if ( id->eid_keyval.bv_val ) {
-               free( id->eid_keyval.bv_val );
+       if ( !BER_BVISNULL( &id->eid_keyval ) ) {
+               op->o_tmpfree( id->eid_keyval.bv_val, op->o_tmpmemctx );
                BER_BVZERO( &id->eid_keyval );
        }
 #endif /* BACKSQL_ARBITRARY_KEY */
 
        if ( freeit ) {
-               free( id );
+               op->o_tmpfree( id, op->o_tmpmemctx );
        }
 
        return next;
@@ -110,6 +110,11 @@ backsql_dn2id(
                        ndn->bv_val, id == NULL ? " (no ID expected)" : "",
                        matched ? " matched expected" : "" );
 
+       if ( id ) {
+               /* NOTE: trap inconsistencies */
+               assert( BER_BVISNULL( &id->eid_ndn ) );
+       }
+
        if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
                Debug( LDAP_DEBUG_TRACE, 
                        "   backsql_dn2id(\"%s\"): DN length=%ld "
@@ -125,16 +130,20 @@ backsql_dn2id(
        {
                if ( id != NULL ) {
 #ifdef BACKSQL_ARBITRARY_KEY
-                       ber_dupbv( &id->eid_id, &backsql_baseObject_bv );
-                       ber_dupbv( &id->eid_keyval, &backsql_baseObject_bv );
+                       ber_dupbv_x( &id->eid_id, &backsql_baseObject_bv,
+                                       op->o_tmpmemctx );
+                       ber_dupbv_x( &id->eid_keyval, &backsql_baseObject_bv,
+                                       op->o_tmpmemctx );
 #else /* ! BACKSQL_ARBITRARY_KEY */
                        id->eid_id = BACKSQL_BASEOBJECT_ID;
                        id->eid_keyval = BACKSQL_BASEOBJECT_KEYVAL;
 #endif /* ! BACKSQL_ARBITRARY_KEY */
                        id->eid_oc_id = BACKSQL_BASEOBJECT_OC;
 
-                       ber_dupbv( &id->eid_ndn, &bi->sql_baseObject->e_nname );
-                       ber_dupbv( &id->eid_dn, &bi->sql_baseObject->e_name );
+                       ber_dupbv_x( &id->eid_ndn, &bi->sql_baseObject->e_nname,
+                                       op->o_tmpmemctx );
+                       ber_dupbv_x( &id->eid_dn, &bi->sql_baseObject->e_name,
+                                       op->o_tmpmemctx );
 
                        id->eid_next = NULL;
                }
@@ -242,8 +251,10 @@ backsql_dn2id(
                        struct berval   dn;
 
 #ifdef BACKSQL_ARBITRARY_KEY
-                       ber_str2bv( row.cols[ 0 ], 0, 1, &id->eid_id );
-                       ber_str2bv( row.cols[ 1 ], 0, 1, &id->eid_keyval );
+                       ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id,
+                                       op->o_tmpmemctx );
+                       ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval,
+                                       op->o_tmpmemctx );
 #else /* ! BACKSQL_ARBITRARY_KEY */
                        id->eid_id = strtol( row.cols[ 0 ], NULL, 0 );
                        id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 );
@@ -256,7 +267,9 @@ backsql_dn2id(
                                res = LDAP_OTHER;
 
                        } else {
-                               res = dnPrettyNormal( NULL, &dn, &id->eid_dn, &id->eid_ndn, NULL );
+                               res = dnPrettyNormal( NULL, &dn,
+                                               &id->eid_dn, &id->eid_ndn,
+                                               op->o_tmpmemctx );
                                if ( res != LDAP_SUCCESS ) {
                                        Debug( LDAP_DEBUG_TRACE,
                                                "   backsql_dn2id(\"%s\"): "
@@ -265,7 +278,7 @@ backsql_dn2id(
                                                ldap_err2string( res ) );
 
                                        /* cleanup... */
-                                       (void)backsql_free_entryID( id, 0 );
+                                       (void)backsql_free_entryID( op, id, 0 );
                                }
 
                                if ( dn.bv_val != row.cols[ 3 ] ) {
@@ -278,6 +291,40 @@ backsql_dn2id(
 
        } else {
                res = LDAP_NO_SUCH_OBJECT;
+               if ( matched ) {
+                       struct berval   pdn = *ndn;
+
+                       /*
+                        * Look for matched
+                        */
+                       rs->sr_matched = NULL;
+                       while ( !be_issuffix( op->o_bd, &pdn ) ) {
+                               struct berval   dn;
+                               char            *matchedDN = NULL;
+       
+                               dn = pdn;
+                               dnParent( &dn, &pdn );
+       
+                               /*
+                                * Empty DN ("") defaults to LDAP_SUCCESS
+                                */
+                               rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, id, 0, 1 );
+                               switch ( rs->sr_err ) {
+                               case LDAP_NO_SUCH_OBJECT:
+                                       /* try another one */
+                                       break;
+                                       
+                               case LDAP_SUCCESS:
+                                       matchedDN = pdn.bv_val;
+                                       /* fail over to next case */
+       
+                               default:
+                                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                                       rs->sr_matched = matchedDN;
+                                       goto done;
+                               } 
+                       }
+               }
        }
        backsql_FreeRow( &row );
 
@@ -511,7 +558,8 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
 int
 backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
 {
-       backsql_info            *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
+       Operation               *op = bsi->bsi_op;
+       backsql_info            *bi = (backsql_info *)op->o_bd->be_private;
        int                     i;
        int                     rc;
 
@@ -534,8 +582,8 @@ backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
                goto done;
        }
 
-       ber_dupbv( &bsi->bsi_e->e_name, &eid->eid_dn );
-       ber_dupbv( &bsi->bsi_e->e_nname, &eid->eid_ndn );
+       ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, op->o_tmpmemctx );
+       ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, op->o_tmpmemctx );
 
        bsi->bsi_e->e_attrs = NULL;
        bsi->bsi_e->e_private = NULL;
@@ -545,6 +593,7 @@ backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
        bsi->bsi_c_eid = eid;
 
 #ifndef BACKSQL_ARBITRARY_KEY  
+       /* FIXME: unused */
        bsi->bsi_e->e_id = eid->eid_id;
 #endif /* ! BACKSQL_ARBITRARY_KEY */
  
@@ -567,7 +616,7 @@ backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
        } else {
                Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
                        "custom attribute list\n", 0, 0, 0 );
-               for ( i = 0; bsi->bsi_attrs[ i ].an_name.bv_val; i++ ) {
+               for ( i = 0; !BER_BVISNULL( &bsi->bsi_attrs[ i ].an_name ); i++ ) {
                        backsql_at_map_rec      **vat;
                        AttributeName           *an = &bsi->bsi_attrs[ i ];
                        int                     j;
@@ -577,7 +626,7 @@ backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
                         * because subtypes are already dealt with
                         * by backsql_supad2at()
                         */
-                       for ( j = 0; bsi->bsi_attrs[ j ].an_name.bv_val; j++ ) {
+                       for ( j = 0; !BER_BVISNULL( &bsi->bsi_attrs[ j ].an_name ); j++ ) {
                                /* skip self */
                                if ( j == i ) {
                                        continue;
index 2f4199d8539051bddb21f512335e325c77242acf..4ec90b2c3addac93d001cfabd450c83b9520dcfb 100644 (file)
@@ -60,27 +60,19 @@ backsql_modify( Operation *op, SlapReply *rs )
                goto done;
        }
 
-       /* FIXME: using all attributes because of access control later ... */
+       bsi.bsi_e = &e;
        rs->sr_err = backsql_init_search( &bsi, &op->o_req_ndn,
                        LDAP_SCOPE_BASE, 
                        SLAP_NO_LIMIT, SLAP_NO_LIMIT,
                        (time_t)(-1), NULL, dbh, op, rs,
                        slap_anlist_all_attributes,
-                       BACKSQL_ISF_GET_ID );
+                       BACKSQL_ISF_GET_ENTRY );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
                        "could not retrieve modifyDN ID - no such entry\n", 
                        0, 0, 0 );
-               rs->sr_err = LDAP_NO_SUCH_OBJECT;
-               goto done;
-       }
-
-       bsi.bsi_e = &e;
-       rs->sr_err = backsql_id2entry( &bsi, &bsi.bsi_base_id );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
-                       "error %d in backsql_id2entry()\n",
-                       rs->sr_err, 0, 0 );
+               /* FIXME: we keep the error code
+                * set by backsql_init_search() */
                goto done;
        }
 
@@ -134,9 +126,7 @@ backsql_modify( Operation *op, SlapReply *rs )
 done:;
        send_ldap_result( op, rs );
 
-       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
-       }
+       (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
 
        if ( bsi.bsi_e != NULL ) {
                entry_clean( bsi.bsi_e );
index d48ccd14f8b49523acb363c0695323aa6626e833..046a726b120eba88a65bb798f27977d1294f3e84 100644 (file)
@@ -223,7 +223,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                "old parent entry id is %ld\n", pe_id.eid_id, 0, 0 );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 
-       (void)backsql_free_entryID( &pe_id, 0 );
+       (void)backsql_free_entryID( op, &pe_id, 0 );
 
        rs->sr_err = backsql_dn2id( op, rs, dbh, new_npdn, &new_pe_id, 0, 1 );
        if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -481,9 +481,7 @@ modrdn_return:;
                }
        }
 
-       if ( !BER_BVISNULL( &new_pe_id.eid_ndn ) ) {
-               (void)backsql_free_entryID( &new_pe_id, 0 );
-       }
+       (void)backsql_free_entryID( op, &new_pe_id, 0 );
 
        send_ldap_result( op, rs );
 
index dbc1d88b6871814a5507eb8fc83ec150de4539e3..d997703d98bc33461a8e6f5b96cd982f486ebf2b 100644 (file)
@@ -196,7 +196,7 @@ backsql_operational(
 
                *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
 
-               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
+               (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
                if ( bsi.bsi_attrs != NULL ) {
                        op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
                }
index 75b2634941bd40cdd1c533ef264a5ebf8a19402c..86657d5b4fa74a86ae51dff43dd0e02987d2bbcc 100644 (file)
@@ -124,7 +124,8 @@ int backsql_count_children( backsql_info *bi, SQLHDBC dbh,
 int backsql_has_children( backsql_info *bi, SQLHDBC dbh, struct berval *dn );
 
 /* frees *id and returns next in list */
-backsql_entryID *backsql_free_entryID( backsql_entryID *id, int freeit );
+backsql_entryID *backsql_free_entryID( Operation *op, backsql_entryID *id,
+               int freeit );
 
 /* turns an ID into an entry */
 int backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *id );
@@ -162,13 +163,6 @@ int backsql_destroy_schema_map( backsql_info *si );
  * search.c
  */
 
-/* the function must collect the entry associated to nbase */
-#define BACKSQL_ISF_GET_ID     0x1U
-#define BACKSQL_ISF_MATCHED    0x2U
-#define BACKSQL_IS_GET_ID(f) \
-       ( ( (f) & BACKSQL_ISF_GET_ID ) == BACKSQL_ISF_GET_ID )
-#define BACKSQL_IS_MATCHED(f) \
-       ( ( (f) & BACKSQL_ISF_MATCHED ) == BACKSQL_ISF_MATCHED )
 int backsql_init_search( backsql_srch_info *bsi, 
                struct berval *nbase, int scope, int slimit, int tlimit,
                time_t stoptime, Filter *filter, SQLHDBC dbh,
index 0f8ac3fa1930f9e7dfd405d3ac872d62f4d6e7f4..e501d1b3bc22d8605e5755ffde4b8e75ecc0f8bc 100644 (file)
@@ -269,10 +269,50 @@ backsql_init_search(
        bsi->bsi_filter_oc = NULL;
 
        if ( BACKSQL_IS_GET_ID( flags ) ) {
+               int     matched = BACKSQL_IS_MATCHED( flags );
+               int     getentry = BACKSQL_IS_GET_ENTRY( flags );
+
                assert( op->o_bd->be_private );
 
                rc = backsql_dn2id( op, rs, dbh, nbase, &bsi->bsi_base_id,
-                               BACKSQL_IS_MATCHED( flags ), 1 );
+                               matched, 1 );
+               
+               if ( ( rc == LDAP_NO_SUCH_OBJECT && matched ) || getentry ) {
+                       if ( !BER_BVISNULL( &bsi->bsi_base_id.eid_ndn ) ) {
+                               assert( bsi->bsi_e != NULL );
+
+                               /*
+                                * let's see if it is a referral and, in case, get it
+                                */
+                               backsql_attrlist_add( bsi, slap_schema.si_ad_ref );
+                               rc = backsql_id2entry( bsi, &bsi->bsi_base_id );
+                               if ( rc == LDAP_SUCCESS && is_entry_referral( bsi->bsi_e ) )
+                               {
+                                       BerVarray erefs = get_entry_referrals( op, bsi->bsi_e );
+                                       if ( erefs ) {
+                                               rc = rs->sr_err = LDAP_REFERRAL;
+                                               rs->sr_ref = referral_rewrite( erefs,
+                                                               &bsi->bsi_e->e_nname,
+                                                               &op->o_req_dn,
+                                                               scope );
+                                               ber_bvarray_free( erefs );
+
+                                       } else {
+                                               rc = rs->sr_err = LDAP_OTHER;
+                                               rs->sr_text = "bad referral object";
+                                       }
+
+                               } else {
+                                       rc = rs->sr_err = getentry ?
+                                               LDAP_SUCCESS : LDAP_NO_SUCH_OBJECT;
+                               }
+
+                       } else {
+                               rs->sr_ref = referral_rewrite( default_referral,
+                                               NULL, &op->o_req_dn, scope );
+                               rc = rs->sr_err = LDAP_REFERRAL;
+                       }
+               }
        }
 
        bsi->bsi_status = rc;
@@ -1397,6 +1437,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 {
        backsql_oc_map_rec      *oc = v_oc;
        backsql_srch_info       *bsi = v_bsi;
+       Operation               *op = bsi->bsi_op;
        backsql_info            *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
        struct berval           query;
        SQLHSTMT                sth = SQL_NULL_HSTMT;
@@ -1666,7 +1707,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
                        continue;
                }
 
-               ret = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
+               ret = dnPrettyNormal( NULL, &dn, &pdn, &ndn, op->o_tmpmemctx );
                if ( dn.bv_val != row.cols[ 3 ] ) {
                        free( dn.bv_val );
                }
@@ -1676,16 +1717,18 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
                }
 
                if ( bi->sql_baseObject && dn_match( &ndn, &bi->sql_baseObject->e_nname ) ) {
-                       free( pdn.bv_val );
-                       free( ndn.bv_val );
+                       op->o_tmpfree( pdn.bv_val, op->o_tmpmemctx );
+                       op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
                        continue;
                }
 
                c_id = (backsql_entryID *)ch_calloc( 1, 
                                sizeof( backsql_entryID ) );
 #ifdef BACKSQL_ARBITRARY_KEY
-               ber_str2bv( row.cols[ 0 ], 0, 1, &c_id->eid_id );
-               ber_str2bv( row.cols[ 1 ], 0, 1, &c_id->eid_keyval );
+               ber_str2bv_x( row.cols[ 0 ], 0, 1, &c_id->eid_id,
+                               op->o_tmpmemctx );
+               ber_str2bv_x( row.cols[ 1 ], 0, 1, &c_id->eid_keyval,
+                               op->o_tmpmemctx );
 #else /* ! BACKSQL_ARBITRARY_KEY */
                c_id->eid_id = strtol( row.cols[ 0 ], NULL, 0 );
                c_id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 );
@@ -1732,7 +1775,8 @@ backsql_search( Operation *op, SlapReply *rs )
        backsql_info            *bi = (backsql_info *)op->o_bd->be_private;
        SQLHDBC                 dbh = SQL_NULL_HDBC;
        int                     sres;
-       Entry                   user_entry = { 0 };
+       Entry                   user_entry = { 0 },
+                               base_entry = { 0 };
        int                     manageDSAit;
        time_t                  stoptime = 0;
        backsql_srch_info       bsi;
@@ -1793,30 +1837,57 @@ backsql_search( Operation *op, SlapReply *rs )
        }
 
        /* init search */
+       bsi.bsi_e = &base_entry;
        rs->sr_err = backsql_init_search( &bsi, &realndn,
                        op->ors_scope,
                        op->ors_slimit, op->ors_tlimit,
                        stoptime, op->ors_filter,
                        dbh, op, rs, op->ors_attrs,
-                       BACKSQL_ISF_GET_ID );
+                       ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
        if ( rs->sr_err != LDAP_SUCCESS ) {
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+               if ( !BER_BVISNULL( &base_entry.e_nname )
+                               && ! access_allowed( op, &base_entry,
+                                       slap_schema.si_ad_entry, NULL,
+                                       ACL_DISCLOSE, NULL ) )
+               {
+                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                       if ( rs->sr_ref ) {
+                               ber_bvarray_free( rs->sr_ref );
+                       }
+                       rs->sr_matched = NULL;
+                       rs->sr_text = NULL;
+               }
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
                send_ldap_result( op, rs );
                goto done;
 
-       } else {
-               Entry   e = { 0 };
+       }
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+       /* NOTE: __NEW__ "search" access is required
+        * on searchBase object */
+       else {
+               slap_mask_t     mask;
 
-               e.e_name = bsi.bsi_base_id.eid_dn;
-               e.e_nname = bsi.bsi_base_id.eid_ndn;
                /* FIXME: need the whole entry (ITS#3480) */
-               if ( ! access_allowed( op, &e, slap_schema.si_ad_entry,
-                               NULL, ACL_DISCLOSE, NULL ) )
+               if ( ! access_allowed_mask( op, &base_entry,
+                                       slap_schema.si_ad_entry,
+                                       NULL, ACL_SEARCH, NULL, &mask ) )
                {
-                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                       if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) {
+                               rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                               rs->sr_text = NULL;
+
+                       } else {
+                               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+                       }
                        send_ldap_result( op, rs );
                        goto done;
                }
        }
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
+
+       bsi.bsi_e = NULL;
 
        bsi.bsi_n_candidates =
                ( op->ors_limit == NULL /* isroot == TRUE */ ? -2 : 
@@ -1872,7 +1943,8 @@ backsql_search( Operation *op, SlapReply *rs )
         */
        for ( eid = bsi.bsi_id_list;
                        eid != NULL; 
-                       eid = backsql_free_entryID( eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )
+                       eid = backsql_free_entryID( op,
+                               eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )
        {
                int             rc;
                Attribute       *a_hasSubordinate = NULL,
@@ -1942,15 +2014,20 @@ backsql_search( Operation *op, SlapReply *rs )
                case LDAP_SCOPE_SUBTREE:
                        /* FIXME: this should never fail... */
                        if ( !dnIsSuffix( &eid->eid_ndn, &op->o_req_ndn ) ) {
+                               assert( 0 );
                                goto next_entry2;
                        }
                        break;
                }
 
-               /* don't recollect baseObject ... */
                if ( BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
+                       /* don't recollect baseObject... */
                        e = bi->sql_baseObject;
 
+               } else if ( eid == &bsi.bsi_base_id ) {
+                       /* don't recollect searchBase object... */
+                       e = &base_entry;
+
                } else {
                        bsi.bsi_e = &user_entry;
                        rc = backsql_id2entry( &bsi, eid );
@@ -1960,7 +2037,6 @@ backsql_search( Operation *op, SlapReply *rs )
                                        "- skipping\n", rc, 0, 0 );
                                continue;
                        }
-
                        e = &user_entry;
                }
 
@@ -1977,20 +2053,22 @@ backsql_search( Operation *op, SlapReply *rs )
                                Entry                   user_entry2 = { 0 };
 
                                /* retry with the full entry... */
-                               (void)backsql_init_search( &bsi2,
+                               bsi2.bsi_e = &user_entry2;
+                               rc = backsql_init_search( &bsi2,
                                                &e->e_nname,
                                                LDAP_SCOPE_BASE, 
                                                SLAP_NO_LIMIT, SLAP_NO_LIMIT,
                                                (time_t)(-1), NULL,
-                                               dbh, op, rs, NULL, 0 );
-                               bsi2.bsi_e = &user_entry2;
-                               rc = backsql_id2entry( &bsi2, eid );
+                                               dbh, op, rs, NULL,
+                                               BACKSQL_ISF_GET_ENTRY );
                                if ( rc == LDAP_SUCCESS ) {
                                        if ( is_entry_referral( &user_entry2 ) )
                                        {
                                                refs = get_entry_referrals( op,
                                                                &user_entry2 );
-                                       } /* else: FIXME: inconsistency! */
+                                       } else {
+                                               rs->sr_err = LDAP_OTHER;
+                                       }
                                        entry_clean( &user_entry2 );
                                }
                                if ( bsi2.bsi_attrs != NULL ) {
@@ -2007,12 +2085,14 @@ backsql_search( Operation *op, SlapReply *rs )
                                ber_bvarray_free( refs );
                        }
 
-                       if ( !rs->sr_ref ) {
+                       if ( rs->sr_ref ) {
+                               rs->sr_err = LDAP_REFERRAL;
+
+                       } else {
                                rs->sr_text = "bad referral object";
                        }
 
                        rs->sr_entry = e;
-                       rs->sr_err = LDAP_REFERRAL;
                        rs->sr_matched = user_entry.e_name.bv_val;
                        send_search_reference( op, rs );
 
@@ -2098,16 +2178,11 @@ backsql_search( Operation *op, SlapReply *rs )
                        rs->sr_attrs = NULL;
                        rs->sr_operational_attrs = NULL;
 
-                       switch ( sres ) {
-                       case 0:
-                               break;
-
-                       default:
+                       if ( sres == -1 ) {
                                /*
                                 * FIXME: send_search_entry failed;
                                 * better stop
                                 */
-                       case -1:
                                Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
                                        "connection lost\n", 0, 0, 0 );
                                goto end_of_search;
@@ -2115,7 +2190,9 @@ backsql_search( Operation *op, SlapReply *rs )
                }
 
 next_entry:;
-               entry_clean( &user_entry );
+               if ( e == &user_entry ) {
+                       entry_clean( &user_entry );
+               }
 
 next_entry2:;
                if ( op->ors_slimit != SLAP_NO_LIMIT
@@ -2128,6 +2205,8 @@ next_entry2:;
        }
 
 end_of_search:;
+       entry_clean( &base_entry );
+
        /* in case we got here accidentally */
        entry_clean( &user_entry );
 
@@ -2172,9 +2251,7 @@ done:;
                ch_free( realndn.bv_val );
        }
 
-       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
-       }
+       (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
 
        if ( bsi.bsi_attrs != NULL ) {
                op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
@@ -2213,6 +2290,8 @@ backsql_entry_get(
        SlapReply               rs = { 0 };
        AttributeName           anlist[ 2 ];
 
+       *ent = NULL;
+
        rc = backsql_get_db_conn( op, &dbh );
        if ( !dbh ) {
                return LDAP_OTHER;
@@ -2224,23 +2303,16 @@ backsql_entry_get(
                BER_BVZERO( &anlist[ 1 ].an_name );
        }
 
+       bsi.bsi_e = ch_malloc( sizeof( Entry ) );
        rc = backsql_init_search( &bsi,
                        ndn,
                        LDAP_SCOPE_BASE, 
                        SLAP_NO_LIMIT, SLAP_NO_LIMIT,
                        (time_t)(-1), NULL,
                        dbh, op, &rs, at ? anlist : NULL,
-                       BACKSQL_ISF_GET_ID );
-       if ( rc != LDAP_SUCCESS ) {
-               return rc;
-       }
+                       BACKSQL_ISF_GET_ENTRY );
 
-       bsi.bsi_e = ch_malloc( sizeof( Entry ) );
-       rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
-
-       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
-       }
+       (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
 
        if ( rc == LDAP_SUCCESS ) {