]> git.sur5r.net Git - openldap/commitdiff
fixes for ITS#3480,3485,3489; implementation of DISCLOSE access for all operations...
authorPierangelo Masarati <ando@openldap.org>
Sun, 16 Jan 2005 23:12:36 +0000 (23:12 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 16 Jan 2005 23:12:36 +0000 (23:12 +0000)
13 files changed:
doc/man/man5/slapd-sql.5
servers/slapd/back-sql/add.c
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/compare.c
servers/slapd/back-sql/delete.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/init.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/proto-sql.h
servers/slapd/back-sql/schema-map.c
servers/slapd/back-sql/search.c
servers/slapd/back-sql/util.c

index ba1aae1a3e56a6683b2291bcac06a717224289b3..34aa56172c2f83d0a0e1208a61524d01d51e066b 100644 (file)
@@ -301,6 +301,22 @@ in table \fIldap_entries\fP needs a subsequent select to collect
 the automatically assigned ID, instead of being returned 
 by a stored procedure.
 
+.LP
+.B fetch_attrs <attrlist>
+.br
+.B fetch_all_attrs { NO | yes }
+.RS
+The first statement allows to provide a list of attributes that
+must always be fetched in addition to those requested by any specific
+operation, because they are required for the proper usage of the
+backend.  For instance, all attributes used in ACLs should be listed
+here.  The second statement is a shortcut to require all attributes 
+to be always loaded.  Note that the dynamically generated attributes,
+e.g. \fIhasSubordinates\fP, \fIentryDN\fP and other implementation
+dependent attributes are \fBNOT\fP generated at this point, for
+consistency with the rest of slapd.  This may change in the future.
+.RE
+
 .TP
 .B sqllayer <name> [...]
 Loads the layer \fB<name>\fP onto a stack of helpers that are used 
index c57d64e1f91eadf00a4becd279b53ad843e2f75b..96a9ef10df6ed6e72c510d474b9e8ad64aa53388 100644 (file)
@@ -952,7 +952,6 @@ backsql_add( Operation *op, SlapReply *rs )
        RETCODE                 rc;
        backsql_oc_map_rec      *oc = NULL;
        backsql_srch_info       bsi;
-       backsql_entryID         parent_id = BACKSQL_ENTRYID_INIT;
        Entry                   p = { 0 }, *e = NULL;
        Attribute               *at,
                                *at_objectClass = NULL;
@@ -1125,6 +1124,15 @@ backsql_add( Operation *op, SlapReply *rs )
                goto done;
        }
 
+       if ( get_assert( op ) &&
+               ( test_filter( op, op->oq_add.rs_e, get_assertion( op ) )
+                       != LDAP_COMPARE_TRUE ) )
+       {
+               rs->sr_err = LDAP_ASSERTION_FAILED;
+               e = op->ora_e;
+               goto done;
+       }
+
        if ( !access_allowed_mask( op, op->ora_e,
                                slap_schema.si_ad_entry,
                                NULL, ACL_WRITE, NULL, &mask ) )
@@ -1140,7 +1148,7 @@ 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 );
+       rc = backsql_Prepare( dbh, &sth, oc->bom_create_proc, 0 );
        if ( rc != SQL_SUCCESS ) {
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
@@ -1152,10 +1160,11 @@ backsql_add( Operation *op, SlapReply *rs )
        if ( BACKSQL_IS_ADD( oc->bom_expect_return ) ) {
                rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &new_keyval );
                if ( rc != SQL_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "   backsql_add_attr(): "
-                               "error binding keyval parameter for objectClass %s\n",
-                               oc->bom_oc->soc_cname.bv_val, 0, 0 );
+                       Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                               "error binding keyval parameter "
+                               "for objectClass %s\n",
+                               op->ora_e->e_name.bv_val,
+                               oc->bom_oc->soc_cname.bv_val, 0 );
                        backsql_PrintErrors( bi->sql_db_env, dbh, 
                                sth, rc );
                        SQLFreeStmt( sth, SQL_DROP );
@@ -1186,11 +1195,12 @@ backsql_add( Operation *op, SlapReply *rs )
                                        oc->bom_create_hint->ad_cname.bv_val,
                                        0, 0 );
                }
+               colnum++;
        }
 
        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): executing \"%s\"\n",
                op->ora_e->e_name.bv_val, oc->bom_create_proc, 0 );
-       rc = SQLExecDirect( sth, oc->bom_create_proc, SQL_NTS );
+       rc = SQLExecute( sth );
        if ( rc != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "create_proc execution failed\n",
@@ -1203,9 +1213,8 @@ backsql_add( Operation *op, SlapReply *rs )
                goto done;
        }
 
-       if ( op->o_noop ) {
-               SQLTransact( SQL_NULL_HENV, dbh, SQL_ROLLBACK );
-       }
+       /* FIXME: after SQLExecute(), the row is already inserted
+        * (at least with PostgreSQL and unixODBC); needs investigation */
 
        if ( !BACKSQL_IS_ADD( oc->bom_expect_return ) ) {
                SWORD           ncols;
@@ -1213,7 +1222,8 @@ backsql_add( Operation *op, SlapReply *rs )
 
                if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) {
                        SQLFreeStmt( sth, SQL_DROP );
-                       rc = SQLAllocStmt( dbh, &sth );
+
+                       rc = backsql_Prepare( dbh, &sth, oc->bom_create_keyval, 0 );
                        if ( rc != SQL_SUCCESS ) {
                                rs->sr_err = LDAP_OTHER;
                                rs->sr_text = "SQL-backend error";
@@ -1221,7 +1231,7 @@ backsql_add( Operation *op, SlapReply *rs )
                                goto done;
                        }
 
-                       rc = SQLExecDirect( sth, oc->bom_create_keyval, SQL_NTS );
+                       rc = SQLExecute( sth );
                        if ( rc != SQL_SUCCESS ) {
                                rs->sr_err = LDAP_OTHER;
                                rs->sr_text = "SQL-backend error";
@@ -1340,10 +1350,10 @@ backsql_add( Operation *op, SlapReply *rs )
        
        rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &realdn );
        if ( rc != SQL_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "   backsql_add_attr(): "
+               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "error binding DN parameter for objectClass %s\n",
-                       oc->bom_oc->soc_cname.bv_val, 0, 0 );
+                       op->ora_e->e_name.bv_val,
+                       oc->bom_oc->soc_cname.bv_val, 0 );
                backsql_PrintErrors( bi->sql_db_env, dbh, 
                        sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
@@ -1356,10 +1366,11 @@ backsql_add( Operation *op, SlapReply *rs )
 
        rc = backsql_BindParamInt( sth, 2, SQL_PARAM_INPUT, &oc->bom_id );
        if ( rc != SQL_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "   backsql_add_attr(): "
-                       "error binding objectClass ID parameter for objectClass %s\n",
-                       oc->bom_oc->soc_cname.bv_val, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       "error binding objectClass ID parameter "
+                       "for objectClass %s\n",
+                       op->ora_e->e_name.bv_val,
+                       oc->bom_oc->soc_cname.bv_val, 0 );
                backsql_PrintErrors( bi->sql_db_env, dbh, 
                        sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
@@ -1370,12 +1381,13 @@ backsql_add( Operation *op, SlapReply *rs )
                goto done;
        }
 
-       rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &parent_id.eid_id );
+       rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &bsi.bsi_base_id.eid_id );
        if ( rc != SQL_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "   backsql_add_attr(): "
-                       "error binding parent ID parameter for objectClass %s\n",
-                       oc->bom_oc->soc_cname.bv_val, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       "error binding parent ID parameter "
+                       "for objectClass %s\n",
+                       op->ora_e->e_name.bv_val,
+                       oc->bom_oc->soc_cname.bv_val, 0 );
                backsql_PrintErrors( bi->sql_db_env, dbh, 
                        sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
@@ -1388,10 +1400,11 @@ backsql_add( Operation *op, SlapReply *rs )
 
        rc = backsql_BindParamInt( sth, 4, SQL_PARAM_INPUT, &new_keyval );
        if ( rc != SQL_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "   backsql_add_attr(): "
-                       "error binding entry ID parameter for objectClass %s\n",
-                       oc->bom_oc->soc_cname.bv_val, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       "error binding entry ID parameter "
+                       "for objectClass %s\n",
+                       op->ora_e->e_name.bv_val,
+                       oc->bom_oc->soc_cname.bv_val, 0 );
                backsql_PrintErrors( bi->sql_db_env, dbh, 
                        sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
@@ -1406,12 +1419,12 @@ backsql_add( Operation *op, SlapReply *rs )
                        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",
-                       oc->bom_id, parent_id.eid_id.bv_val, new_keyval );
+                       "p_id=%s, keyval=%ld\n",
+                       oc->bom_id, bsi.bsi_base_id.eid_id.bv_val, new_keyval );
 #else /* ! BACKSQL_ARBITRARY_KEY */
        Debug( LDAP_DEBUG_TRACE, "                  for oc_map_id=%ld, "
-                       "parent_id=%ld, keyval=%ld\n",
-                       oc->bom_id, parent_id.eid_id, new_keyval );
+                       "p_id=%ld, keyval=%ld\n",
+                       oc->bom_id, bsi.bsi_base_id.eid_id, new_keyval );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
        rc = SQLExecute( sth );
        if ( rc != SQL_SUCCESS ) {
@@ -1430,26 +1443,29 @@ backsql_add( Operation *op, SlapReply *rs )
                goto done;
        }
 
-       /* FIXME: need ldap_entries.id of newly added entry */
+       SQLFreeStmt( sth, SQL_DROP );
+
        if ( at_objectClass ) {
-               rs->sr_err = backsql_add_attr( op, rs, dbh, oc, at_objectClass, new_keyval );
+               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;
                }
        }
 
-       SQLFreeStmt( sth, SQL_DROP );
-
 done:;
        /*
         * Commit only if all operations succeed
         */
-       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
-               SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
+       if ( sth != SQL_NULL_HSTMT ) {
+               SQLUSMALLINT    CompletionType = SQL_ROLLBACK;
 
-       } else {
-               SQLTransact( SQL_NULL_HENV, dbh, SQL_ROLLBACK );
+               if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+                       CompletionType = SQL_COMMIT;
+               }
+
+               SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
        }
 
        /*
@@ -1497,7 +1513,10 @@ done:;
        {
                ch_free( realdn.bv_val );
        }
-       (void)backsql_free_entryID( op, &parent_id, 0 );
+
+       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
+               (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+       }
 
        if ( !BER_BVISNULL( &p.e_nname ) ) {
                entry_clean( &p );
index fb285c0c5e860e59ce670d222c90ebd4cb59f03e..e91736288b87df440a54f999be9b5687bb417f27 100644 (file)
  * 1. id_query.patch           applied (with changes)
  * 2. shortcut.patch           applied (reworked)
  * 3. create_hint.patch                applied
- * 4. count_query.patch                rejected (conflicts with other features)
+ * 4. count_query.patch                applied (reworked)
  * 5. returncodes.patch                applied (with sanity checks)
  * 6. connpool.patch           under evaluation
- * 7. modoc.patch              under evaluation
- * 8. miscfixes.patch          applied (reworked; FIXME: other
- *                             operations may need to load the
- *                             entire entry for ACL purposes)
+ * 7. modoc.patch              under evaluation (requires
+ *                             manageDSAit and "manage"
+ *                             access privileges)
+ * 8. miscfixes.patch          applied (reworked; other
+ *                             operations need to load the
+ *                             entire entry for ACL purposes;
+ *                             see ITS#3480, now fixed)
  *
  * original description:
 
@@ -195,6 +198,16 @@ typedef struct {
  */
 #undef BACKSQL_TRACE
 
+/*
+ * define to enable values counting for attributes
+ */
+#define BACKSQL_COUNTQUERY
+
+/*
+ * define to enable prettification/validation of values
+ */
+#define BACKSQL_PRETTY_VALIDATE
+
 /*
  * define to enable varchars as unique keys in user tables
  *
@@ -333,6 +346,9 @@ typedef struct backsql_at_map_rec {
        /* for optimization purposes attribute load query 
         * is preconstructed from parts on schemamap load time */
        char            *bam_query;
+#ifdef BACKSQL_COUNTQUERY
+       char            *bam_countquery;
+#endif /* BACKSQL_COUNTQUERY */
        /* following flags are bitmasks (first bit used for add_proc, 
         * second - for delete_proc) */
        /* order of parameters for procedures above; 
index d339009fb671f5db57e46cd67f776ec3ba204c35..4dfb365a0bbca0f49b7171d709ce3dc7af065550 100644 (file)
@@ -79,6 +79,14 @@ backsql_compare( Operation *op, SlapReply *rs )
                goto return_results;
        }
 
+       if ( get_assert( op ) &&
+                       ( test_filter( op, &e, get_assertion( op ) )
+                         != LDAP_COMPARE_TRUE ) )
+       {
+               rs->sr_err = LDAP_ASSERTION_FAILED;
+               goto return_results;
+       }
+
        if ( is_at_operational( op->oq_compare.rs_ava->aa_desc->ad_type ) ) {
                SlapReply       nrs = { 0 };
 
index c07ee3400bf421fb0f36a0b35f587222bcf5244e..e094fb58424f4b112a3262fc1cac39678ad36b6f 100644 (file)
@@ -87,14 +87,13 @@ backsql_delete( Operation *op, SlapReply *rs )
        RETCODE                 rc;
        int                     prc = LDAP_SUCCESS;
        backsql_oc_map_rec      *oc = NULL;
-       backsql_srch_info       bsi;
+       backsql_srch_info       bsi = { 0 };
        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;
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_delete(): deleting entry \"%s\"\n",
                        op->o_req_ndn.bv_val, 0, 0 );
@@ -114,12 +113,12 @@ backsql_delete( Operation *op, SlapReply *rs )
         * Get the entry
         */
        bsi.bsi_e = &d;
-       rc = backsql_init_search( &bsi, &op->o_req_ndn,
+       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_no_attrs,
                        ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
-       switch ( rc ) {
+       switch ( rs->sr_err ) {
        case LDAP_SUCCESS:
                break;
 
@@ -144,6 +143,22 @@ backsql_delete( Operation *op, SlapReply *rs )
                Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
                        "could not retrieve deleteDN ID - no such entry\n", 
                        0, 0, 0 );
+               if ( !BER_BVISNULL( &d.e_nname ) ) {
+                       /* FIXME: should always be true! */
+                       e = &d;
+
+               } else {
+                       e = NULL;
+               }
+               goto done;
+       }
+
+       if ( get_assert( op ) &&
+                       ( test_filter( op, &d, get_assertion( op ) )
+                         != LDAP_COMPARE_TRUE ) )
+       {
+               rs->sr_err = LDAP_ASSERTION_FAILED;
+               e = &d;
                goto done;
        }
 
@@ -204,12 +219,12 @@ backsql_delete( Operation *op, SlapReply *rs )
        dnParent( &op->o_req_ndn, &pdn );
        bsi.bsi_e = &p;
        e_id = bsi.bsi_base_id;
-       rc = backsql_init_search( &bsi, &pdn,
+       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_GET_ENTRY );
-       if ( rc != LDAP_SUCCESS ) {
+       if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
                        "could not retrieve deleteDN ID - no such entry\n", 
                        0, 0, 0 );
@@ -471,22 +486,20 @@ backsql_delete( Operation *op, SlapReply *rs )
 
        rs->sr_err = LDAP_SUCCESS;
 
-done:;
-
        /*
         * Commit only if all operations succeed
-        *
-        * FIXME: backsql_add() does not fail if add operations 
-        * are not available for some attributes, or if
-        * a multiple value add actually results in a replace, 
-        * or if a single operation on an attribute fails 
-        * for any reason
         */
-       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
-               CompletionType = SQL_COMMIT;
+       if ( sth != SQL_NULL_HSTMT ) {
+               SQLUSMALLINT    CompletionType = SQL_ROLLBACK;
+       
+               if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+                       CompletionType = SQL_COMMIT;
+               }
+
+               SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
        }
-       SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
 
+done:;
 #ifdef SLAP_ACL_HONOR_DISCLOSE
        if ( e != NULL ) {
                if ( !access_allowed( op, e, slap_schema.si_ad_entry, NULL,
@@ -501,7 +514,6 @@ done:;
                        }
                }
        }
-
 #endif /* SLAP_ACL_HONOR_DISCLOSE */
 
        send_ldap_result( op, rs );
index 18dbba5fd85436fc0cef2ba99b714421fd8c72c6..abfe7027122e8e8bb089763bf864fbb386181221 100644 (file)
@@ -455,7 +455,21 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
        RETCODE                 rc;
        SQLHSTMT                sth = SQL_NULL_HSTMT;
        BACKSQL_ROW_NTS         row;
-       int                     i;
+       unsigned long           i,
+                               k = 0,
+                               oldcount = 0;
+#ifdef BACKSQL_COUNTQUERY
+       unsigned long           count,
+                               countsize = sizeof( count ),
+                               j;
+       Attribute               *attr = NULL;
+
+       slap_mr_normalize_func          *normfunc = NULL;
+#endif /* BACKSQL_COUNTQUERY */
+#ifdef BACKSQL_PRETTY_VALIDATE
+       slap_syntax_validate_func       *validate = NULL;
+       slap_syntax_transform_func      *pretty = NULL;
+#endif /* BACKSQL_PRETTY_VALIDATE */
 
        assert( at );
        assert( bsi );
@@ -472,9 +486,141 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                bsi->bsi_c_eid->eid_keyval );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 
+#ifdef BACKSQL_PRETTY_VALIDATE
+       validate = at->bam_ad->ad_type->sat_syntax->ssyn_validate;
+       pretty =  at->bam_ad->ad_type->sat_syntax->ssyn_pretty;
+
+       if ( validate == NULL && pretty == NULL ) {
+               return 1;
+       }
+#endif /* BACKSQL_PRETTY_VALIDATE */
+
+#ifdef BACKSQL_COUNTQUERY
+       if ( at->bam_ad->ad_type->sat_equality ) {
+               normfunc = at->bam_ad->ad_type->sat_equality->smr_normalize;
+       }
+
+       /* Count how many rows will be returned. This avoids memory 
+        * fragmentation that can result from loading the values in 
+        * one by one and using realloc() 
+        */
+       rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_countquery, 0 );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
+                       "error preparing count query: %s\n",
+                       at->bam_countquery, 0, 0 );
+               backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
+               return 1;
+       }
+
+       rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
+                       &bsi->bsi_c_eid->eid_keyval );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
+                       "error binding key value parameter\n", 0, 0, 0 );
+               SQLFreeStmt( sth, SQL_DROP );
+               return 1;
+       }
+
+       rc = SQLExecute( sth );
+       if ( ! BACKSQL_SUCCESS( rc ) ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
+                       "error executing attribute count query '%s'\n",
+                       at->bam_countquery, 0, 0 );
+               backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               return 1;
+       }
+
+       SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_LONG,
+                       (SQLPOINTER)&count,
+                       (SQLINTEGER)sizeof( count ),
+                       &countsize );
+
+       rc = SQLFetch( sth );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
+                       "error fetch results of count query: %s\n",
+                       at->bam_countquery, 0, 0 );
+               backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               return 1;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
+               "number of values in query: %d\n", count, 0, 0 );
+       SQLFreeStmt( sth, SQL_DROP );
+       if ( count == 0 ) {
+               return 1;
+       }
+
+       attr = attr_find( bsi->bsi_e->e_attrs, at->bam_ad );
+       if ( attr != NULL ) {
+               BerVarray       tmp;
+
+               if ( attr->a_vals != NULL ) {
+                       for ( ; !BER_BVISNULL( &attr->a_vals[ oldcount ] ); oldcount++ )
+                               /* just count */ ;
+               }
+
+               tmp = ch_realloc( attr->a_vals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
+               if ( tmp == NULL ) {
+                       return 1;
+               }
+               attr->a_vals = tmp;
+               memset( &attr->a_vals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );
+
+               if ( normfunc ) {
+                       tmp = ch_realloc( attr->a_nvals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
+                       if ( tmp == NULL ) {
+                               return 1;
+                       }
+                       attr->a_nvals = tmp;
+                       memset( &attr->a_nvals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );
+
+               } else {
+                       attr->a_nvals = attr->a_vals;
+               }
+
+       } else {
+               Attribute       **ap;
+
+               /* Make space for the array of values */
+               attr = (Attribute *) ch_malloc( sizeof( Attribute ) );
+               attr->a_desc = at->bam_ad;
+               attr->a_flags = 0;
+               attr->a_next = NULL;
+               attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) );
+               if ( attr->a_vals == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 );
+                       ch_free( attr );
+                       return 1;
+               }
+               memset( attr->a_vals, 0, ( count + 1 ) * sizeof( struct berval ) );
+               if ( normfunc ) {
+                       attr->a_nvals = ch_calloc( count + 1, sizeof( struct berval ) );
+                       if ( attr->a_nvals == NULL ) {
+                               ch_free( attr->a_vals );
+                               ch_free( attr );
+                               return 1;
+
+                       } else {
+                               memset( attr->a_nvals, 0, ( count + 1 ) * sizeof( struct berval ) );
+                       }
+
+               } else {
+                       attr->a_nvals = attr->a_vals;
+               }
+
+               for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
+                       /* goto last */ ;
+               *ap =  attr;
+       }
+#endif /* BACKSQL_COUNTQUERY */
+
        rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_query, 0 );
        if ( rc != SQL_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
                        "error preparing query: %s\n", at->bam_query, 0, 0 );
                backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
                return 1;
@@ -483,18 +629,18 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
        rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
                        &bsi->bsi_c_eid->eid_keyval );
        if ( rc != SQL_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
                        "error binding key value parameter\n", 0, 0, 0 );
                return 1;
        }
 
 #ifdef BACKSQL_TRACE
 #ifdef BACKSQL_ARBITRARY_KEY
-       Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+       Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
                "query=\"%s\" keyval=%s\n", at->bam_query,
                bsi->bsi_c_eid->eid_keyval.bv_val, 0 );
 #else /* !BACKSQL_ARBITRARY_KEY */
-       Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+       Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
                "query=\"%s\" keyval=%d\n", at->bam_query,
                bsi->bsi_c_eid->eid_keyval, 0 );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
@@ -502,7 +648,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
 
        rc = SQLExecute( sth );
        if ( ! BACKSQL_SUCCESS( rc ) ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
                        "error executing attribute query \"%s\"\n",
                        at->bam_query, 0, 0 );
                backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
@@ -511,30 +657,146 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
        }
 
        backsql_BindRowAsStrings( sth, &row );
-
-       rc = SQLFetch( sth );
-       for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
+#ifdef BACKSQL_COUNTQUERY
+       j = oldcount;
+#endif /* BACKSQL_COUNTQUERY */
+       for ( rc = SQLFetch( sth ), k = 0;
+                       BACKSQL_SUCCESS( rc );
+                       rc = SQLFetch( sth ), k++ )
+       {
                for ( i = 0; i < row.ncols; i++ ) {
+
                        if ( row.value_len[ i ] > 0 ) {
-                               struct berval   bv;
+                               struct berval           bv;
+                               int                     retval;
+#ifdef BACKSQL_TRACE
+                               AttributeDescription    *ad = NULL;
+                               const char              *text;
+
+                               retval = slap_bv2ad( &row.col_names[ i ], &ad, &text );
+                               if ( retval != LDAP_SUCCESS ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "==>backsql_get_attr_vals(\"%s\"): "
+                                               "unable to find AttributeDescription %s "
+                                               "in schema (%d)\n",
+                                               bsi->bsi_e->e_name.bv_val,
+                                               row.col_names[ i ].bv_val, retval );
+                                       return 1;
+                               }
+
+                               if ( ad != at->bam_ad ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "==>backsql_get_attr_vals(\"%s\"): "
+                                               "column name %s differs from "
+                                               "AttributeDescription %s\n",
+                                               bsi->bsi_e->e_name.bv_val,
+                                               ad->ad_cname.bv_val,
+                                               at->bam_ad->ad_cname.bv_val );
+                                       return 1;
+                               }
+#endif /* BACKSQL_TRACE */
 
-                               bv.bv_val = row.cols[ i ];
-#if 0
-                               bv.bv_len = row.col_prec[ i ];
-#else
                                /*
                                 * FIXME: what if a binary 
                                 * is fetched?
                                 */
-                               bv.bv_len = strlen( row.cols[ i ] );
-#endif
-                               backsql_entry_addattr( bsi->bsi_e, 
-                                               &row.col_names[ i ], &bv,
+                               ber_str2bv( row.cols[ i ], 0, 0, &bv );
+
+#ifdef BACKSQL_PRETTY_VALIDATE
+                               if ( pretty ) {
+                                       struct berval   pbv;
+
+                                       retval = pretty( at->bam_ad->ad_type->sat_syntax,
+                                               &bv, &pbv, bsi->bsi_op->o_tmpmemctx );
+                                       bv = pbv;
+
+                               } else {
+                                       retval = validate( at->bam_ad->ad_type->sat_syntax,
+                                               &bv );
+                               }
+
+                               if ( retval != LDAP_SUCCESS ) {
+                                       char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                       /* FIXME: we're ignoring invalid values,
+                                        * but we're accepting the attributes;
+                                        * should we fail at all? */
+                                       snprintf( buf, sizeof( buf ),
+                                                       "unable to %s value #%d "
+                                                       "of AttributeDescription %s",
+                                                       pretty ? "prettify" : "validate",
+                                                       at->bam_ad->ad_cname.bv_val,
+                                                       k - oldcount );
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               "==>backsql_get_attr_vals(\"%s\"): "
+                                               "%s (%d)\n",
+                                               bsi->bsi_e->e_name.bv_val, buf, retval );
+                                       continue;
+                               }
+#endif /* BACKSQL_PRETTY_VALIDATE */
+
+#ifndef BACKSQL_COUNTQUERY
+                               (void)backsql_entry_addattr( bsi->bsi_e, 
+                                               at->bam_ad, &bv,
+                                               bsi->bsi_op->o_tmpmemctx );
+
+#else /* BACKSQL_COUNTQUERY */
+                               if ( normfunc ) {
+                                       struct berval   nbv;
+
+                                       retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                                               at->bam_ad->ad_type->sat_syntax,
+                                               at->bam_ad->ad_type->sat_equality,
+                                               &bv, &nbv,
                                                bsi->bsi_op->o_tmpmemctx );
 
+                                       if ( retval != LDAP_SUCCESS ) {
+                                               char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                               /* FIXME: we're ignoring invalid values,
+                                                * but we're accepting the attributes;
+                                                * should we fail at all? */
+                                               snprintf( buf, sizeof( buf ),
+                                                       "unable to normalize value #%d "
+                                                       "of AttributeDescription %s",
+                                                       at->bam_ad->ad_cname.bv_val,
+                                                       k - oldcount );
+                                               Debug( LDAP_DEBUG_TRACE,
+                                                       "==>backsql_get_attr_vals(\"%s\"): "
+                                                       "%s (%d)\n",
+                                                       bsi->bsi_e->e_name.bv_val, buf, retval );
+
+#ifdef BACKSQL_PRETTY_VALIDATE
+                                               if ( pretty ) {
+                                                       bsi->bsi_op->o_tmpfree( bv.bv_val,
+                                                                       bsi->bsi_op->o_tmpmemctx );
+                                               }
+#endif /* BACKSQL_PRETTY_VALIDATE */
+
+                                               continue;
+                                       }
+                                       ber_dupbv( &attr->a_nvals[ j ], &nbv );
+                                       bsi->bsi_op->o_tmpfree( nbv.bv_val,
+                                                       bsi->bsi_op->o_tmpmemctx );
+                               }
+
+                               ber_dupbv( &attr->a_vals[ j ], &bv );
+
+                               assert( j < oldcount + count );
+                               j++;
+#endif /* BACKSQL_COUNTQUERY */
+
+#ifdef BACKSQL_PRETTY_VALIDATE
+                               if ( pretty ) {
+                                       bsi->bsi_op->o_tmpfree( bv.bv_val,
+                                                       bsi->bsi_op->o_tmpmemctx );
+                               }
+#endif /* BACKSQL_PRETTY_VALIDATE */
+
 #ifdef BACKSQL_TRACE
                                Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
                                        (int)row.col_prec[ i ], 0, 0 );
+
                        } else {
                                Debug( LDAP_DEBUG_TRACE, "NULL value "
                                        "in this row for attribute \"%s\"\n",
index cf5de2117ffc099d95453b2857f1241f16a3aa23..3ebdfea0a93e67154ca3e73eed0d8e828253482b 100644 (file)
@@ -34,10 +34,10 @@ sql_back_initialize(
        BackendInfo     *bi )
 { 
        static char *controls[] = {
+               LDAP_CONTROL_ASSERT,
+               LDAP_CONTROL_MANAGEDSAIT,
 #if 0 /* needs improvements */
-#ifdef LDAP_CONTROL_NOOP
                LDAP_CONTROL_NOOP,
-#endif /* LDAP_CONTROL_NOOP */
 #endif
 #ifdef LDAP_CONTROL_VALUESRETURNFILTER
                LDAP_CONTROL_VALUESRETURNFILTER,
index 4ec90b2c3addac93d001cfabd450c83b9520dcfb..ac9a197155cc3f25fbcbcd373244654c509b6ce9 100644 (file)
@@ -36,7 +36,9 @@ backsql_modify( Operation *op, SlapReply *rs )
        SQLHDBC                 dbh = SQL_NULL_HDBC;
        backsql_oc_map_rec      *oc = NULL;
        backsql_srch_info       bsi = { 0 };
-       Entry                   e = { 0 };
+       Entry                   m = { 0 }, *e = NULL;
+       int                     manageDSAit = get_manageDSAit( op );
+       SQLUSMALLINT            CompletionType = SQL_ROLLBACK;
 
        /*
         * FIXME: in case part of the operation cannot be performed
@@ -60,19 +62,45 @@ backsql_modify( Operation *op, SlapReply *rs )
                goto done;
        }
 
-       bsi.bsi_e = &e;
+       bsi.bsi_e = &m;
        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_ENTRY );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
+                       ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
+       switch ( rs->sr_err ) {
+       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 = &m;
+               /* fallthru */
+
+       default:
                Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
                        "could not retrieve modifyDN ID - no such entry\n", 
                        0, 0, 0 );
-               /* FIXME: we keep the error code
-                * set by backsql_init_search() */
+               if ( !BER_BVISNULL( &m.e_nname ) ) {
+                       /* FIXME: should always be true! */
+                       e = &m;
+
+               } else {
+                       e = NULL;
+               }
                goto done;
        }
 
@@ -87,6 +115,15 @@ backsql_modify( Operation *op, SlapReply *rs )
                bsi.bsi_base_id.eid_dn.bv_val, bsi.bsi_base_id.eid_id, 0 );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 
+       if ( get_assert( op ) &&
+                       ( test_filter( op, &m, get_assertion( op ) )
+                         != LDAP_COMPARE_TRUE ))
+       {
+               rs->sr_err = LDAP_ASSERTION_FAILED;
+               e = &m;
+               goto done;
+       }
+
        oc = backsql_id2oc( bi, bsi.bsi_base_id.eid_oc_id );
        if ( oc == NULL ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
@@ -102,28 +139,47 @@ backsql_modify( Operation *op, SlapReply *rs )
                 */
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
+               e = NULL;
                goto done;
        }
 
        /* FIXME: need the whole entry (ITS#3480) */
-       if ( !acl_check_modlist( op, &e, op->oq_modify.rs_modlist ) ) {
+       if ( !acl_check_modlist( op, &m, op->oq_modify.rs_modlist ) ) {
                rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-
-       } else {
-               rs->sr_err = backsql_modify_internal( op, rs, dbh, oc,
-                               &bsi.bsi_base_id,
-                               op->oq_modify.rs_modlist );
+               e = &m;
+               goto done;
        }
 
-       if ( rs->sr_err == LDAP_SUCCESS ) {
-               /*
-                * Commit only if all operations succeed
-                */
-               SQLTransact( SQL_NULL_HENV, dbh, 
-                               op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
+       rs->sr_err = backsql_modify_internal( op, rs, dbh, oc,
+                       &bsi.bsi_base_id,
+                       op->oq_modify.rs_modlist );
+
+       /*
+        * Commit only if all operations succeed
+        */
+       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+               CompletionType = SQL_COMMIT;
        }
 
+       SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
+
 done:;
+#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 );
 
        (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
@@ -138,6 +194,6 @@ done:;
 
        Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
 
-       return rs->sr_err != LDAP_SUCCESS ? rs->sr_err : op->o_noop;
+       return rs->sr_err;
 }
 
index 046a726b120eba88a65bb798f27977d1294f3e84..a722e9f39882326423bc703617c188de3c1cadc5 100644 (file)
@@ -37,16 +37,20 @@ backsql_modrdn( Operation *op, SlapReply *rs )
        SQLHSTMT                sth = SQL_NULL_HSTMT;
        RETCODE                 rc;
        backsql_entryID         e_id = BACKSQL_ENTRYID_INIT,
-                               pe_id = BACKSQL_ENTRYID_INIT,
-                               new_pe_id = BACKSQL_ENTRYID_INIT;
+                               n_id = BACKSQL_ENTRYID_INIT;
+       backsql_srch_info       bsi = { 0 };
        backsql_oc_map_rec      *oc = NULL;
-       struct berval           p_dn = BER_BVNULL, p_ndn = BER_BVNULL,
+       struct berval           pdn = BER_BVNULL, pndn = BER_BVNULL,
                                *new_pdn = NULL, *new_npdn = NULL,
                                new_dn = BER_BVNULL, new_ndn = BER_BVNULL,
                                realnew_dn = BER_BVNULL;
        LDAPRDN                 new_rdn = NULL;
        LDAPRDN                 old_rdn = NULL;
-       Entry                   e = { 0 };
+       Entry                   r = { 0 },
+                               p = { 0 },
+                               n = { 0 },
+                               *e = NULL;
+       int                     manageDSAit = get_manageDSAit( op );
        Modifications           *mod = NULL;
        struct berval           *newSuperior = op->oq_modrdn.rs_newSup;
        char                    *next;
@@ -55,6 +59,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                        "newrdn=\"%s\", newSuperior=\"%s\"\n",
                        op->o_req_dn.bv_val, op->oq_modrdn.rs_newrdn.bv_val, 
                        newSuperior ? newSuperior->bv_val : "(NULL)" );
+
        rs->sr_err = backsql_get_db_conn( op, &dbh );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
@@ -62,19 +67,50 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                        0, 0, 0 );
                rs->sr_text = ( rs->sr_err == LDAP_OTHER )
                        ?  "SQL-backend error" : NULL;
-               send_ldap_result( op, rs );
-               return 1;
+               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 ) {
-               Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
-                       "could not lookup entry id (%d)\n",
-                       rs->sr_err, 0, 0 );
-               rs->sr_text = ( rs->sr_err == LDAP_OTHER )
-                       ?  "SQL-backend error" : NULL;
-               send_ldap_result( op, rs );
-               return 1;
+       bsi.bsi_e = &r;
+       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_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
+       switch ( rs->sr_err ) {
+       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 = &r;
+               /* fallthru */
+
+       default:
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "could not retrieve modrdnDN ID - no such entry\n", 
+                       0, 0, 0 );
+               if ( !BER_BVISNULL( &r.e_nname ) ) {
+                       /* FIXME: should always be true! */
+                       e = &r;
+
+               } else {
+                       e = NULL;
+               }
+               goto done;
        }
 
 #ifdef BACKSQL_ARBITRARY_KEY
@@ -85,58 +121,90 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                e_id.eid_id, 0, 0 );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 
+       if ( get_assert( op ) &&
+                       ( test_filter( op, &r, get_assertion( op ) )
+                         != LDAP_COMPARE_TRUE ) )
+       {
+               rs->sr_err = LDAP_ASSERTION_FAILED;
+               e = &r;
+               goto done;
+       }
+
        if ( backsql_has_children( bi, dbh, &op->o_req_ndn ) == LDAP_COMPARE_TRUE ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
                        "entry \"%s\" has children\n",
                        op->o_req_dn.bv_val, 0, 0 );
                rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
                rs->sr_text = "subtree rename not supported";
-               send_ldap_result( op, rs );
-               return 1;
+               e = &r;
+               goto done;
        }
 
        /*
         * 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, 
+       if ( !access_allowed( op, &r, 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;
+               goto done;
        }
 
-       dnParent( &op->o_req_dn, &p_dn );
-       dnParent( &op->o_req_ndn, &p_ndn );
+       dnParent( &op->o_req_dn, &pdn );
+       dnParent( &op->o_req_ndn, &pndn );
 
        /*
         * namingContext "" is not supported
         */
-       if ( BER_BVISEMPTY( &p_dn ) ) {
+       if ( BER_BVISEMPTY( &pdn ) ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
                        "parent is \"\" - aborting\n", 0, 0, 0 );
                rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                rs->sr_text = "not allowed within namingContext";
-               send_ldap_result( op, rs );
-               goto modrdn_return;
+               e = NULL;
+               goto done;
        }
 
        /*
         * Check for children access to parent
         */
-       e.e_name = p_dn;
-       e.e_nname = p_ndn;
-       /* FIXME: need the whole entry (ITS#3480) */
-       if ( !access_allowed( op, &e, slap_schema.si_ad_children, 
+       bsi.bsi_e = &p;
+       e_id = bsi.bsi_base_id;
+       rs->sr_err = backsql_init_search( &bsi, &pndn,
+                       LDAP_SCOPE_BASE, 
+                       SLAP_NO_LIMIT, SLAP_NO_LIMIT,
+                       (time_t)(-1), NULL, dbh, op, rs,
+                       slap_anlist_all_attributes,
+                       BACKSQL_ISF_GET_ENTRY );
+
+#ifdef BACKSQL_ARBITRARY_KEY
+       Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
+               "old parent entry id is %s\n",
+               bsi.bsi_base_id.eid_id.bv_val, 0, 0 );
+#else /* ! BACKSQL_ARBITRARY_KEY */
+       Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
+               "old parent entry id is %ld\n",
+               bsi.bsi_base_id.eid_id, 0, 0 );
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "could not retrieve renameDN ID - no such entry\n", 
+                       0, 0, 0 );
+               e = &p;
+               goto done;
+       }
+
+       if ( !access_allowed( op, &p, slap_schema.si_ad_children, 
                                NULL, ACL_WRITE, NULL ) ) {
                Debug( LDAP_DEBUG_TRACE, "   no access to parent\n", 0, 0, 0 );
                rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               goto modrdn_return;
+               goto done;
        }
 
        if ( newSuperior ) {
+               (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+               
                /*
                 * namingContext "" is not supported
                 */
@@ -145,8 +213,8 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                                "newSuperior is \"\" - aborting\n", 0, 0, 0 );
                        rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                        rs->sr_text = "not allowed within namingContext";
-                       send_ldap_result( op, rs );
-                       goto modrdn_return;
+                       e = NULL;
+                       goto done;
                }
 
                new_pdn = newSuperior;
@@ -155,24 +223,50 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                /*
                 * 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, 
+               bsi.bsi_e = &n;
+               rs->sr_err = backsql_init_search( &bsi, new_npdn,
+                               LDAP_SCOPE_BASE, 
+                               SLAP_NO_LIMIT, SLAP_NO_LIMIT,
+                               (time_t)(-1), NULL, dbh, op, rs,
+                               slap_anlist_all_attributes,
+                               ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
+               if ( rs->sr_err != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                               "could not retrieve renameDN ID - no such entry\n", 
+                               0, 0, 0 );
+                       e = &n;
+                       goto done;
+               }
+
+               n_id = bsi.bsi_base_id;
+
+#ifdef BACKSQL_ARBITRARY_KEY
+               Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
+                       "new parent entry id=%s\n",
+                       n_id.eid_id.bv_val, 0, 0 );
+#else /* ! BACKSQL_ARBITRARY_KEY */
+               Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
+                       "new parent entry id=%ld\n",
+                       n_id.eid_id, 0, 0 );
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+
+               if ( !access_allowed( op, &n, slap_schema.si_ad_children, 
                                        NULL, ACL_WRITE, NULL ) ) {
                        Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
                                        "no access to new parent \"%s\"\n", 
                                        new_pdn->bv_val, 0, 0 );
                        rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                       goto modrdn_return;
+                       e = &n;
+                       goto done;
                }
 
        } else {
-               new_pdn = &p_dn;
-               new_npdn = &p_ndn;
+               n_id = bsi.bsi_base_id;
+               new_pdn = &pdn;
+               new_npdn = &pndn;
        }
 
-       if ( newSuperior && dn_match( &p_ndn, new_npdn ) ) {
+       if ( newSuperior && dn_match( &pndn, new_npdn ) ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
                        "newSuperior is equal to old parent - ignored\n",
                        0, 0, 0 );
@@ -185,64 +279,18 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                        "- aborting\n", 0, 0, 0 );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "newSuperior is equal to old DN";
-               send_ldap_result( op, rs );
-               goto modrdn_return;
+               e = &r;
+               goto done;
        }
 
        build_new_dn( &new_dn, new_pdn, &op->oq_modrdn.rs_newrdn,
                        op->o_tmpmemctx );
-       rs->sr_err = dnNormalize( 0, NULL, NULL, &new_dn, &new_ndn,
+       build_new_dn( &new_ndn, new_npdn, &op->oq_modrdn.rs_nnewrdn,
                        op->o_tmpmemctx );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
-                       "new dn is invalid (\"%s\") - aborting\n",
-                       new_dn.bv_val, 0, 0 );
-               rs->sr_text = "unable to build new DN";
-               send_ldap_result( op, rs );
-               goto modrdn_return;
-       }
        
        Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): new entry dn is \"%s\"\n",
                        new_dn.bv_val, 0, 0 );
 
-       rs->sr_err = backsql_dn2id( op, rs, dbh, &p_ndn, &pe_id, 0, 1 );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
-                       "could not lookup old parent entry id\n", 0, 0, 0 );
-               rs->sr_text = ( rs->sr_err == LDAP_OTHER )
-                       ? "SQL-backend error" : NULL;
-               send_ldap_result( op, rs );
-               goto modrdn_return;
-       }
-
-#ifdef BACKSQL_ARBITRARY_KEY
-       Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
-               "old parent entry id is %s\n", pe_id.eid_id.bv_val, 0, 0 );
-#else /* ! BACKSQL_ARBITRARY_KEY */
-       Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
-               "old parent entry id is %ld\n", pe_id.eid_id, 0, 0 );
-#endif /* ! BACKSQL_ARBITRARY_KEY */
-
-       (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 ) {
-               Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
-                       "could not lookup new parent entry id\n", 0, 0, 0 );
-               rs->sr_text = ( rs->sr_err == LDAP_OTHER )
-                       ? "SQL-backend error" : NULL;
-               send_ldap_result( op, rs );
-               goto modrdn_return;
-       }
-
-#ifdef BACKSQL_ARBITRARY_KEY
-       Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
-               "new parent entry id=%s\n", new_pe_id.eid_id.bv_val, 0, 0 );
-#else /* ! BACKSQL_ARBITRARY_KEY */
-       Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
-               "new parent entry id=%ld\n", new_pe_id.eid_id, 0, 0 );
-#endif /* ! BACKSQL_ARBITRARY_KEY */
-
  
        Debug(  LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
                "executing delentry_stmt\n", 0, 0, 0 );
@@ -257,6 +305,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -267,12 +316,12 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                        "error binding entry ID parameter "
                        "for objectClass %s\n",
                        oc->bom_oc->soc_cname.bv_val, 0, 0 );
-               backsql_PrintErrors( bi->sql_db_env, dbh, 
-                       sth, rc );
+               backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -285,7 +334,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                SQLFreeStmt( sth, SQL_DROP );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
-               send_ldap_result( op, rs );
+               e = NULL;
                goto done;
        }
 
@@ -304,6 +353,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -316,6 +366,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -331,6 +382,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -346,10 +398,11 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
-       rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &new_pe_id.eid_id );
+       rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &n_id.eid_id );
        if ( rc != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE,
                        "   backsql_add_attr(): "
@@ -361,6 +414,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -376,6 +430,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
                rs->sr_text = "SQL-backend error";
                rs->sr_err = LDAP_OTHER;
+               e = NULL;
                goto done;
        }
 
@@ -387,7 +442,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                SQLFreeStmt( sth, SQL_DROP );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
-               send_ldap_result( op, rs );
+               e = NULL;
                goto done;
        }
        SQLFreeStmt( sth, SQL_DROP );
@@ -401,15 +456,15 @@ backsql_modrdn( Operation *op, SlapReply *rs )
        {
                Debug( LDAP_DEBUG_TRACE,
                        "   backsql_modrdn: can't figure out "
-                       "type(s)/values(s) of newrdn\n", 
+                       "type(s)/values(s) of new_rdn\n", 
                        0, 0, 0 );
                rs->sr_err = LDAP_INVALID_DN_SYNTAX;
+               e = &r;
                goto done;
        }
 
-       Debug( LDAP_DEBUG_TRACE,
-               "   backsql_modrdn: new_rdn_type=\"%s\", "
-               "new_rdn_val=\"%s\"\n",
+       Debug( LDAP_DEBUG_TRACE, "backsql_modrdn: "
+               "new_rdn_type=\"%s\", new_rdn_val=\"%s\"\n",
                new_rdn[ 0 ]->la_attr.bv_val,
                new_rdn[ 0 ]->la_value.bv_val, 0 );
 
@@ -422,38 +477,53 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                                "the old_rdn type(s)/value(s)\n", 
                                0, 0, 0 );
                        rs->sr_err = LDAP_OTHER;
-                       goto done;              
+                       e = NULL;
+                       goto done;
                }
        }
 
-       e.e_name = new_dn;
-       e.e_nname = new_ndn;
-       rs->sr_err = slap_modrdn2mods( op, rs, &e, old_rdn, new_rdn, &mod );
+       rs->sr_err = slap_modrdn2mods( op, rs, &r, old_rdn, new_rdn, &mod );
        if ( rs->sr_err != LDAP_SUCCESS ) {
-               goto modrdn_return;
-       }
-
-       /* FIXME: need the whole entry (ITS#3480) */
-       if ( !acl_check_modlist( op, &e, mod )) {
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               goto modrdn_return;
+               e = &r;
+               goto done;
        }
 
        oc = backsql_id2oc( bi, e_id.eid_oc_id );
        rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, mod );
+       e = &r;
 
 done:;
+#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 );
+
        /*
         * Commit only if all operations succeed
         */
-       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
-               SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
+       if ( sth != SQL_NULL_HSTMT ) {
+               SQLUSMALLINT    CompletionType = SQL_ROLLBACK;
+       
+               if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+                       CompletionType = SQL_COMMIT;
+               }
 
-       } else {
-               SQLTransact( SQL_NULL_HENV, dbh, SQL_ROLLBACK );
+               SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
        }
 
-modrdn_return:;
        if ( !BER_BVISNULL( &realnew_dn ) && realnew_dn.bv_val != new_dn.bv_val ) {
                ch_free( realnew_dn.bv_val );
        }
@@ -481,11 +551,28 @@ modrdn_return:;
                }
        }
 
-       (void)backsql_free_entryID( op, &new_pe_id, 0 );
+       if ( !BER_BVISNULL( &e_id.eid_ndn ) ) {
+               (void)backsql_free_entryID( op, &e_id, 0 );
+       }
+
+       if ( !BER_BVISNULL( &n_id.eid_ndn ) ) {
+               (void)backsql_free_entryID( op, &n_id, 0 );
+       }
 
-       send_ldap_result( op, rs );
+       if ( !BER_BVISNULL( &r.e_nname ) ) {
+               entry_clean( &r );
+       }
+
+       if ( !BER_BVISNULL( &p.e_nname ) ) {
+               entry_clean( &p );
+       }
+
+       if ( !BER_BVISNULL( &n.e_nname ) ) {
+               entry_clean( &n );
+       }
 
        Debug( LDAP_DEBUG_TRACE, "<==backsql_modrdn()\n", 0, 0, 0 );
-       return op->o_noop;
+
+       return rs->sr_err;
 }
 
index 86657d5b4fa74a86ae51dff43dd0e02987d2bbcc..e3cd9b82ffced972dd2d6e1431ba99c60a556e22 100644 (file)
@@ -237,7 +237,7 @@ extern char
 struct berbuf * backsql_strcat( struct berbuf *dest, ... );
 struct berbuf * backsql_strfcat( struct berbuf *dest, const char *fmt, ... );
 
-int backsql_entry_addattr( Entry *e, struct berval *at_name
+int backsql_entry_addattr( Entry *e, AttributeDescription *ad
                struct berval *at_val, void *memctx );
 
 int backsql_merge_from_clause( struct berbuf *dest_from, 
index 2dbd05915e4e3fe6e62b5e7efdf94b9ea72a08ab..618daf5d33cf630ff434a89741e36a6cf2b7d845 100644 (file)
@@ -154,7 +154,30 @@ backsql_make_attr_query(
 #endif /* ! BACKSQL_ALIASING_QUOTE */
 
        at_map->bam_query = bb.bb_val.bv_val;
-       
+
+#ifdef BACKSQL_COUNTQUERY
+       /* Query to count how many rows will be returned. */
+       BER_BVZERO( &bb.bb_val );
+       bb.bb_len = 0;
+       backsql_strfcat( &bb, "lblbcbl", 
+                       (ber_len_t)STRLENOF( "SELECT COUNT(*) FROM " ),
+                               "SELECT COUNT(*) FROM ", 
+                       &at_map->bam_from_tbls, 
+                       (ber_len_t)STRLENOF( " WHERE " ), " WHERE ", 
+                       &oc_map->bom_keytbl,
+                       '.', 
+                       &oc_map->bom_keycol,
+                       (ber_len_t)STRLENOF( "=?" ), "=?" );
+
+       if ( !BER_BVISNULL( &at_map->bam_join_where ) ) {
+               backsql_strfcat( &bb, "lb",
+                               (ber_len_t)STRLENOF( " AND " ), " AND ", 
+                               &at_map->bam_join_where );
+       }
+
+       at_map->bam_countquery = bb.bb_val.bv_val;
+#endif /* BACKSQL_COUNTQUERY */
+
        return 0;
 }
 
@@ -826,7 +849,7 @@ supad2at_f( void *v_at, void *v_arg )
        struct supad2at_t       *va = (struct supad2at_t *)v_arg;
 
        if ( is_at_subtype( at->bam_ad->ad_type, va->ad->ad_type ) ) {
-               backsql_at_map_rec      **ret;
+               backsql_at_map_rec      **ret = NULL;
                unsigned                i;
 
                /* if already listed, holler! (should never happen) */
@@ -843,9 +866,11 @@ supad2at_f( void *v_at, void *v_arg )
                }
 
                ret = ch_realloc( va->ret,
-                               sizeof( backsql_at_map_rec *) * ( va->n + 2 ) );
+                               sizeof( backsql_at_map_rec * ) * ( va->n + 2 ) );
                if ( ret == NULL ) {
                        ch_free( va->ret );
+                       va->ret = NULL;
+                       va->n = 0;
                        return SUPAD2AT_STOP;
                }
 
@@ -867,7 +892,7 @@ int
 backsql_supad2at( backsql_oc_map_rec *objclass, AttributeDescription *supad,
                backsql_at_map_rec ***pret )
 {
-       struct supad2at_t       va;
+       struct supad2at_t       va = { 0 };
        int                     rc;
 
        assert( objclass );
@@ -876,9 +901,7 @@ backsql_supad2at( backsql_oc_map_rec *objclass, AttributeDescription *supad,
 
        *pret = NULL;
 
-       va.ret = NULL;
        va.ad = supad;
-       va.n = 0;
 
        rc = avl_apply( objclass->bom_attrs, supad2at_f, &va,
                        SUPAD2AT_STOP, AVL_INORDER );
index e501d1b3bc22d8605e5755ffde4b8e75ecc0f8bc..d6524d160900041fe70cfebffcf9ae5f67b20588 100644 (file)
@@ -271,40 +271,50 @@ backsql_init_search(
        if ( BACKSQL_IS_GET_ID( flags ) ) {
                int     matched = BACKSQL_IS_MATCHED( flags );
                int     getentry = BACKSQL_IS_GET_ENTRY( flags );
+               int     gotit = 0;
 
                assert( op->o_bd->be_private );
 
                rc = backsql_dn2id( op, rs, dbh, nbase, &bsi->bsi_base_id,
                                matched, 1 );
-               
+
+               /* the entry is collected either if requested for by getentry
+                * or if get noSuchObject and requested to climb the tree,
+                * so that a matchedDN or a referral can be returned */
                if ( ( rc == LDAP_NO_SUCH_OBJECT && matched ) || getentry ) {
                        if ( !BER_BVISNULL( &bsi->bsi_base_id.eid_ndn ) ) {
                                assert( bsi->bsi_e != NULL );
-
+                               
+                               if ( dn_match( nbase, &bsi->bsi_base_id.eid_ndn ) )
+                               {
+                                       gotit = 1;
+                               }
+                       
                                /*
                                 * 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 );
+                               if ( rc == LDAP_SUCCESS ) {
+                                       if ( 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 = LDAP_OTHER;
-                                               rs->sr_text = "bad referral object";
+                                       } else if ( !gotit ) {
+                                               rc = rs->sr_err = LDAP_NO_SUCH_OBJECT;
                                        }
-
-                               } else {
-                                       rc = rs->sr_err = getentry ?
-                                               LDAP_SUCCESS : LDAP_NO_SUCH_OBJECT;
                                }
 
                        } else {
@@ -1868,18 +1878,27 @@ backsql_search( Operation *op, SlapReply *rs )
         * on searchBase object */
        else {
                slap_mask_t     mask;
-
-               /* FIXME: need the whole entry (ITS#3480) */
+               
+               if ( get_assert( op ) &&
+                               ( test_filter( op, &base_entry, get_assertion( op ) )
+                                 != LDAP_COMPARE_TRUE ) )
+               {
+                       rs->sr_err = LDAP_ASSERTION_FAILED;
+                       
+               }
                if ( ! access_allowed_mask( op, &base_entry,
                                        slap_schema.si_ad_entry,
                                        NULL, ACL_SEARCH, NULL, &mask ) )
                {
+                       if ( rs->sr_err == LDAP_SUCCESS ) {
+                               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+                       }
+               }
+
+               if ( rs->sr_err != LDAP_SUCCESS ) {
                        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;
index cf2d222ce4266b04fbd994ab98980a86fc393d52..337b6bf975d8a85771b84bc1a6c7bb9a2ef6a409 100644 (file)
@@ -245,44 +245,33 @@ backsql_strfcat( struct berbuf *dest, const char *fmt, ... )
 
 int
 backsql_entry_addattr(
-       Entry           *e,
-       struct berval   *at_name,
-       struct berval   *at_val,
-       void            *memctx )
+       Entry                   *e,
+       AttributeDescription    *ad,
+       struct berval           *val,
+       void                    *memctx )
 {
-       AttributeDescription    *ad;
        int                     rc;
-       const char              *text;
 
 #ifdef BACKSQL_TRACE
-       Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
-               "at_name=\"%s\", at_val=\"%s\"\n", 
-               at_name->bv_val, at_val->bv_val, 0 );
+       Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(\"%s\"): %s=%s\n", 
+               e->e_name.bv_val, ad->ad_cname->bv_val, val->bv_val );
 #endif /* BACKSQL_TRACE */
 
-       ad = NULL;
-       rc = slap_bv2ad( at_name, &ad, &text );
-       if ( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
-                       "failed to find AttributeDescription for \"%s\"\n",
-                       at_name->bv_val, 0, 0 );
-               return 0;
-       }
-
-       rc = attr_merge_normalize_one( e, ad, at_val, memctx );
+       rc = attr_merge_normalize_one( e, ad, val, memctx );
 
-       if ( rc != 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(\"%s\"): "
                        "failed to merge value \"%s\" for attribute \"%s\"\n",
-                       at_val->bv_val, at_name->bv_val, 0 );
-               return 0;
+                       e->e_name.bv_val, val->bv_val, ad->ad_cname.bv_val );
+               return rc;
        }
 
 #ifdef BACKSQL_TRACE
-       Debug( LDAP_DEBUG_TRACE, "<==backsql_query_addattr()\n", 0, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_entry_addattr(\"%s\")\n",
+               e->e_name.bv_val, 0, 0 );
 #endif /* BACKSQL_TRACE */
 
-       return 1;
+       return LDAP_SUCCESS;
 }
 
 static char *