improve previous commit; consistently use dn/ndn; add support for LDAP_SCOPE_SUBORDINATE

This commit is contained in:
Pierangelo Masarati 2004-10-03 21:08:54 +00:00
parent 796dce8657
commit 87a63d3b5d
10 changed files with 211 additions and 101 deletions

View File

@ -752,7 +752,7 @@ backsql_add_attr(
* to build the entry * to build the entry
*/ */
if ( at->a_desc == slap_schema.si_ad_objectClass ) { if ( at->a_desc == slap_schema.si_ad_objectClass ) {
if ( bvmatch( at_val, &oc->bom_oc->soc_cname ) ) if ( dn_match( at_val, &oc->bom_oc->soc_cname ) )
{ {
continue; continue;
} }
@ -882,6 +882,7 @@ backsql_add( Operation *op, SlapReply *rs )
*at_objectClass = NULL; *at_objectClass = NULL;
struct berval pdn; struct berval pdn;
struct berval realdn = BER_BVNULL, struct berval realdn = BER_BVNULL,
realndn = BER_BVNULL,
realpdn = BER_BVNULL; realpdn = BER_BVNULL;
Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n", Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
@ -965,14 +966,23 @@ backsql_add( Operation *op, SlapReply *rs )
if ( backsql_api_dn2odbc( op, rs, &realdn ) ) { if ( backsql_api_dn2odbc( op, rs, &realdn ) ) {
Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
"backsql_api_dn2odbc(\"%s\") failed\n", "backsql_api_dn2odbc(\"%s\") failed\n",
op->oq_add.rs_e->e_name.bv_val, op->oq_add.rs_e->e_name.bv_val, realdn.bv_val, 0 );
op->oq_add.rs_e->e_name.bv_val, 0 );
rs->sr_err = LDAP_OTHER; rs->sr_err = LDAP_OTHER;
rs->sr_text = "SQL-backend error"; rs->sr_text = "SQL-backend error";
goto done; goto done;
} }
rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realdn ); realndn = op->oq_add.rs_e->e_nname;
if ( backsql_api_dn2odbc( op, rs, &realndn ) ) {
Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
"backsql_api_dn2odbc(\"%s\") failed\n",
op->oq_add.rs_e->e_name.bv_val, realndn.bv_val, 0 );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "SQL-backend error";
goto done;
}
rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realndn );
if ( rs->sr_err == LDAP_SUCCESS ) { if ( rs->sr_err == LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
"entry exists\n", "entry exists\n",
@ -1388,10 +1398,15 @@ done:;
{ {
ch_free( realdn.bv_val ); ch_free( realdn.bv_val );
} }
if ( !BER_BVISNULL( &realndn )
&& realndn.bv_val != op->oq_add.rs_e->e_nname.bv_val )
{
ch_free( realndn.bv_val );
}
if ( !BER_BVISNULL( &realpdn ) && realpdn.bv_val != pdn.bv_val ) { if ( !BER_BVISNULL( &realpdn ) && realpdn.bv_val != pdn.bv_val ) {
ch_free( realpdn.bv_val ); ch_free( realpdn.bv_val );
} }
if ( !BER_BVISNULL( &parent_id.eid_dn ) ) { if ( !BER_BVISNULL( &parent_id.eid_ndn ) ) {
(void)backsql_free_entryID( &parent_id, 0 ); (void)backsql_free_entryID( &parent_id, 0 );
} }

View File

@ -153,13 +153,14 @@ typedef struct backsql_entryID {
unsigned long eid_oc_id; unsigned long eid_oc_id;
struct berval eid_dn; struct berval eid_dn;
struct berval eid_ndn;
struct backsql_entryID *eid_next; struct backsql_entryID *eid_next;
} backsql_entryID; } backsql_entryID;
#ifdef BACKSQL_ARBITRARY_KEY #ifdef BACKSQL_ARBITRARY_KEY
#define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, BER_BVNULL, NULL } #define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, BER_BVNULL, BER_BVNULL, NULL }
#else /* ! BACKSQL_ARBITRARY_KEY */ #else /* ! BACKSQL_ARBITRARY_KEY */
#define BACKSQL_ENTRYID_INIT { 0, 0, 0, BER_BVNULL, NULL } #define BACKSQL_ENTRYID_INIT { 0, 0, 0, BER_BVNULL, BER_BVNULL, NULL }
#endif /* BACKSQL_ARBITRARY_KEY */ #endif /* BACKSQL_ARBITRARY_KEY */
/* /*
@ -265,9 +266,14 @@ typedef struct backsql_srch_info {
#define BSQL_SF_ALL_OPER 0x0001 #define BSQL_SF_ALL_OPER 0x0001
#define BSQL_SF_FILTER_HASSUBORDINATE 0x0002 #define BSQL_SF_FILTER_HASSUBORDINATE 0x0002
struct berval *bsi_base_dn; struct berval *bsi_base_ndn;
backsql_entryID bsi_base_id; backsql_entryID bsi_base_id;
int bsi_scope; int bsi_scope;
/* BACKSQL_SCOPE_BASE_LIKE can be set by API in ors_scope
* whenever the search base DN contains chars that cannot
* be mapped into the charset used in the RDBMS; so they're
* turned into '%' and an approximate ('LIKE') condition
* is used */
#define BACKSQL_SCOPE_BASE_LIKE ( LDAP_SCOPE_BASE | 0x1000 ) #define BACKSQL_SCOPE_BASE_LIKE ( LDAP_SCOPE_BASE | 0x1000 )
Filter *bsi_filter; Filter *bsi_filter;
int bsi_slimit, int bsi_slimit,

View File

@ -38,7 +38,7 @@ backsql_bind( Operation *op, SlapReply *rs )
backsql_srch_info bsi; backsql_srch_info bsi;
AttributeName anlist[2]; AttributeName anlist[2];
int rc; int rc;
struct berval dn; struct berval ndn;
Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 ); Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 );
@ -73,8 +73,8 @@ backsql_bind( Operation *op, SlapReply *rs )
return 1; return 1;
} }
dn = op->o_req_ndn; ndn = op->o_req_ndn;
if ( backsql_api_dn2odbc( op, rs, &dn ) ) { if ( backsql_api_dn2odbc( op, rs, &ndn ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_search(): " Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
"backsql_api_dn2odbc failed\n", "backsql_api_dn2odbc failed\n",
0, 0, 0 ); 0, 0, 0 );
@ -87,11 +87,11 @@ backsql_bind( Operation *op, SlapReply *rs )
anlist[0].an_desc = password; anlist[0].an_desc = password;
anlist[1].an_name.bv_val = NULL; anlist[1].an_name.bv_val = NULL;
rc = backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE, rc = backsql_init_search( &bsi, &ndn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, anlist, 1 ); -1, -1, -1, NULL, dbh, op, rs, anlist, 1 );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): " Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"could not retrieve bind dn id - no such entry\n", "could not retrieve bindDN ID - no such entry\n",
0, 0, 0 ); 0, 0, 0 );
rs->sr_err = LDAP_INVALID_CREDENTIALS; rs->sr_err = LDAP_INVALID_CREDENTIALS;
send_ldap_result( op, rs ); send_ldap_result( op, rs );
@ -134,7 +134,7 @@ backsql_bind( Operation *op, SlapReply *rs )
} }
error_return:; error_return:;
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) { if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
(void)backsql_free_entryID( &bsi.bsi_base_id, 0 ); (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
} }
@ -143,8 +143,8 @@ error_return:;
return 1; return 1;
} }
if ( dn.bv_val != op->o_req_dn.bv_val ) { if ( ndn.bv_val != op->o_req_ndn.bv_val ) {
ch_free( dn.bv_val ); ch_free( ndn.bv_val );
} }
Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0); Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0);

View File

@ -37,7 +37,7 @@ backsql_compare( Operation *op, SlapReply *rs )
backsql_srch_info bsi; backsql_srch_info bsi;
int rc; int rc;
AttributeName anlist[2]; AttributeName anlist[2];
struct berval dn; struct berval ndn;
user_entry.e_name.bv_val = NULL; user_entry.e_name.bv_val = NULL;
user_entry.e_name.bv_len = 0; user_entry.e_name.bv_len = 0;
@ -58,8 +58,8 @@ backsql_compare( Operation *op, SlapReply *rs )
goto return_results; goto return_results;
} }
dn = op->o_req_ndn; ndn = op->o_req_ndn;
if ( backsql_api_dn2odbc( op, rs, &dn ) ) { if ( backsql_api_dn2odbc( op, rs, &ndn ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_search(): " Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
"backsql_api_dn2odbc failed\n", "backsql_api_dn2odbc failed\n",
0, 0, 0 ); 0, 0, 0 );
@ -95,11 +95,11 @@ backsql_compare( Operation *op, SlapReply *rs )
user_entry.e_attrs = nrs.sr_operational_attrs; user_entry.e_attrs = nrs.sr_operational_attrs;
} else { } else {
rc = backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE, rc = backsql_init_search( &bsi, &ndn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, anlist, 1 ); -1, -1, -1, NULL, dbh, op, rs, anlist, 1 );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_compare(): " Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
"could not retrieve compare dn id - no such entry\n", "could not retrieve compareDN ID - no such entry\n",
0, 0, 0 ); 0, 0, 0 );
rs->sr_err = LDAP_NO_SUCH_OBJECT; rs->sr_err = LDAP_NO_SUCH_OBJECT;
goto return_results; goto return_results;
@ -145,12 +145,12 @@ backsql_compare( Operation *op, SlapReply *rs )
return_results:; return_results:;
send_ldap_result( op, rs ); send_ldap_result( op, rs );
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) { if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
(void)backsql_free_entryID( &bsi.bsi_base_id, 0 ); (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
} }
if ( dn.bv_val != op->o_req_dn.bv_val ) { if ( ndn.bv_val != op->o_req_ndn.bv_val ) {
ch_free( dn.bv_val ); ch_free( ndn.bv_val );
} }
if ( e != NULL ) { if ( e != NULL ) {

View File

@ -120,6 +120,7 @@ backsql_delete( Operation *op, SlapReply *rs )
goto done; goto done;
} }
/* FIXME: API... */
rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn ); rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, " backsql_delete(): " Debug( LDAP_DEBUG_TRACE, " backsql_delete(): "

View File

@ -42,9 +42,16 @@ backsql_free_entryID( backsql_entryID *id, int freeit )
next = id->eid_next; next = id->eid_next;
if ( id->eid_dn.bv_val != NULL ) { if ( !BER_BVISNULL( &id->eid_ndn ) ) {
free( id->eid_dn.bv_val ); if ( !BER_BVISNULL( &id->eid_dn )
BER_BVZERO( &id->eid_dn ); && id->eid_dn.bv_val != id->eid_ndn.bv_val )
{
free( id->eid_dn.bv_val );
BER_BVZERO( &id->eid_dn );
}
free( id->eid_ndn.bv_val );
BER_BVZERO( &id->eid_ndn );
} }
#ifdef BACKSQL_ARBITRARY_KEY #ifdef BACKSQL_ARBITRARY_KEY
@ -66,12 +73,15 @@ backsql_free_entryID( backsql_entryID *id, int freeit )
return next; return next;
} }
/*
* NOTE: the dn must be normalized
*/
int int
backsql_dn2id( backsql_dn2id(
backsql_info *bi, backsql_info *bi,
backsql_entryID *id, backsql_entryID *id,
SQLHDBC dbh, SQLHDBC dbh,
struct berval *dn ) struct berval *ndn )
{ {
SQLHSTMT sth; SQLHSTMT sth;
BACKSQL_ROW_NTS row; BACKSQL_ROW_NTS row;
@ -80,7 +90,7 @@ backsql_dn2id(
/* TimesTen */ /* TimesTen */
char upperdn[ BACKSQL_MAX_DN_LEN + 1 ]; char upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
struct berval toBind; struct berval tbbDN;
int i, j; int i, j;
/* /*
@ -91,18 +101,18 @@ backsql_dn2id(
*/ */
Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): dn=\"%s\"%s\n", Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): dn=\"%s\"%s\n",
dn->bv_val, id == NULL ? " (no ID)" : "", 0 ); ndn->bv_val, id == NULL ? " (no ID)" : "", 0 );
if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) { if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,
"backsql_dn2id(): DN \"%s\" (%ld bytes) " "backsql_dn2id(): DN \"%s\" (%ld bytes) "
"exceeds max DN length (%d):\n", "exceeds max DN length (%d):\n",
dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN ); ndn->bv_val, ndn->bv_len, BACKSQL_MAX_DN_LEN );
return LDAP_OTHER; return LDAP_OTHER;
} }
/* return baseObject if available and matches */ /* return baseObject if available and matches */
if ( bi->sql_baseObject != NULL && bvmatch( dn, &bi->sql_baseObject->e_nname ) ) { if ( bi->sql_baseObject != NULL && dn_match( ndn, &bi->sql_baseObject->e_nname ) ) {
if ( id != NULL ) { if ( id != NULL ) {
#ifdef BACKSQL_ARBITRARY_KEY #ifdef BACKSQL_ARBITRARY_KEY
ber_dupbv( &id->eid_id, &backsql_baseObject_bv ); ber_dupbv( &id->eid_id, &backsql_baseObject_bv );
@ -113,7 +123,8 @@ backsql_dn2id(
#endif /* ! BACKSQL_ARBITRARY_KEY */ #endif /* ! BACKSQL_ARBITRARY_KEY */
id->eid_oc_id = BACKSQL_BASEOBJECT_OC; id->eid_oc_id = BACKSQL_BASEOBJECT_OC;
ber_dupbv( &id->eid_dn, &bi->sql_baseObject->e_nname ); ber_dupbv( &id->eid_ndn, &bi->sql_baseObject->e_nname );
ber_dupbv( &id->eid_dn, &bi->sql_baseObject->e_name );
id->eid_next = NULL; id->eid_next = NULL;
} }
@ -140,36 +151,36 @@ backsql_dn2id(
* that can be searched using indexes * that can be searched using indexes
*/ */
for ( i = 0, j = dn->bv_len - 1; dn->bv_val[ i ]; i++, j--) { for ( i = 0, j = ndn->bv_len - 1; ndn->bv_val[ i ]; i++, j--) {
upperdn[ i ] = dn->bv_val[ j ]; upperdn[ i ] = ndn->bv_val[ j ];
} }
upperdn[ i ] = '\0'; upperdn[ i ] = '\0';
ldap_pvt_str2upper( upperdn ); ldap_pvt_str2upper( upperdn );
Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): upperdn=\"%s\"\n", Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): upperdn=\"%s\"\n",
upperdn, 0, 0 ); upperdn, 0, 0 );
ber_str2bv( upperdn, 0, 0, &toBind ); ber_str2bv( upperdn, 0, 0, &tbbDN );
} else { } else {
if ( BACKSQL_USE_REVERSE_DN( bi ) ) { if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 ); AC_MEMCPY( upperdn, ndn->bv_val, ndn->bv_len + 1 );
ldap_pvt_str2upper( upperdn ); ldap_pvt_str2upper( upperdn );
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,
"==>backsql_dn2id(): upperdn=\"%s\"\n", "==>backsql_dn2id(): upperdn=\"%s\"\n",
upperdn, 0, 0 ); upperdn, 0, 0 );
ber_str2bv( upperdn, 0, 0, &toBind ); ber_str2bv( upperdn, 0, 0, &tbbDN );
} else { } else {
toBind = *dn; tbbDN = *ndn;
} }
} }
rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &toBind ); rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &tbbDN );
if ( rc != SQL_SUCCESS) { if ( rc != SQL_SUCCESS) {
/* end TimesTen */ /* end TimesTen */
Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): " Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
"error binding dn=\"%s\" parameter:\n", "error binding dn=\"%s\" parameter:\n",
toBind.bv_val, 0, 0 ); tbbDN.bv_val, 0, 0 );
backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
SQLFreeStmt( sth, SQL_DROP ); SQLFreeStmt( sth, SQL_DROP );
return LDAP_OTHER; return LDAP_OTHER;
@ -179,7 +190,7 @@ backsql_dn2id(
if ( rc != SQL_SUCCESS ) { if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): " Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
"error executing query (\"%s\", \"%s\"):\n", "error executing query (\"%s\", \"%s\"):\n",
bi->sql_id_query, toBind.bv_val, 0 ); bi->sql_id_query, tbbDN.bv_val, 0 );
backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
SQLFreeStmt( sth, SQL_DROP ); SQLFreeStmt( sth, SQL_DROP );
return LDAP_OTHER; return LDAP_OTHER;
@ -188,11 +199,21 @@ backsql_dn2id(
backsql_BindRowAsStrings( sth, &row ); backsql_BindRowAsStrings( sth, &row );
rc = SQLFetch( sth ); rc = SQLFetch( sth );
if ( BACKSQL_SUCCESS( rc ) ) { if ( BACKSQL_SUCCESS( rc ) ) {
res = LDAP_SUCCESS; char buf[BUFSIZ];
Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): id=%s keyval=%s oc_id=%s\n",
row.cols[ 0 ], row.cols[ 1 ], row.cols[ 2 ] );
#ifdef LDAP_DEBUG
snprintf( buf, sizeof(buf),
"id=%s keyval=%s oc_id=%s dn=%s",
row.cols[ 0 ], row.cols[ 1 ],
row.cols[ 2 ], row.cols[ 3 ] );
Debug( LDAP_DEBUG_TRACE,
"<==backsql_dn2id(): %s\n", buf, 0, 0 );
#endif /* LDAP_DEBUG */
res = LDAP_SUCCESS;
if ( id != NULL ) { if ( id != NULL ) {
struct berval dn;
#ifdef BACKSQL_ARBITRARY_KEY #ifdef BACKSQL_ARBITRARY_KEY
ber_str2bv( row.cols[ 0 ], 0, 1, &id->eid_id ); ber_str2bv( row.cols[ 0 ], 0, 1, &id->eid_id );
ber_str2bv( row.cols[ 1 ], 0, 1, &id->eid_keyval ); ber_str2bv( row.cols[ 1 ], 0, 1, &id->eid_keyval );
@ -202,7 +223,20 @@ backsql_dn2id(
#endif /* ! BACKSQL_ARBITRARY_KEY */ #endif /* ! BACKSQL_ARBITRARY_KEY */
id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 ); id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 );
ber_dupbv( &id->eid_dn, dn ); ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
res = dnPrettyNormal( NULL, &dn, &id->eid_dn, &id->eid_ndn, NULL );
if ( res != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_dn2id(\"%s\"): "
"dnPrettyNormal failed (%d: %s)\n",
ndn->bv_val, res,
ldap_err2string( res ) );
/* cleanup... */
(void)backsql_free_entryID( id, 0 );
}
id->eid_next = NULL; id->eid_next = NULL;
} }
@ -456,12 +490,8 @@ backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
goto done; goto done;
} }
rc = dnPrettyNormal( NULL, &eid->eid_dn, ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, bsi->bsi_op->o_tmpmemctx );
&bsi->bsi_e->e_name, &bsi->bsi_e->e_nname, ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, bsi->bsi_op->o_tmpmemctx );
bsi->bsi_op->o_tmpmemctx );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
bsi->bsi_e->e_attrs = NULL; bsi->bsi_e->e_attrs = NULL;
bsi->bsi_e->e_private = NULL; bsi->bsi_e->e_private = NULL;

View File

@ -61,6 +61,7 @@ backsql_modify( Operation *op, SlapReply *rs )
return 1; return 1;
} }
/* FIXME: API... */
rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn ); rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, " backsql_modify(): " Debug( LDAP_DEBUG_TRACE, " backsql_modify(): "

View File

@ -65,6 +65,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
return 1; return 1;
} }
/* FIXME: API... */
rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn ); rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): "
@ -191,6 +192,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): new entry dn is \"%s\"\n", Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): new entry dn is \"%s\"\n",
new_dn.bv_val, 0, 0 ); new_dn.bv_val, 0, 0 );
/* FIXME: API... */
rs->sr_err = backsql_dn2id( bi, &pe_id, dbh, &p_ndn ); rs->sr_err = backsql_dn2id( bi, &pe_id, dbh, &p_ndn );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): "
@ -211,6 +213,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
(void)backsql_free_entryID( &pe_id, 0 ); (void)backsql_free_entryID( &pe_id, 0 );
/* FIXME: API... */
rs->sr_err = backsql_dn2id( bi, &new_pe_id, dbh, new_npdn ); rs->sr_err = backsql_dn2id( bi, &new_pe_id, dbh, new_npdn );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): "
@ -450,7 +453,7 @@ modrdn_return:;
} }
} }
if ( new_pe_id.eid_dn.bv_val ) { if ( !BER_BVISNULL( &new_pe_id.eid_ndn ) ) {
(void)backsql_free_entryID( &new_pe_id, 0 ); (void)backsql_free_entryID( &new_pe_id, 0 );
} }

View File

@ -96,13 +96,15 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
* Initializes the search structure. * Initializes the search structure.
* *
* If get_base_id != 0, the field bsi_base_id is filled * If get_base_id != 0, the field bsi_base_id is filled
* with the entryID of bsi_base_dn; it must be freed * with the entryID of bsi_base_ndn; it must be freed
* by backsql_free_entryID() when no longer required. * by backsql_free_entryID() when no longer required.
*
* NOTE: base must be normalized
*/ */
int int
backsql_init_search( backsql_init_search(
backsql_srch_info *bsi, backsql_srch_info *bsi,
struct berval *base, struct berval *nbase,
int scope, int scope,
int slimit, int slimit,
int tlimit, int tlimit,
@ -117,8 +119,9 @@ backsql_init_search(
AttributeName *p; AttributeName *p;
int rc = LDAP_SUCCESS; int rc = LDAP_SUCCESS;
bsi->bsi_base_dn = base; bsi->bsi_base_ndn = nbase;
BER_BVZERO( &bsi->bsi_base_id.eid_dn ); BER_BVZERO( &bsi->bsi_base_id.eid_dn );
BER_BVZERO( &bsi->bsi_base_id.eid_ndn );
bsi->bsi_scope = scope; bsi->bsi_scope = scope;
bsi->bsi_slimit = slimit; bsi->bsi_slimit = slimit;
bsi->bsi_tlimit = tlimit; bsi->bsi_tlimit = tlimit;
@ -187,7 +190,7 @@ backsql_init_search(
assert( op->o_bd->be_private ); assert( op->o_bd->be_private );
rc = backsql_dn2id( (backsql_info *)op->o_bd->be_private, rc = backsql_dn2id( (backsql_info *)op->o_bd->be_private,
&bsi->bsi_base_id, dbh, base ); &bsi->bsi_base_id, dbh, nbase );
} }
return ( bsi->bsi_status = rc ); return ( bsi->bsi_status = rc );
@ -1109,6 +1112,9 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
"ldap_entries.parent=?" ); "ldap_entries.parent=?" );
break; break;
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
if ( BACKSQL_CANUPPERCASE( bi ) ) { if ( BACKSQL_CANUPPERCASE( bi ) ) {
backsql_strfcat( &bsi->bsi_join_where, "bl", backsql_strfcat( &bsi->bsi_join_where, "bl",
@ -1184,11 +1190,13 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
int n_candidates = bsi->bsi_n_candidates; int n_candidates = bsi->bsi_n_candidates;
/* /*
* + 1 because we need room for '%'; this makes a subtree * + 1 because we need room for '%';
* + 1 because we need room for ',' for LDAP_SCOPE_SUBORDINATE;
* this makes a subtree
* search for a DN BACKSQL_MAX_DN_LEN long legal * search for a DN BACKSQL_MAX_DN_LEN long legal
* if it returns that DN only * if it returns that DN only
*/ */
char temp_base_dn[ BACKSQL_MAX_DN_LEN + 1 + 1 ]; char tmp_base_ndn[ BACKSQL_MAX_DN_LEN + 1 + 1 ];
bsi->bsi_status = LDAP_SUCCESS; bsi->bsi_status = LDAP_SUCCESS;
@ -1271,28 +1279,28 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
* We do not accept DNs longer than BACKSQL_MAX_DN_LEN; * We do not accept DNs longer than BACKSQL_MAX_DN_LEN;
* however this should be handled earlier * however this should be handled earlier
*/ */
if ( bsi->bsi_base_dn->bv_len > BACKSQL_MAX_DN_LEN ) { if ( bsi->bsi_base_ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
bsi->bsi_status = LDAP_OTHER; bsi->bsi_status = LDAP_OTHER;
return BACKSQL_AVL_CONTINUE; return BACKSQL_AVL_CONTINUE;
} }
AC_MEMCPY( temp_base_dn, bsi->bsi_base_dn->bv_val, AC_MEMCPY( tmp_base_ndn, bsi->bsi_base_ndn->bv_val,
bsi->bsi_base_dn->bv_len + 1 ); bsi->bsi_base_ndn->bv_len + 1 );
/* uppercase DN only if the stored DN can be uppercased /* uppercase DN only if the stored DN can be uppercased
* for comparison */ * for comparison */
if ( BACKSQL_CANUPPERCASE( bi ) ) { if ( BACKSQL_CANUPPERCASE( bi ) ) {
ldap_pvt_str2upper( temp_base_dn ); ldap_pvt_str2upper( tmp_base_ndn );
} }
Debug( LDAP_DEBUG_TRACE, "(base)dn: \"%s\"\n", Debug( LDAP_DEBUG_TRACE, "(base)dn: \"%s\"\n",
temp_base_dn, 0, 0 ); tmp_base_ndn, 0, 0 );
rc = backsql_BindParamStr( sth, 2, SQL_PARAM_INPUT, rc = backsql_BindParamStr( sth, 2, SQL_PARAM_INPUT,
temp_base_dn, BACKSQL_MAX_DN_LEN ); tmp_base_ndn, BACKSQL_MAX_DN_LEN );
if ( rc != SQL_SUCCESS ) { if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
"error binding base_dn parameter\n", 0, 0, 0 ); "error binding base_ndn parameter\n", 0, 0, 0 );
backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh,
sth, rc ); sth, rc );
bsi->bsi_status = LDAP_OTHER; bsi->bsi_status = LDAP_OTHER;
@ -1300,12 +1308,16 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
} }
break; break;
case LDAP_SCOPE_SUBTREE: { #ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_SUBTREE:
{
/* /*
* We do not accept DNs longer than BACKSQL_MAX_DN_LEN; * We do not accept DNs longer than BACKSQL_MAX_DN_LEN;
* however this should be handled earlier * however this should be handled earlier
*/ */
if ( bsi->bsi_base_dn->bv_len > BACKSQL_MAX_DN_LEN ) { if ( bsi->bsi_base_ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
bsi->bsi_status = LDAP_OTHER; bsi->bsi_status = LDAP_OTHER;
return BACKSQL_AVL_CONTINUE; return BACKSQL_AVL_CONTINUE;
} }
@ -1324,34 +1336,59 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
* If "dn_ru" is being used, do a prefix search. * If "dn_ru" is being used, do a prefix search.
*/ */
if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) { if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
temp_base_dn[ 0 ] = '\0'; tmp_base_ndn[ 0 ] = '\0';
for ( i = 0, j = bsi->bsi_base_dn->bv_len - 1;
for ( i = 0, j = bsi->bsi_base_ndn->bv_len - 1;
j >= 0; i++, j--) { j >= 0; i++, j--) {
temp_base_dn[ i ] = bsi->bsi_base_dn->bv_val[ j ]; tmp_base_ndn[ i ] = bsi->bsi_base_ndn->bv_val[ j ];
} }
temp_base_dn[ i ] = '%';
temp_base_dn[ i + 1 ] = '\0'; #ifdef LDAP_SCOPE_SUBORDINATE
if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
tmp_base_ndn[ i++ ] = ',';
}
#endif /* LDAP_SCOPE_SUBORDINATE */
tmp_base_ndn[ i ] = '%';
tmp_base_ndn[ i + 1 ] = '\0';
} else { } else {
temp_base_dn[ 0 ] = '%'; i = 0;
AC_MEMCPY( &temp_base_dn[ 1 ], bsi->bsi_base_dn->bv_val,
bsi->bsi_base_dn->bv_len + 1 ); tmp_base_ndn[ i++ ] = '%';
#ifdef LDAP_SCOPE_SUBORDINATE
if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
tmp_base_ndn[ i++ ] = ',';
}
#endif /* LDAP_SCOPE_SUBORDINATE */
AC_MEMCPY( &tmp_base_ndn[ i ], bsi->bsi_base_ndn->bv_val,
bsi->bsi_base_ndn->bv_len + 1 );
} }
/* uppercase DN only if the stored DN can be uppercased /* uppercase DN only if the stored DN can be uppercased
* for comparison */ * for comparison */
if ( BACKSQL_CANUPPERCASE( bi ) ) { if ( BACKSQL_CANUPPERCASE( bi ) ) {
ldap_pvt_str2upper( temp_base_dn ); ldap_pvt_str2upper( tmp_base_ndn );
} }
Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n", temp_base_dn, #ifdef LDAP_SCOPE_SUBORDINATE
0, 0 ); if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
Debug( LDAP_DEBUG_TRACE, "(children)dn: \"%s\"\n",
tmp_base_ndn, 0, 0 );
} else
#endif /* LDAP_SCOPE_SUBORDINATE */
{
Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n",
tmp_base_ndn, 0, 0 );
}
rc = backsql_BindParamStr( sth, 2, SQL_PARAM_INPUT, rc = backsql_BindParamStr( sth, 2, SQL_PARAM_INPUT,
temp_base_dn, BACKSQL_MAX_DN_LEN ); tmp_base_ndn, BACKSQL_MAX_DN_LEN );
if ( rc != SQL_SUCCESS ) { if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
"error binding base_dn parameter (2)\n", "error binding base_ndn parameter (2)\n",
0, 0, 0 ); 0, 0, 0 );
backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh,
sth, rc ); sth, rc );
@ -1362,7 +1399,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
} }
case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_ONELEVEL:
assert( !BER_BVISNULL( &bsi->bsi_base_id.eid_dn ) ); assert( !BER_BVISNULL( &bsi->bsi_base_id.eid_ndn ) );
#ifdef BACKSQL_ARBITRARY_KEY #ifdef BACKSQL_ARBITRARY_KEY
Debug( LDAP_DEBUG_TRACE, "(one)id: \"%s\"\n", Debug( LDAP_DEBUG_TRACE, "(one)id: \"%s\"\n",
@ -1395,7 +1432,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
backsql_BindRowAsStrings( sth, &row ); backsql_BindRowAsStrings( sth, &row );
rc = SQLFetch( sth ); rc = SQLFetch( sth );
for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) { for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
struct berval dn, ndn; struct berval dn, pdn, ndn;
backsql_entryID *c_id = NULL; backsql_entryID *c_id = NULL;
int ret; int ret;
@ -1405,7 +1442,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
continue; continue;
} }
ret = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ); ret = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
if ( dn.bv_val != row.cols[ 3 ] ) { if ( dn.bv_val != row.cols[ 3 ] ) {
free( dn.bv_val ); free( dn.bv_val );
} }
@ -1414,7 +1451,8 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
continue; continue;
} }
if ( bi->sql_baseObject && bvmatch( &ndn, &bi->sql_baseObject->e_nname ) ) { if ( bi->sql_baseObject && dn_match( &ndn, &bi->sql_baseObject->e_nname ) ) {
free( pdn.bv_val );
free( ndn.bv_val ); free( ndn.bv_val );
continue; continue;
} }
@ -1430,11 +1468,8 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
#endif /* ! BACKSQL_ARBITRARY_KEY */ #endif /* ! BACKSQL_ARBITRARY_KEY */
c_id->eid_oc_id = bsi->bsi_oc->bom_id; c_id->eid_oc_id = bsi->bsi_oc->bom_id;
if ( ndn.bv_val == row.cols[ 3 ] ) { c_id->eid_dn = pdn;
ber_dupbv( &c_id->eid_dn, &ndn ); c_id->eid_ndn = ndn;
} else {
c_id->eid_dn = ndn;
}
/* append at end of list ... */ /* append at end of list ... */
c_id->eid_next = NULL; c_id->eid_next = NULL;
@ -1478,7 +1513,7 @@ backsql_search( Operation *op, SlapReply *rs )
time_t stoptime = 0; time_t stoptime = 0;
backsql_srch_info bsi; backsql_srch_info bsi;
backsql_entryID *eid = NULL; backsql_entryID *eid = NULL;
struct berval base; struct berval nbase = BER_BVNULL;
manageDSAit = get_manageDSAit( op ); manageDSAit = get_manageDSAit( op );
@ -1521,19 +1556,19 @@ backsql_search( Operation *op, SlapReply *rs )
/* compute it anyway; root does not use it */ /* compute it anyway; root does not use it */
stoptime = op->o_time + op->ors_tlimit; stoptime = op->o_time + op->ors_tlimit;
base = op->o_req_ndn; nbase = op->o_req_ndn;
if ( backsql_api_dn2odbc( op, rs, &base ) ) { if ( backsql_api_dn2odbc( op, rs, &nbase ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_search(): " Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
"backsql_api_dn2odbc failed\n", "backsql_api_dn2odbc failed\n",
0, 0, 0 ); 0, 0, 0 );
rs->sr_err = LDAP_OTHER; rs->sr_err = LDAP_OTHER;
rs->sr_text = "SQL-backend error"; rs->sr_text = "SQL-backend error";
send_ldap_result( op, rs ); send_ldap_result( op, rs );
return 1; goto done;
} }
/* init search */ /* init search */
rs->sr_err = backsql_init_search( &bsi, &base, rs->sr_err = backsql_init_search( &bsi, &nbase,
op->ors_scope, op->ors_scope,
op->ors_slimit, op->ors_tlimit, op->ors_slimit, op->ors_tlimit,
stoptime, op->ors_filter, stoptime, op->ors_filter,
@ -1654,7 +1689,7 @@ backsql_search( Operation *op, SlapReply *rs )
switch ( op->ors_scope ) { switch ( op->ors_scope ) {
case LDAP_SCOPE_BASE: case LDAP_SCOPE_BASE:
case BACKSQL_SCOPE_BASE_LIKE: case BACKSQL_SCOPE_BASE_LIKE:
if ( !bvmatch( &e->e_nname, &op->o_req_ndn ) ) { if ( !dn_match( &e->e_nname, &op->o_req_ndn ) ) {
goto next_entry; goto next_entry;
} }
break; break;
@ -1662,6 +1697,7 @@ backsql_search( Operation *op, SlapReply *rs )
case LDAP_SCOPE_ONE: case LDAP_SCOPE_ONE:
{ {
struct berval rdn = user_entry.e_nname; struct berval rdn = user_entry.e_nname;
rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," ); rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," );
if ( !dnIsOneLevelRDN( &rdn ) ) { if ( !dnIsOneLevelRDN( &rdn ) ) {
goto next_entry; goto next_entry;
@ -1669,7 +1705,17 @@ backsql_search( Operation *op, SlapReply *rs )
/* fall thru */ /* fall thru */
} }
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
/* discard the baseObject entry */
if ( dn_match( &e->e_nname, &op->o_req_ndn ) ) {
goto next_entry;
}
/* FALLTHRU */
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
/* FIXME: this should never fail... */
if ( !dnIsSuffix( &e->e_nname, &op->o_req_ndn ) ) { if ( !dnIsSuffix( &e->e_nname, &op->o_req_ndn ) ) {
goto next_entry; goto next_entry;
} }
@ -1829,7 +1875,7 @@ end_of_search:;
} }
done:; done:;
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) { if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
(void)backsql_free_entryID( &bsi.bsi_base_id, 0 ); (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
} }
@ -1837,8 +1883,16 @@ done:;
ch_free( bsi.bsi_attrs ); ch_free( bsi.bsi_attrs );
} }
if ( base.bv_val != op->o_req_ndn.bv_val ) { if ( !BER_BVISNULL( &nbase )
ch_free( base.bv_val ); && nbase.bv_val != op->o_req_ndn.bv_val )
{
ch_free( nbase.bv_val );
}
/* restore scope ... FIXME: this should be done before ANY
* frontend call that uses op */
if ( op->ors_scope == BACKSQL_SCOPE_BASE_LIKE ) {
op->ors_scope = LDAP_SCOPE_BASE;
} }
Debug( LDAP_DEBUG_TRACE, "<==backsql_search()\n", 0, 0, 0 ); Debug( LDAP_DEBUG_TRACE, "<==backsql_search()\n", 0, 0, 0 );

View File

@ -56,7 +56,7 @@ char backsql_def_delreferrals_query[] = "DELETE FROM ldap_referrals "
"WHERE entry_id=?"; "WHERE entry_id=?";
char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)"; char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)";
char backsql_def_upper_subtree_cond[] = "(ldap_entries.dn) LIKE CONCAT('%',?)"; char backsql_def_upper_subtree_cond[] = "(ldap_entries.dn) LIKE CONCAT('%',?)";
char backsql_id_query[] = "SELECT id,keyval,oc_map_id FROM ldap_entries WHERE "; char backsql_id_query[] = "SELECT id,keyval,oc_map_id,dn FROM ldap_entries WHERE ";
/* better ?||? or cast(?||? as varchar) */ /* better ?||? or cast(?||? as varchar) */
char backsql_def_concat_func[] = "CONCAT(?,?)"; char backsql_def_concat_func[] = "CONCAT(?,?)";