fix, rework and optimize search base; allow orphaned entries addition

This commit is contained in:
Pierangelo Masarati 2004-09-28 23:27:39 +00:00
parent 7ccd03da88
commit 60d4aaba54
8 changed files with 115 additions and 63 deletions

View file

@ -1016,7 +1016,8 @@ backsql_add( Operation *op, SlapReply *rs )
* if not attempting to add entry at suffix or with parent ""
*/
if ( ( ( !be_isroot( op ) && !be_shadow_update( op ) )
|| !BER_BVISEMPTY( &pdn ) ) && !is_entry_glue( op->oq_add.rs_e ) )
|| !BER_BVISEMPTY( &pdn ) ) && !is_entry_glue( op->oq_add.rs_e )
&& !BACKSQL_ALLOW_ORPHANS( bi ) )
{
Debug( LDAP_DEBUG_TRACE, " backsql_add: %s denied\n",
BER_BVISEMPTY( &pdn ) ? "suffix" : "entry at root",
@ -1391,7 +1392,7 @@ done:;
ch_free( realpdn.bv_val );
}
if ( !BER_BVISNULL( &parent_id.eid_dn ) ) {
backsql_free_entryID( &parent_id, 0 );
(void)backsql_free_entryID( &parent_id, 0 );
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_add(\"%s\"): %d \"%s\"\n",

View file

@ -92,6 +92,7 @@
* define to enable very extensive trace logging (debug only)
*/
#undef BACKSQL_TRACE
#define BACKSQL_TRACE
/*
* define to enable varchars as unique keys in user tables
@ -254,6 +255,7 @@ typedef struct backsql_srch_info {
#define BSQL_SF_FILTER_HASSUBORDINATE 0x0002
struct berval *bsi_base_dn;
backsql_entryID bsi_base_id;
int bsi_scope;
#define BACKSQL_SCOPE_BASE_LIKE ( LDAP_SCOPE_BASE | 0x1000 )
Filter *bsi_filter;
@ -320,6 +322,7 @@ typedef struct {
#define BSQLF_HAS_LDAPINFO_DN_RU 0x0010
#define BSQLF_DONTCHECK_LDAPINFO_DN_RU 0x0020
#define BSQLF_USE_REVERSE_DN 0x0040
#define BSQLF_ALLOW_ORPHANS 0x0080
#define BACKSQL_SCHEMA_LOADED(si) \
((si)->bsql_flags & BSQLF_SCHEMA_LOADED)
@ -337,6 +340,8 @@ typedef struct {
((si)->bsql_flags & BSQLF_USE_REVERSE_DN)
#define BACKSQL_CANUPPERCASE(si) \
((si)->upper_func.bv_val)
#define BACKSQL_ALLOW_ORPHANS(si) \
((si)->bsql_flags & BSQLF_ALLOW_ORPHANS)
struct berval strcast_func;
Avlnode *db_conns;

View file

@ -31,8 +31,6 @@
int
backsql_bind( Operation *op, SlapReply *rs )
{
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
backsql_entryID user_id = BACKSQL_ENTRYID_INIT;
SQLHDBC dbh;
AttributeDescription *password = slap_schema.si_ad_userPassword;
Entry *e, user_entry;
@ -85,7 +83,12 @@ backsql_bind( Operation *op, SlapReply *rs )
goto error_return;
}
rc = backsql_dn2id( bi, &user_id, dbh, &dn );
anlist[0].an_name = password->ad_cname;
anlist[0].an_desc = password;
anlist[1].an_name.bv_val = NULL;
rc = backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, anlist, 1 );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"could not retrieve bind dn id - no such entry\n",
@ -95,14 +98,8 @@ backsql_bind( Operation *op, SlapReply *rs )
return 1;
}
anlist[0].an_name = password->ad_cname;
anlist[0].an_desc = password;
anlist[1].an_name.bv_val = NULL;
backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, anlist );
bsi.bsi_e = &user_entry;
rc = backsql_id2entry( &bsi, &user_id );
rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"error %d in backsql_id2entry() "
@ -137,6 +134,10 @@ backsql_bind( Operation *op, SlapReply *rs )
}
error_return:;
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
(void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
}
if ( rs->sr_err ) {
send_ldap_result( op, rs );
return 1;

View file

@ -31,8 +31,6 @@
int
backsql_compare( Operation *op, SlapReply *rs )
{
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
backsql_entryID user_id = BACKSQL_ENTRYID_INIT;
SQLHDBC dbh;
Entry *e = NULL, user_entry;
Attribute *a = NULL;
@ -70,15 +68,6 @@ backsql_compare( Operation *op, SlapReply *rs )
goto return_results;
}
rc = backsql_dn2id( bi, &user_id, dbh, &dn );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
"could not retrieve compare dn id - no such entry\n",
0, 0, 0 );
rs->sr_err = LDAP_NO_SUCH_OBJECT;
goto return_results;
}
memset( &anlist[0], 0, 2 * sizeof( AttributeName ) );
anlist[0].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
anlist[0].an_desc = op->oq_compare.rs_ava->aa_desc;
@ -106,10 +95,18 @@ backsql_compare( Operation *op, SlapReply *rs )
user_entry.e_attrs = nrs.sr_operational_attrs;
} else {
backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, anlist );
rc = backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, anlist, 1 );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
"could not retrieve compare dn id - no such entry\n",
0, 0, 0 );
rs->sr_err = LDAP_NO_SUCH_OBJECT;
goto return_results;
}
bsi.bsi_e = &user_entry;
rc = backsql_id2entry( &bsi, &user_id );
rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
"error %d in backsql_id2entry() "
@ -148,6 +145,10 @@ backsql_compare( Operation *op, SlapReply *rs )
return_results:;
send_ldap_result( op, rs );
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
(void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
}
if ( dn.bv_val != op->o_req_dn.bv_val ) {
ch_free( dn.bv_val );
}

View file

@ -360,6 +360,35 @@ backsql_db_config(
"fail_if_no_mapping=%s\n",
BACKSQL_FAIL_IF_NO_MAPPING( si ) ? "yes" : "no", 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "allow_orphans") ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing { yes | no }"
"in \"allow_orphans\" directive\n",
fname, lineno, 0 );
return 1;
}
if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
si->bsql_flags |= BSQLF_ALLOW_ORPHANS;
} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
si->bsql_flags &= ~BSQLF_ALLOW_ORPHANS;
} else {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"\"allow_orphans\" directive arg "
"must be \"yes\" or \"no\"\n",
fname, lineno, 0 );
return 1;
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"allow_orphans=%s\n",
BACKSQL_ALLOW_ORPHANS( si ) ? "yes" : "no", 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "sqllayer") ) {
if ( backsql_api_config( si, argv[ 1 ] ) ) {
Debug( LDAP_DEBUG_TRACE,

View file

@ -209,7 +209,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
"old parent entry id is %ld\n", pe_id.eid_id, 0, 0 );
#endif /* ! BACKSQL_ARBITRARY_KEY */
backsql_free_entryID( &pe_id, 0 );
(void)backsql_free_entryID( &pe_id, 0 );
rs->sr_err = backsql_dn2id( bi, &new_pe_id, dbh, new_npdn );
if ( rs->sr_err != LDAP_SUCCESS ) {
@ -451,7 +451,7 @@ modrdn_return:;
}
if ( new_pe_id.eid_dn.bv_val ) {
backsql_free_entryID( &new_pe_id, 0 );
(void)backsql_free_entryID( &new_pe_id, 0 );
}
send_ldap_result( op, rs );

View file

@ -149,10 +149,11 @@ int backsql_destroy_schema_map( backsql_info *si );
* search.c
*/
void backsql_init_search( backsql_srch_info *bsi,
int backsql_init_search( backsql_srch_info *bsi,
struct berval *nbase, int scope, int slimit, int tlimit,
time_t stoptime, Filter *filter, SQLHDBC dbh,
Operation *op, SlapReply *rs, AttributeName *attrs );
Operation *op, SlapReply *rs, AttributeName *attrs,
int get_base_id );
/*
* sql-wrap.h

View file

@ -92,7 +92,14 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
return 1;
}
void
/*
* Initializes the search structure.
*
* If get_base_id != 0, the field bsi_base_id is filled
* with the entryID of bsi_base_dn; it must be freed
* by backsql_free_entryID() when no longer required.
*/
int
backsql_init_search(
backsql_srch_info *bsi,
struct berval *base,
@ -104,11 +111,14 @@ backsql_init_search(
SQLHDBC dbh,
Operation *op,
SlapReply *rs,
AttributeName *attrs )
AttributeName *attrs,
int get_base_id )
{
AttributeName *p;
int rc = LDAP_SUCCESS;
bsi->bsi_base_dn = base;
BER_BVZERO( &bsi->bsi_base_id.eid_dn );
bsi->bsi_scope = scope;
bsi->bsi_slimit = slimit;
bsi->bsi_tlimit = tlimit;
@ -125,7 +135,7 @@ backsql_init_search(
bsi->bsi_attrs = NULL;
} else {
int is_oc = 0;
int got_oc = 0;
bsi->bsi_attrs = (AttributeName *)ch_calloc( 1,
sizeof( AttributeName ) );
@ -143,13 +153,13 @@ backsql_init_search(
continue;
} else if ( p->an_desc == slap_schema.si_ad_objectClass ) {
is_oc = 1;
got_oc = 1;
}
backsql_attrlist_add( bsi, p->an_desc );
}
if ( is_oc == 0 ) {
if ( got_oc == 0 ) {
/* add objectClass if not present,
* because it is required to understand
* if an entry is a referral, an alias
@ -173,7 +183,12 @@ backsql_init_search(
bsi->bsi_flt_where.bb_len = 0;
bsi->bsi_filter_oc = NULL;
bsi->bsi_status = LDAP_SUCCESS;
if ( get_base_id ) {
rc = backsql_dn2id( (backsql_info *)op->o_bd->be_private,
&bsi->bsi_base_id, dbh, base );
}
return ( bsi->bsi_status = rc );
}
static int
@ -1160,7 +1175,6 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
struct berval query;
SQLHSTMT sth;
RETCODE rc;
backsql_entryID base_id = BACKSQL_ENTRYID_INIT;
int res;
BACKSQL_ROW_NTS row;
int i;
@ -1346,27 +1360,17 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
}
case LDAP_SCOPE_ONELEVEL:
res = backsql_dn2id( bi, &base_id,
bsi->bsi_dbh, bsi->bsi_base_dn );
if ( res != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
"could not retrieve base_dn id%s\n",
res == LDAP_NO_SUCH_OBJECT ? ": no such entry"
: "", 0, 0 );
bsi->bsi_status = res;
return BACKSQL_AVL_CONTINUE;
}
assert( !BER_BVISNULL( &bsi->bsi_base_id.eid_dn ) );
#ifdef BACKSQL_ARBITRARY_KEY
Debug( LDAP_DEBUG_TRACE, "(one)id: \"%s\"\n",
base_id.eid_id.bv_val, 0, 0 );
bsi->bsi_base_id.eid_id.bv_val, 0, 0 );
#else /* ! BACKSQL_ARBITRARY_KEY */
Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n", base_id.eid_id,
0, 0 );
Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n",
bsi->bsi_base_id.eid_id, 0, 0 );
#endif /* ! BACKSQL_ARBITRARY_KEY */
rc = backsql_BindParamID( sth, 2, SQL_PARAM_INPUT,
&base_id.eid_id );
backsql_free_entryID( &base_id, 0 );
&bsi->bsi_base_id.eid_id );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
"error binding base id parameter\n", 0, 0, 0 );
@ -1511,11 +1515,16 @@ backsql_search( Operation *op, SlapReply *rs )
return 1;
}
backsql_init_search( &srch_info, &base,
/* init search */
rs->sr_err = backsql_init_search( &srch_info, &base,
op->ors_scope,
op->ors_slimit, op->ors_tlimit,
stoptime, op->ors_filter,
dbh, op, rs, op->ors_attrs );
dbh, op, rs, op->ors_attrs, 1 );
if ( rs->sr_err != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
goto done;
}
/*
* for each objectclass we try to construct query which gets IDs
@ -1536,7 +1545,7 @@ backsql_search( Operation *op, SlapReply *rs )
send_ldap_result( op, rs );
goto done;
}
/*
* now we load candidate entries (only those attributes
* mentioned in attrs and filter), test it against full filter
@ -1620,20 +1629,18 @@ backsql_search( Operation *op, SlapReply *rs )
is_entry_referral( &user_entry ) )
{
BerVarray refs;
struct berval matched_dn;
ber_dupbv( &matched_dn, &user_entry.e_name );
refs = get_entry_referrals( op, &user_entry );
if ( !refs ) {
backsql_srch_info srch_info2 = { 0 };
Entry user_entry2 = { 0 };
/* retry with the full entry... */
backsql_init_search( &srch_info2,
(void)backsql_init_search( &srch_info2,
&user_entry.e_name,
LDAP_SCOPE_BASE,
-1, -1, -1, NULL,
dbh, op, rs, NULL );
dbh, op, rs, NULL, 0 );
srch_info2.bsi_e = &user_entry2;
rc = backsql_id2entry( &srch_info2, eid );
if ( rc == LDAP_SUCCESS ) {
@ -1648,7 +1655,8 @@ backsql_search( Operation *op, SlapReply *rs )
if ( refs ) {
rs->sr_ref = referral_rewrite( refs,
&matched_dn, &op->o_req_dn,
&user_entry.e_name,
&op->o_req_dn,
op->ors_scope );
ber_bvarray_free( refs );
}
@ -1658,12 +1666,11 @@ backsql_search( Operation *op, SlapReply *rs )
}
rs->sr_err = LDAP_REFERRAL;
rs->sr_matched = matched_dn.bv_val;
rs->sr_matched = user_entry.e_name.bv_val;
send_search_reference( op, rs );
ber_bvarray_free( rs->sr_ref );
rs->sr_ref = NULL;
ber_memfree( matched_dn.bv_val );
rs->sr_matched = NULL;
goto next_entry;
@ -1767,7 +1774,14 @@ end_of_search:;
}
done:;
ch_free( srch_info.bsi_attrs );
if ( !BER_BVISNULL( &srch_info.bsi_base_id.eid_dn ) ) {
(void)backsql_free_entryID( &srch_info.bsi_base_id, 0 );
}
if ( srch_info.bsi_attrs ) {
ch_free( srch_info.bsi_attrs );
}
if ( base.bv_val != op->o_req_ndn.bv_val ) {
ch_free( base.bv_val );
}