mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-30 13:30:57 +08:00
handle referrals correctly; allow to add suffix entry; fix multiple values add bug; cleanup
This commit is contained in:
parent
37db80eadb
commit
467524ef92
@ -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;
|
||||
}
|
||||
|
||||
rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realpdn );
|
||||
switch ( rs->sr_err ) {
|
||||
case LDAP_NO_SUCH_OBJECT:
|
||||
if ( pdn.bv_len > 0 ) {
|
||||
break;
|
||||
while ( 1 ) {
|
||||
struct berval dn;
|
||||
char *matched = NULL;
|
||||
|
||||
if ( realpdn.bv_val != pdn.bv_val ) {
|
||||
ch_free( realpdn.bv_val );
|
||||
}
|
||||
/* fail over to next case */
|
||||
|
||||
case LDAP_SUCCESS:
|
||||
matched = pdn.bv_val;
|
||||
/* fail over to next case */
|
||||
|
||||
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 {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef BACKSQL_REALLOC_STMT
|
||||
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;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
#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;
|
||||
|
||||
for ( i = 0, at_val = &at->a_vals[ i ];
|
||||
at_val->bv_val != NULL;
|
||||
i++, at_val = &at->a_vals[ i ] ) {
|
||||
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 ) {
|
||||
|
||||
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "SQL-backend error";
|
||||
goto done;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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 );
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user