mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-29 19:19:35 -05:00
fix, rework and optimize search base; allow orphaned entries addition
This commit is contained in:
parent
7ccd03da88
commit
60d4aaba54
8 changed files with 115 additions and 63 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue