From: Pierangelo Masarati Date: Tue, 28 Sep 2004 23:27:39 +0000 (+0000) Subject: fix, rework and optimize search base; allow orphaned entries addition X-Git-Tag: OPENLDAP_REL_ENG_2_3_0ALPHA~480 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=60d4aaba545830919283be24bb24a67b16dcb386;p=openldap fix, rework and optimize search base; allow orphaned entries addition --- diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index bf733ff08d..4074f37bd9 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -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", diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index 08370e7abe..db901cbbb5 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -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; diff --git a/servers/slapd/back-sql/bind.c b/servers/slapd/back-sql/bind.c index 2f8d31c2c0..461ef8d18c 100644 --- a/servers/slapd/back-sql/bind.c +++ b/servers/slapd/back-sql/bind.c @@ -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; diff --git a/servers/slapd/back-sql/compare.c b/servers/slapd/back-sql/compare.c index 9dd4ea7620..5296f46bed 100644 --- a/servers/slapd/back-sql/compare.c +++ b/servers/slapd/back-sql/compare.c @@ -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 ); } diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index 02795c64ef..fe62525cf6 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -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, diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index 698daed1c7..624ea7b950 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -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 ); diff --git a/servers/slapd/back-sql/proto-sql.h b/servers/slapd/back-sql/proto-sql.h index c24e206075..2f623900c4 100644 --- a/servers/slapd/back-sql/proto-sql.h +++ b/servers/slapd/back-sql/proto-sql.h @@ -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 diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index f3951734bb..c3c96746e0 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -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 ); }