From 467524ef92375a45cb87300e71ad837bc4f4b1f4 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 21 Aug 2004 09:38:08 +0000 Subject: [PATCH] handle referrals correctly; allow to add suffix entry; fix multiple values add bug; cleanup --- servers/slapd/back-sql/add.c | 219 +++++++++++++++++----------- servers/slapd/back-sql/back-sql.h | 1 + servers/slapd/back-sql/schema-map.c | 6 + servers/slapd/back-sql/search.c | 87 +++++++---- 4 files changed, 195 insertions(+), 118 deletions(-) diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index a938b16978..b3e51aea4c 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -76,7 +76,7 @@ backsql_modify_internal( SQLUSMALLINT pno, po; /* procedure return code */ int prc; - + #ifdef BACKSQL_REALLOC_STMT SQLAllocStmt( dbh, &sth ); #endif /* BACKSQL_REALLOC_STMT */ @@ -321,6 +321,20 @@ add_only:; for ( i = 0, at_val = c_mod->sm_values; at_val->bv_val != NULL; i++, at_val++ ) { + + rc = backsql_Prepare( dbh, &sth, at->bam_add_proc, 0 ); + if ( rc != SQL_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, + " backsql_modify_internal(): " + "error preparing add query\n", + 0, 0, 0 ); + backsql_PrintErrors( bi->db_env, dbh, sth, rc ); + + rs->sr_err = LDAP_OTHER; + rs->sr_text = "SQL-backend error"; + goto done; + } + if ( BACKSQL_IS_ADD( at->bam_expect_return ) ) { pno = 1; SQLBindParameter( sth, 1, @@ -357,8 +371,7 @@ add_only:; " backsql_modify_internal(): " "executing \"%s\"\n", at->bam_add_proc, 0, 0 ); - rc = SQLExecDirect( sth, at->bam_add_proc, - SQL_NTS ); + rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): " @@ -516,7 +529,8 @@ backsql_add( Operation *op, SlapReply *rs ) SQLUSMALLINT pno, po; /* procedure return code */ int prc; - struct berval realdn, realpdn; + struct berval realdn = BER_BVNULL, + realpdn = BER_BVNULL; Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n", op->oq_add.rs_e->e_name.bv_val, 0, 0 ); @@ -616,9 +630,14 @@ backsql_add( Operation *op, SlapReply *rs ) } /* - * Check if parent exists + * Get the parent dn and see if the corresponding entry exists. */ - dnParent( &op->oq_add.rs_e->e_name, &pdn ); + if ( be_issuffix( op->o_bd, &op->oq_add.rs_e->e_nname ) ) { + pdn = slap_empty_bv; + } else { + dnParent( &op->oq_add.rs_e->e_nname, &pdn ); + } + realpdn = pdn; if ( backsql_api_dn2odbc( op, rs, &realpdn ) ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " @@ -640,60 +659,73 @@ backsql_add( Operation *op, SlapReply *rs ) } /* - * Look for matched + * no parent! + * if not attempting to add entry at suffix or with parent "" */ - while ( 1 ) { - struct berval dn; - char *matched = NULL; - - if ( realpdn.bv_val != pdn.bv_val ) { - ch_free( realpdn.bv_val ); - } - - dn = pdn; - dnParent( &dn, &pdn ); - + if ( ( ( !be_isroot( op ) && !be_shadow_update( op ) ) + || pdn.bv_len > 0 ) && !is_entry_glue( op->oq_add.rs_e ) ) + { + Debug( LDAP_DEBUG_TRACE, " backsql_add: %s denied\n", + pdn.bv_len == 0 ? "suffix" : "entry at root", + 0, 0 ); /* - * Empty DN ("") defaults to LDAP_SUCCESS + * Look for matched */ - realpdn = pdn; - if ( backsql_api_dn2odbc( op, rs, &realpdn ) ) { - Debug( LDAP_DEBUG_TRACE, - " backsql_add(\"%s\"): " - "backsql_api_dn2odbc failed\n", - op->oq_add.rs_e->e_name.bv_val, 0, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "SQL-backend error"; - goto done; + while ( 1 ) { + struct berval dn; + char *matched = NULL; + + if ( realpdn.bv_val != pdn.bv_val ) { + ch_free( realpdn.bv_val ); + } + + dn = pdn; + dnParent( &dn, &pdn ); + + /* + * Empty DN ("") defaults to LDAP_SUCCESS + */ + realpdn = pdn; + if ( backsql_api_dn2odbc( op, rs, &realpdn ) ) { + Debug( LDAP_DEBUG_TRACE, + " backsql_add(\"%s\"): " + "backsql_api_dn2odbc failed\n", + op->oq_add.rs_e->e_name.bv_val, 0, 0 ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "SQL-backend error"; + goto done; + } + + rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realpdn ); + switch ( rs->sr_err ) { + case LDAP_NO_SUCH_OBJECT: + if ( pdn.bv_len > 0 ) { + break; + } + /* fail over to next case */ + + case LDAP_SUCCESS: + matched = pdn.bv_val; + /* fail over to next case */ + + default: + rs->sr_err = LDAP_NO_SUCH_OBJECT; + rs->sr_matched = matched; + goto done; + } } + } else { - rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realpdn ); - switch ( rs->sr_err ) { - case LDAP_NO_SUCH_OBJECT: - if ( pdn.bv_len > 0 ) { - break; - } - /* fail over to next case */ - - case LDAP_SUCCESS: - matched = pdn.bv_val; - /* fail over to next case */ - - default: - rs->sr_err = LDAP_NO_SUCH_OBJECT; - rs->sr_matched = matched; - goto done; - } +#ifdef BACKSQL_ARBITRARY_KEY + ber_str2bv( "SUFFIX", 0, 1, &parent_id.eid_id ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + parent_id.eid_id = 0; +#endif /* ! BACKSQL_ARBITRARY_KEY */ + rs->sr_err = LDAP_SUCCESS; } } - /* - * create_proc is executed; if expect_return is set, then - * an output parameter is bound, which should contain - * the id of the added row; otherwise the procedure - * is expected to return the id as the first column of a select - */ - + /* check "children" pseudo-attribute access to parent */ p.e_attrs = NULL; p.e_name = pdn; dnParent( &op->oq_add.rs_e->e_nname, &p.e_nname ); @@ -703,6 +735,13 @@ backsql_add( Operation *op, SlapReply *rs ) goto done; } + /* + * create_proc is executed; if expect_return is set, then + * an output parameter is bound, which should contain + * 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 ); if ( rc != SQL_SUCCESS ) { rs->sr_err = LDAP_OTHER; @@ -887,40 +926,41 @@ backsql_add( Operation *op, SlapReply *rs ) continue; } + for ( i = 0, at_val = &at->a_vals[ i ]; + at_val->bv_val != NULL; + i++, at_val = &at->a_vals[ i ] ) + { + char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL"; + #ifdef BACKSQL_REALLOC_STMT - rc = backsql_Prepare( dbh, &sth, at_rec->bam_add_proc, 0 ); - if ( rc != SQL_SUCCESS ) { + rc = backsql_Prepare( dbh, &sth, at_rec->bam_add_proc, 0 ); + if ( rc != SQL_SUCCESS ) { - if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { - rs->sr_err = LDAP_OTHER; - rs->sr_text = "SQL-backend error"; - goto done; - } + if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "SQL-backend error"; + goto done; + } - continue; - } + goto next_attr; + } #endif /* BACKSQL_REALLOC_STMT */ - if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) { - pno = 1; - SQLBindParameter( sth, 1, SQL_PARAM_OUTPUT, - SQL_C_ULONG, SQL_INTEGER, - 0, 0, &prc, 0, 0 ); - } else { - pno = 0; - } - - po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0; - currpos = pno + 1 + po; - SQLBindParameter( sth, currpos, - SQL_PARAM_INPUT, SQL_C_ULONG, - SQL_INTEGER, 0, 0, &new_keyval, 0, 0 ); - currpos = pno + 2 - po; + if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) { + pno = 1; + SQLBindParameter( sth, 1, SQL_PARAM_OUTPUT, + SQL_C_ULONG, SQL_INTEGER, + 0, 0, &prc, 0, 0 ); + } else { + pno = 0; + } - for ( i = 0, at_val = &at->a_vals[ i ]; - at_val->bv_val != NULL; - i++, at_val = &at->a_vals[ i ] ) { - char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL"; + po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0; + currpos = pno + 1 + po; + SQLBindParameter( sth, currpos, + SQL_PARAM_INPUT, SQL_C_ULONG, + SQL_INTEGER, 0, 0, &new_keyval, 0, 0 ); + currpos = pno + 2 - po; /* * Do not deal with the objectClass that is used @@ -966,12 +1006,14 @@ backsql_add( Operation *op, SlapReply *rs ) goto done; } } - } #ifndef BACKSQL_REALLOC_STMT - SQLFreeStmt( sth, SQL_RESET_PARAMS ); + SQLFreeStmt( sth, SQL_RESET_PARAMS ); #else /* BACKSQL_REALLOC_STMT */ - SQLFreeStmt( sth, SQL_DROP ); + SQLFreeStmt( sth, SQL_DROP ); #endif /* BACKSQL_REALLOC_STMT */ + } + +next_attr:; } #ifdef BACKSQL_REALLOC_STMT @@ -983,8 +1025,7 @@ backsql_add( Operation *op, SlapReply *rs ) } #endif /* BACKSQL_REALLOC_STMT */ - backsql_BindParamStr( sth, 1, op->oq_add.rs_e->e_name.bv_val, - BACKSQL_MAX_DN_LEN ); + backsql_BindParamStr( sth, 1, realdn.bv_val, BACKSQL_MAX_DN_LEN ); SQLBindParameter( sth, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &oc->bom_id, 0, 0 ); #ifdef BACKSQL_ARBITRARY_KEY @@ -1050,13 +1091,15 @@ backsql_add( Operation *op, SlapReply *rs ) done:; send_ldap_result( op, rs ); - if ( realdn.bv_val != op->oq_add.rs_e->e_name.bv_val ) { + if ( !BER_BVISNULL( &realdn ) + && realdn.bv_val != op->oq_add.rs_e->e_name.bv_val ) + { ch_free( realdn.bv_val ); } - if ( realpdn.bv_val != pdn.bv_val ) { + if ( !BER_BVISNULL( &realpdn ) && realpdn.bv_val != pdn.bv_val ) { ch_free( realpdn.bv_val ); } - if ( parent_id.eid_dn.bv_val != NULL ) { + if ( !BER_BVISNULL( &parent_id.eid_dn ) ) { backsql_free_entryID( &parent_id, 0 ); } diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index de5e279edc..6bfedc643c 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -250,6 +250,7 @@ typedef struct backsql_srch_info { time_t bsi_stoptime; backsql_entryID *bsi_id_list, + **bsi_id_listtail, *bsi_c_eid; int bsi_n_candidates; int bsi_abandon; diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c index 69bd1c293e..e7d701b8bc 100644 --- a/servers/slapd/back-sql/schema-map.c +++ b/servers/slapd/back-sql/schema-map.c @@ -41,7 +41,10 @@ backsql_cmp_oc( const void *v_m1, const void *v_m2 ) { const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2; +#if 0 return SLAP_PTRCMP( m1->bom_oc, m2->bom_oc ); +#endif + return ber_bvcmp( &m1->bom_oc->soc_cname, &m2->bom_oc->soc_cname ); } static int @@ -60,7 +63,10 @@ backsql_cmp_attr( const void *v_m1, const void *v_m2 ) { const backsql_at_map_rec *m1 = v_m1, *m2 = v_m2; +#if 0 return SLAP_PTRCMP( m1->bam_ad, m2->bam_ad ); +#endif + return ber_bvcmp( &m1->bam_ad->ad_cname, &m2->bam_ad->ad_cname ); } int diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index e14733b53b..ed43829b12 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -126,6 +126,8 @@ backsql_init_search( bsi->bsi_attrs = NULL; } else { + int is_oc = 0; + bsi->bsi_attrs = (AttributeName *)ch_calloc( 1, sizeof( AttributeName ) ); BER_BVZERO( &bsi->bsi_attrs[ 0 ].an_name ); @@ -140,14 +142,25 @@ backsql_init_search( } else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) { continue; + } else if ( p->an_desc == slap_schema.si_ad_objectClass ) { + is_oc = 1; } backsql_attrlist_add( bsi, p->an_desc ); } + + if ( is_oc == 0 ) { + /* add objectClass if not present, + * because it is required to understand + * if an entry is a referral, an alias + * or so... */ + backsql_attrlist_add( bsi, slap_schema.si_ad_objectClass ); + } } bsi->bsi_abandon = 0; bsi->bsi_id_list = NULL; + bsi->bsi_id_listtail = &bsi->bsi_id_list; bsi->bsi_n_candidates = 0; bsi->bsi_stoptime = stoptime; BER_BVZERO( &bsi->bsi_sel.bb_val ); @@ -1315,9 +1328,10 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) c_id->eid_dn = dn; } - c_id->eid_next = bsi->bsi_id_list; - bsi->bsi_id_list = c_id; - bsi->bsi_n_candidates--; + /* append at end of list ... */ + c_id->eid_next = NULL; + *bsi->bsi_id_listtail = c_id; + bsi->bsi_id_listtail = &c_id->eid_next; #ifdef BACKSQL_ARBITRARY_KEY Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " @@ -1330,6 +1344,8 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) c_id->eid_id, c_id->eid_keyval, row.cols[ 3 ] ); #endif /* ! BACKSQL_ARBITRARY_KEY */ + /* count candidates, for unchecked limit */ + bsi->bsi_n_candidates--; if ( bsi->bsi_n_candidates == -1 ) { break; } @@ -1495,6 +1511,28 @@ backsql_search( Operation *op, SlapReply *rs ) 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, + &user_entry.e_name, + LDAP_SCOPE_BASE, + -1, -1, -1, NULL, + dbh, op, rs, NULL ); + srch_info2.bsi_e = &user_entry2; + rc = backsql_id2entry( &srch_info2, eid ); + if ( rc == LDAP_SUCCESS ) { + if ( is_entry_referral( &user_entry2 ) ) + { + refs = get_entry_referrals( op, + &user_entry2 ); + } /* else: FIXME: inconsistency! */ + entry_clean( &user_entry2 ); + } + } + if ( refs ) { rs->sr_ref = referral_rewrite( refs, &matched_dn, &op->o_req_dn, @@ -1515,7 +1553,7 @@ backsql_search( Operation *op, SlapReply *rs ) ber_memfree( matched_dn.bv_val ); rs->sr_matched = NULL; - continue; + goto next_entry; } /* @@ -1546,11 +1584,7 @@ backsql_search( Operation *op, SlapReply *rs ) "has_children failed( %d)\n", rc, 0, 0 ); rc = 1; - break; - } - - if ( rc ) { - continue; + goto next_entry; } } @@ -1563,39 +1597,32 @@ backsql_search( Operation *op, SlapReply *rs ) hasSubordinate = NULL; } -#if 0 /* noop is masked SLAP_CTRL_UPDATE */ - if ( op->o_noop ) { - sres = 0; - } else -#endif - { - rs->sr_attrs = op->ors_attrs; - rs->sr_operational_attrs = NULL; - rs->sr_entry = &user_entry; - rs->sr_flags = REP_ENTRY_MODIFIABLE; - sres = send_search_entry( op, rs ); - rs->sr_entry = NULL; - rs->sr_attrs = NULL; - rs->sr_operational_attrs = NULL; - } + rs->sr_attrs = op->ors_attrs; + rs->sr_operational_attrs = NULL; + rs->sr_entry = &user_entry; + rs->sr_flags = REP_ENTRY_MODIFIABLE; + sres = send_search_entry( op, rs ); + rs->sr_entry = NULL; + rs->sr_attrs = NULL; + rs->sr_operational_attrs = NULL; switch ( sres ) { case 0: break; - case -1: - Debug( LDAP_DEBUG_TRACE, "backsql_search(): " - "connection lost\n", 0, 0, 0 ); - goto end_of_search; - default: /* * FIXME: send_search_entry failed; * better stop */ - break; + case -1: + Debug( LDAP_DEBUG_TRACE, "backsql_search(): " + "connection lost\n", 0, 0, 0 ); + goto end_of_search; } } + +next_entry:; entry_clean( &user_entry ); if ( op->ors_slimit != SLAP_NO_LIMIT -- 2.39.5