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
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;
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 ) )
* 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";
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 );
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",
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;
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";
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";
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 );
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 );
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 );
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 );
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 ) {
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 );
}
/*
{
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 );
* 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:
*/
#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
*
/* 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;
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 };
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 );
* 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;
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;
}
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 );
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,
}
}
}
-
#endif /* SLAP_ACL_HONOR_DISCLOSE */
send_ldap_result( op, rs );
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 );
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;
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 */
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 );
}
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",
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,
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
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;
}
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(): "
*/
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 );
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;
}
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;
"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(): "
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
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
*/
"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;
/*
* 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 );
"- 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 );
rs->sr_text = "SQL-backend error";
rs->sr_err = LDAP_OTHER;
+ e = NULL;
goto done;
}
"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;
}
SQLFreeStmt( sth, SQL_DROP );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "SQL-backend error";
- send_ldap_result( op, rs );
+ e = NULL;
goto done;
}
rs->sr_text = "SQL-backend error";
rs->sr_err = LDAP_OTHER;
+ e = NULL;
goto done;
}
rs->sr_text = "SQL-backend error";
rs->sr_err = LDAP_OTHER;
+ e = NULL;
goto done;
}
rs->sr_text = "SQL-backend error";
rs->sr_err = LDAP_OTHER;
+ e = NULL;
goto done;
}
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(): "
rs->sr_text = "SQL-backend error";
rs->sr_err = LDAP_OTHER;
+ e = NULL;
goto done;
}
rs->sr_text = "SQL-backend error";
rs->sr_err = LDAP_OTHER;
+ e = NULL;
goto done;
}
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 );
{
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 );
"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 );
}
}
}
- (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;
}
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,
#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;
}
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) */
}
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;
}
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 );
*pret = NULL;
- va.ret = NULL;
va.ad = supad;
- va.n = 0;
rc = avl_apply( objclass->bom_attrs, supad2at_f, &va,
SUPAD2AT_STOP, AVL_INORDER );
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 {
* 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;
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 *