fixes for ITS#3480,3485,3489; implementation of DISCLOSE access for all operations (ITS#3472); ITS#3432.4; added value validate/pretty when applicable (see comments and #defines in back-sql.h)

This commit is contained in:
Pierangelo Masarati 2005-01-16 23:12:36 +00:00
parent 56e45fc1ae
commit b4e37e518f
13 changed files with 787 additions and 280 deletions

View 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

View 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 );

View File

@ -76,13 +76,16 @@
* 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;

View 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 };

View 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;
}
SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
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 );
}
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 );

View 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;
bv.bv_val = row.cols[ i ];
#if 0
bv.bv_len = row.col_prec[ i ];
#else
if ( row.value_len[ i ] > 0 ) {
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 */
/*
* 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",

View 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,

View 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;
}

View 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 );
}
send_ldap_result( op, rs );
if ( !BER_BVISNULL( &n_id.eid_ndn ) ) {
(void)backsql_free_entryID( op, &n_id, 0 );
}
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;
}

View 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,

View 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 );

View 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;

View 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 );
rc = attr_merge_normalize_one( e, ad, val, memctx );
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 );
if ( rc != 0 ) {
Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
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 *