From: Pierangelo Masarati Date: Sat, 10 Apr 2004 09:33:55 +0000 (+0000) Subject: Added provisions for a layer between the backend and the ODBC X-Git-Tag: OPENLDAP_REL_ENG_2_2_BP~51 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=b703cfb008d2d38502ebd8ec306aaaf4ccc1cf06;p=openldap Added provisions for a layer between the backend and the ODBC for further mucking with data. This can be of use in ill situations where not all the required massaging can be done on data with SQL by means of stored procedures, but overlays are called too early and cannot be used to make data non LDAP compliant. - only support for bidirectional DN mucking is provided right now - support for other values mucking is planned - write is not completely tested yet - the API could change quite often; don't rely too much on it other cleanup has been added. --- diff --git a/servers/slapd/back-sql/Makefile.in b/servers/slapd/back-sql/Makefile.in index 4e4f8ba28d..fe32d8bd34 100644 --- a/servers/slapd/back-sql/Makefile.in +++ b/servers/slapd/back-sql/Makefile.in @@ -15,10 +15,10 @@ SRCS = init.c config.c search.c bind.c compare.c operational.c \ entry-id.c schema-map.c sql-wrap.c modify.c util.c \ - add.c delete.c modrdn.c + add.c delete.c modrdn.c api.c OBJS = init.lo config.lo search.lo bind.lo compare.lo operational.lo \ entry-id.lo schema-map.lo sql-wrap.lo modify.lo util.lo \ - add.lo delete.lo modrdn.lo + add.lo delete.lo modrdn.lo api.lo LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index 6f00d487f0..f09cdcd4d3 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -507,7 +507,7 @@ backsql_add( Operation *op, SlapReply *rs ) RETCODE rc; backsql_oc_map_rec *oc = NULL; backsql_at_map_rec *at_rec = NULL; - backsql_entryID e_id, parent_id; + backsql_entryID parent_id = BACKSQL_ENTRYID_INIT; Entry p; Attribute *at; struct berval *at_val; @@ -516,6 +516,7 @@ backsql_add( Operation *op, SlapReply *rs ) SQLUSMALLINT pno, po; /* procedure return code */ int prc; + struct berval realdn, realpdn; Debug( LDAP_DEBUG_TRACE, "==>backsql_add(): adding entry \"%s\"\n", op->oq_add.rs_e->e_name.bv_val, 0, 0 ); @@ -588,7 +589,17 @@ backsql_add( Operation *op, SlapReply *rs ) /* * Check if entry exists */ - rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->oq_add.rs_e->e_name ); + realdn = op->oq_add.rs_e->e_name; + if ( backsql_api_dn2odbc( op, rs, &realdn ) ) { + Debug( LDAP_DEBUG_TRACE, "backsql_search(): " + "backsql_api_dn2odbc failed\n", + 0, 0, 0 ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "SQL-backend error"; + goto done; + } + + rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realdn ); if ( rs->sr_err == LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(): " "entry \"%s\" exists\n", @@ -601,7 +612,17 @@ backsql_add( Operation *op, SlapReply *rs ) * Check if parent exists */ dnParent( &op->oq_add.rs_e->e_name, &pdn ); - rs->sr_err = backsql_dn2id( bi, &parent_id, dbh, &pdn ); + realpdn = pdn; + if ( backsql_api_dn2odbc( op, rs, &realpdn ) ) { + Debug( LDAP_DEBUG_TRACE, "backsql_search(): " + "backsql_api_dn2odbc failed\n", + 0, 0, 0 ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "SQL-backend error"; + goto done; + } + + rs->sr_err = backsql_dn2id( bi, &parent_id, dbh, &realpdn ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(): " "could not lookup parent entry for new record \"%s\"\n", @@ -618,13 +639,27 @@ backsql_add( Operation *op, SlapReply *rs ) 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 */ - rs->sr_err = backsql_dn2id( bi, &parent_id, dbh, &pdn ); + realpdn = pdn; + if ( backsql_api_dn2odbc( op, rs, &realpdn ) ) { + Debug( LDAP_DEBUG_TRACE, "backsql_add(): " + "backsql_api_dn2odbc failed\n", + 0, 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 ) { @@ -998,6 +1033,16 @@ 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 ) { + ch_free( realdn.bv_val ); + } + if ( realpdn.bv_val != pdn.bv_val ) { + ch_free( realpdn.bv_val ); + } + if ( parent_id.eid_dn.bv_val != NULL ) { + backsql_free_entryID( &parent_id, 0 ); + } + Debug( LDAP_DEBUG_TRACE, "<==backsql_add(): %d%s%s\n", rs->sr_err, rs->sr_text ? ": " : "", diff --git a/servers/slapd/back-sql/api.c b/servers/slapd/back-sql/api.c new file mode 100644 index 0000000000..431a94495a --- /dev/null +++ b/servers/slapd/back-sql/api.c @@ -0,0 +1,146 @@ +/* This work is part of OpenLDAP Software . + * + * Copyright 1999-2004 The OpenLDAP Foundation. + * Portions Copyright 1999 Dmitry Kovalev. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Dmitry Kovalev for inclusion + * by OpenLDAP Software. + */ + +#include "portable.h" + +#ifdef SLAPD_SQL + +#include +#include +#include "ac/string.h" + +#include "slap.h" +#include "lber_pvt.h" +#include "ldap_pvt.h" +#include "proto-sql.h" + +static backsql_api *backsqlapi; + +int +backsql_api_config( backsql_info *si, const char *name ) +{ + backsql_api *ba; + + assert( si ); + assert( name ); + + for ( ba = backsqlapi; ba; ba = ba->ba_next ) { + if ( strcasecmp( name, ba->ba_name ) == 0 ) { + backsql_api *ba2; + + ba2 = ch_malloc( sizeof( backsql_api ) ); + *ba2 = *ba; + ba2->ba_next = si->si_api; + si->si_api = ba2; + return 0; + } + } + + return 1; +} + +int +backsql_api_register( backsql_api *ba ) +{ + backsql_api *ba2; + + assert( ba ); + + if ( ba->ba_name == NULL ) { + fprintf( stderr, "API module has no name\n" ); + exit(EXIT_FAILURE); + } + + for ( ba2 = backsqlapi; ba2; ba2 = ba2->ba_next ) { + if ( strcasecmp( ba->ba_name, ba2->ba_name ) == 0 ) { + fprintf( stderr, "API module \"%s\" already defined\n", ba->ba_name ); + exit(EXIT_FAILURE); + } + } + + ba->ba_next = backsqlapi; + backsqlapi = ba; + + return 0; +} + +int +backsql_api_dn2odbc( Operation *op, SlapReply *rs, struct berval *dn ) +{ + backsql_info *si = (backsql_info *)op->o_bd->be_private; + backsql_api *ba; + int rc; + struct berval bv; + + ba = si->si_api; + + if ( ba == NULL ) { + return 0; + } + + ber_dupbv( &bv, dn ); + + for ( ; ba; ba = ba->ba_next ) { + if ( ba->ba_dn2odbc ) { + rc = ( *ba->ba_dn2odbc )( op, rs, &bv ); + + if ( rc ) { + return rc; + } + } + } + + *dn = bv; + + return 0; +} + +int +backsql_api_odbc2dn( Operation *op, SlapReply *rs, struct berval *dn ) +{ + backsql_info *si = (backsql_info *)op->o_bd->be_private; + backsql_api *ba; + int rc; + struct berval bv; + + ba = si->si_api; + + if ( ba == NULL ) { + return 0; + } + + ber_dupbv( &bv, dn ); + + for ( ; ba; ba = ba->ba_next ) { + if ( ba->ba_dn2odbc ) { + rc = ( *ba->ba_odbc2dn )( op, rs, &bv ); + + if ( rc ) { + return rc; + } + } + } + + *dn = bv; + + return 0; +} + +#endif /* SLAPD_SQL */ + diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index eb513f0043..5ec834f695 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -96,7 +96,17 @@ /* * define to enable varchars as unique keys in user tables */ -#undef BACKSQL_ARBITRARY_KEY +#define BACKSQL_ARBITRARY_KEY + +/* + * API + */ +typedef struct backsql_api { + char *ba_name; + int (*ba_dn2odbc)( Operation *op, SlapReply *rs, struct berval *dn ); + int (*ba_odbc2dn)( Operation *op, SlapReply *rs, struct berval *dn ); + struct backsql_api *ba_next; +} backsql_api; /* * Entry ID structure @@ -122,6 +132,12 @@ typedef struct backsql_entryID { struct backsql_entryID *eid_next; } backsql_entryID; +#ifdef BACKSQL_ARBITRARY_KEY +#define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, BER_BVNULL, NULL } +#else /* ! BACKSQL_ARBITRARY_KEY */ +#define BACKSQL_ENTRYID_INIT { 0, 0, 0, BER_BVNULL, NULL } +#endif /* BACKSQL_ARBITRARY_KEY */ + /* * "structural" objectClass mapping structure */ @@ -219,6 +235,7 @@ typedef struct berbuf { typedef struct backsql_srch_info { Operation *bsi_op; + SlapReply *bsi_rs; int bsi_flags; #define BSQL_SF_ALL_OPER 0x0001 @@ -226,6 +243,7 @@ typedef struct backsql_srch_info { struct berval *bsi_base_dn; int bsi_scope; +#define BACKSQL_SCOPE_BASE_LIKE ( LDAP_SCOPE_BASE | 0x1000 ) Filter *bsi_filter; int bsi_slimit, bsi_tlimit; @@ -311,6 +329,8 @@ typedef struct { ldap_pvt_thread_mutex_t dbconn_mutex; ldap_pvt_thread_mutex_t schema_mutex; SQLHENV db_env; + + backsql_api *si_api; } backsql_info; #define BACKSQL_SUCCESS( rc ) \ diff --git a/servers/slapd/back-sql/bind.c b/servers/slapd/back-sql/bind.c index 82da5b9be2..21906b22f4 100644 --- a/servers/slapd/back-sql/bind.c +++ b/servers/slapd/back-sql/bind.c @@ -32,7 +32,7 @@ int backsql_bind( Operation *op, SlapReply *rs ) { backsql_info *bi = (backsql_info*)op->o_bd->be_private; - backsql_entryID user_id; + backsql_entryID user_id = BACKSQL_ENTRYID_INIT; SQLHDBC dbh; AttributeDescription *password = slap_schema.si_ad_userPassword; Entry *e, user_entry; @@ -40,6 +40,7 @@ backsql_bind( Operation *op, SlapReply *rs ) backsql_srch_info bsi; AttributeName anlist[2]; int rc; + struct berval dn; Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 ); @@ -74,7 +75,17 @@ backsql_bind( Operation *op, SlapReply *rs ) return 1; } - rc = backsql_dn2id( bi, &user_id, dbh, &op->o_req_ndn ); + dn = op->o_req_dn; + if ( backsql_api_dn2odbc( op, rs, &dn ) ) { + Debug( LDAP_DEBUG_TRACE, "backsql_search(): " + "backsql_api_dn2odbc failed\n", + 0, 0, 0 ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "SQL-backend error"; + goto error_return; + } + + rc = backsql_dn2id( bi, &user_id, dbh, &dn ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_bind(): " "could not retrieve bind dn id - no such entry\n", @@ -87,35 +98,42 @@ backsql_bind( Operation *op, SlapReply *rs ) anlist[0].an_name = password->ad_cname; anlist[0].an_desc = password; anlist[1].an_name.bv_val = NULL; - backsql_init_search( &bsi, &op->o_req_ndn, LDAP_SCOPE_BASE, - -1, -1, -1, NULL, dbh, op, anlist ); + + backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE, + -1, -1, -1, NULL, dbh, op, rs, anlist ); e = backsql_id2entry( &bsi, &user_entry, &user_id ); if ( e == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_bind(): " "error in backsql_id2entry() - auth failed\n", 0, 0, 0 ); rs->sr_err = LDAP_OTHER; - send_ldap_result( op, rs ); - return 1; + goto error_return; } if ( ! access_allowed( op, e, password, NULL, ACL_AUTH, NULL ) ) { rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - send_ldap_result( op, rs ); - return 1; + goto error_return; } if ( ( a = attr_find( e->e_attrs, password ) ) == NULL ) { rs->sr_err = LDAP_INAPPROPRIATE_AUTH; - send_ldap_result( op, rs ); - return 1; + goto error_return; } if ( slap_passwd_check( op->o_conn, a, &op->oq_bind.rb_cred, &rs->sr_text ) != 0 ) { rs->sr_err = LDAP_INVALID_CREDENTIALS; + goto error_return; + } + +error_return:; + if ( rs->sr_err ) { send_ldap_result( op, rs ); return 1; } + + if ( dn.bv_val != op->o_req_dn.bv_val ) { + ch_free( dn.bv_val ); + } Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0); return 0; diff --git a/servers/slapd/back-sql/compare.c b/servers/slapd/back-sql/compare.c index 43ebc9c7b9..3526389a42 100644 --- a/servers/slapd/back-sql/compare.c +++ b/servers/slapd/back-sql/compare.c @@ -32,13 +32,14 @@ int backsql_compare( Operation *op, SlapReply *rs ) { backsql_info *bi = (backsql_info*)op->o_bd->be_private; - backsql_entryID user_id; + backsql_entryID user_id = BACKSQL_ENTRYID_INIT; SQLHDBC dbh; Entry *e = NULL, user_entry; Attribute *a = NULL, *a_op = NULL; backsql_srch_info bsi; int rc; AttributeName anlist[2]; + struct berval dn; user_entry.e_name.bv_val = NULL; user_entry.e_name.bv_len = 0; @@ -59,7 +60,17 @@ backsql_compare( Operation *op, SlapReply *rs ) goto return_results; } - rc = backsql_dn2id( bi, &user_id, dbh, &op->o_req_ndn ); + dn = op->o_req_dn; + if ( backsql_api_dn2odbc( op, rs, &dn ) ) { + Debug( LDAP_DEBUG_TRACE, "backsql_search(): " + "backsql_api_dn2odbc failed\n", + 0, 0, 0 ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "SQL-backend error"; + 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", @@ -106,8 +117,8 @@ backsql_compare( Operation *op, SlapReply *rs ) e = &user_entry; } else { - backsql_init_search( &bsi, &op->o_req_ndn, LDAP_SCOPE_BASE, - -1, -1, -1, NULL, dbh, op, anlist ); + backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE, + -1, -1, -1, NULL, dbh, op, rs, anlist ); e = backsql_id2entry( &bsi, &user_entry, &user_id ); if ( e == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_compare(): " @@ -146,6 +157,10 @@ backsql_compare( Operation *op, SlapReply *rs ) return_results:; send_ldap_result( op, rs ); + if ( dn.bv_val != op->o_req_dn.bv_val ) { + ch_free( dn.bv_val ); + } + if ( e != NULL ) { if ( e->e_name.bv_val != NULL ) { free( e->e_name.bv_val ); diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index 10f934a321..bce6198045 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -334,6 +334,15 @@ backsql_db_config( "fail_if_no_mapping=%s\n", BACKSQL_FAIL_IF_NO_MAPPING( si ) ? "yes" : "no", 0, 0 ); + } else if ( !strcasecmp( argv[ 0 ], "sqllayer") ) { + if ( backsql_api_config( si, argv[ 1 ] ) ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "unable to load sqllayer \"%s\"\n", + fname, lineno, argv[ 1 ] ); + return 1; + } + } else { return SLAP_CONF_UNKNOWN; } diff --git a/servers/slapd/back-sql/delete.c b/servers/slapd/back-sql/delete.c index ecb404ecf8..3f4cfb99a4 100644 --- a/servers/slapd/back-sql/delete.c +++ b/servers/slapd/back-sql/delete.c @@ -38,7 +38,7 @@ backsql_delete( Operation *op, SlapReply *rs ) SQLHSTMT sth; RETCODE rc; backsql_oc_map_rec *oc = NULL; - backsql_entryID e_id; + backsql_entryID e_id = BACKSQL_ENTRYID_INIT; Entry e; /* first parameter no */ SQLUSMALLINT pno; diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index 931b4f571c..051e4f12ad 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -75,13 +75,18 @@ backsql_dn2id( /* TimesTen */ char upperdn[ BACKSQL_MAX_DN_LEN + 1 ]; - char *toBind; + struct berval toBind; int i, j; - Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): dn='%s'\n", - dn->bv_val, 0, 0 ); + /* + * NOTE: id can be NULL; in this case, the function + * simply checks whether the DN can be successfully + * turned into an ID, returning LDAP_SUCCESS for + * positive cases, or the most appropriate error + */ - assert( id ); + Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): dn=\"%s\"%s\n", + dn->bv_val, id == NULL ? " (no ID)" : "", 0 ); if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) { Debug( LDAP_DEBUG_TRACE, @@ -92,7 +97,7 @@ backsql_dn2id( } /* begin TimesTen */ - Debug(LDAP_DEBUG_TRACE, "id_query '%s'\n", bi->id_query, 0, 0); + Debug(LDAP_DEBUG_TRACE, "id_query \"%s\"\n", bi->id_query, 0, 0); assert( bi->id_query ); rc = backsql_Prepare( dbh, &sth, bi->id_query, 0 ); if ( rc != SQL_SUCCESS ) { @@ -116,29 +121,30 @@ backsql_dn2id( upperdn[ i ] = '\0'; 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 ); - toBind = upperdn; + ber_str2bv( upperdn, 0, 0, &toBind ); + } else { if ( BACKSQL_USE_REVERSE_DN( bi ) ) { AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 ); ldap_pvt_str2upper( upperdn ); Debug( LDAP_DEBUG_TRACE, - "==>backsql_dn2id(): upperdn='%s'\n", + "==>backsql_dn2id(): upperdn=\"%s\"\n", upperdn, 0, 0 ); - toBind = upperdn; + ber_str2bv( upperdn, 0, 0, &toBind ); } else { - toBind = dn->bv_val; + toBind = *dn; } } - rc = backsql_BindParamStr( sth, 1, toBind, BACKSQL_MAX_DN_LEN ); + rc = backsql_BindParamStr( sth, 1, toBind.bv_val, BACKSQL_MAX_DN_LEN ); if ( rc != SQL_SUCCESS) { /* end TimesTen */ Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): " "error binding dn=\"%s\" parameter:\n", - toBind, 0, 0 ); + toBind.bv_val, 0, 0 ); backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return LDAP_OTHER; @@ -148,7 +154,7 @@ backsql_dn2id( if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): " "error executing query (\"%s\", \"%s\"):\n", - bi->id_query, toBind, 0 ); + bi->id_query, toBind.bv_val, 0 ); backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return LDAP_OTHER; @@ -157,37 +163,32 @@ backsql_dn2id( backsql_BindRowAsStrings( sth, &row ); rc = SQLFetch( sth ); if ( BACKSQL_SUCCESS( rc ) ) { + res = LDAP_SUCCESS; + Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): id=%s keyval=%s oc_id=%s\n", + row.cols[ 0 ], row.cols[ 1 ], row.cols[ 2 ] ); + + if ( id != NULL ) { #ifdef BACKSQL_ARBITRARY_KEY - ber_str2bv( row.cols[ 0 ], 0, 1, &id->eid_id ); - ber_str2bv( row.cols[ 1 ], 0, 1, &id->eid_keyval ); + ber_str2bv( row.cols[ 0 ], 0, 1, &id->eid_id ); + ber_str2bv( row.cols[ 1 ], 0, 1, &id->eid_keyval ); #else /* ! BACKSQL_ARBITRARY_KEY */ - id->eid_id = strtol( row.cols[ 0 ], NULL, 0 ); - id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 ); + id->eid_id = strtol( row.cols[ 0 ], NULL, 0 ); + id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 ); #endif /* ! BACKSQL_ARBITRARY_KEY */ - id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 ); - ber_dupbv( &id->eid_dn, dn ); - id->eid_next = NULL; + id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 ); - res = LDAP_SUCCESS; + ber_dupbv( &id->eid_dn, dn ); + id->eid_next = NULL; + } } else { res = LDAP_NO_SUCH_OBJECT; + Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): no match\n", + 0, 0, 0 ); } backsql_FreeRow( &row ); SQLFreeStmt( sth, SQL_DROP ); - if ( res == LDAP_SUCCESS ) { -#ifdef BACKSQL_ARBITRARY_KEY - Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): id=%s\n", - id->eid_id.bv_val, 0, 0 ); -#else /* ! BACKSQL_ARBITRARY_KEY */ - Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): id=%ld\n", - id->eid_id, 0, 0 ); -#endif /* !BACKSQL_ARBITRARY_KEY */ - } else { - Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): no match\n", - 0, 0, 0 ); - } return res; } @@ -203,7 +204,7 @@ backsql_count_children( RETCODE rc; int res = LDAP_SUCCESS; - Debug( LDAP_DEBUG_TRACE, "==>backsql_count_children(): dn='%s'\n", + Debug( LDAP_DEBUG_TRACE, "==>backsql_count_children(): dn=\"%s\"\n", dn->bv_val, 0, 0 ); if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) { @@ -215,7 +216,7 @@ backsql_count_children( } /* begin TimesTen */ - Debug(LDAP_DEBUG_TRACE, "children id query '%s'\n", + Debug(LDAP_DEBUG_TRACE, "children id query \"%s\"\n", bi->has_children_query, 0, 0); assert( bi->has_children_query ); rc = backsql_Prepare( dbh, &sth, bi->has_children_query, 0 ); @@ -310,12 +311,12 @@ backsql_get_attr_vals( void *v_at, void *v_bsi ) #ifdef BACKSQL_ARBITRARY_KEY Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): " - "oc='%s' attr='%s' keyval=%s\n", + "oc=\"%s\" attr=\"%s\" keyval=%s\n", BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val, bsi->bsi_c_eid->eid_keyval.bv_val ); #else /* ! BACKSQL_ARBITRARY_KEY */ Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): " - "oc='%s' attr='%s' keyval=%ld\n", + "oc=\"%s\" attr=\"%s\" keyval=%ld\n", BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val, bsi->bsi_c_eid->eid_keyval ); #endif /* ! BACKSQL_ARBITRARY_KEY */ @@ -343,7 +344,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi ) rc = SQLExecute( sth ); if ( ! BACKSQL_SUCCESS( rc ) ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): " - "error executing attribute query '%s'\n", + "error executing attribute query \"%s\"\n", at->bam_query, 0, 0 ); backsql_PrintErrors( bi->db_env, bsi->bsi_dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); @@ -377,7 +378,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi ) (int)row.col_prec[ i ], 0, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "NULL value " - "in this row for attribute '%s'\n", + "in this row for attribute \"%s\"\n", row.col_names[ i ].bv_val, 0, 0 ); #endif /* BACKSQL_TRACE */ } @@ -454,8 +455,8 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid ) rc = backsql_supad2at( bsi->bsi_oc, attr->an_desc, &vat ); if ( rc != 0 || vat == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): " - "attribute '%s' is not defined " - "for objectlass '%s'\n", + "attribute \"%s\" is not defined " + "for objectlass \"%s\"\n", attr->an_name.bv_val, BACKSQL_OC_NAME( bsi->bsi_oc ), 0 ); continue; diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index 30c2f860df..b188a679df 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -46,7 +46,7 @@ init_module( return 0; } -#endif /* SLAPD_SQL == SLAPD_MOD_DYNAMIC*/ +#endif /* SLAPD_SQL == SLAPD_MOD_DYNAMIC */ int sql_back_initialize( @@ -94,7 +94,7 @@ sql_back_initialize( bi->bi_connection_init = 0; bi->bi_connection_destroy = backsql_connection_destroy; - + Debug( LDAP_DEBUG_TRACE,"<==backsql_initialize()\n", 0, 0, 0 ); return 0; } @@ -195,7 +195,7 @@ backsql_db_open( if ( backsql_split_pattern( backsql_def_concat_func, &si->concat_func, 2 ) ) { Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " - "unable to parse pattern '%s'", + "unable to parse pattern \"%s\"", backsql_def_concat_func, 0, 0 ); return 1; } @@ -294,7 +294,7 @@ backsql_db_open( si->subtree_cond = bb.bb_val; Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " - "setting '%s' as default\n", + "setting \"%s\" as default\n", si->subtree_cond.bv_val, 0, 0 ); } @@ -328,7 +328,7 @@ backsql_db_open( si->children_cond = bb.bb_val; Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " - "setting '%s' as default\n", + "setting \"%s\" as default\n", si->children_cond.bv_val, 0, 0 ); } @@ -346,7 +346,7 @@ backsql_db_open( "(use \"oc_query\" directive in slapd.conf)\n", 0, 0, 0 ); Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " - "setting '%s' by default\n", si->oc_query, 0, 0 ); + "setting \"%s\" by default\n", si->oc_query, 0, 0 ); } if ( si->at_query == NULL ) { @@ -355,7 +355,7 @@ backsql_db_open( "(use \"at_query\" directive in slapd.conf)\n", 0, 0, 0 ); Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): " - "setting '%s' by default\n", + "setting \"%s\" by default\n", backsql_def_at_query, 0, 0 ); si->at_query = ch_strdup( backsql_def_at_query ); } @@ -366,7 +366,7 @@ backsql_db_open( "(use \"insentry_query\" directive in slapd.conf)\n", 0, 0, 0 ); Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): " - "setting '%s' by default\n", + "setting \"%s\" by default\n", backsql_def_insentry_query, 0, 0 ); si->insentry_query = ch_strdup( backsql_def_insentry_query ); } @@ -377,7 +377,7 @@ backsql_db_open( "(use \"delentry_query\" directive in slapd.conf)\n", 0, 0, 0 ); Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " - "setting '%s' by default\n", + "setting \"%s\" by default\n", backsql_def_delentry_query, 0, 0 ); si->delentry_query = ch_strdup( backsql_def_delentry_query ); } diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index 2c392a3650..1a528091d8 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -36,7 +36,7 @@ backsql_modify( Operation *op, SlapReply *rs ) backsql_info *bi = (backsql_info*)op->o_bd->be_private; SQLHDBC dbh; backsql_oc_map_rec *oc = NULL; - backsql_entryID e_id; + backsql_entryID e_id = BACKSQL_ENTRYID_INIT; Entry e; /* diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index bf58cddead..ee05c7d8f1 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -37,7 +37,9 @@ backsql_modrdn( Operation *op, SlapReply *rs ) SQLHDBC dbh; SQLHSTMT sth; RETCODE rc; - backsql_entryID e_id, pe_id, new_pid; + backsql_entryID e_id = BACKSQL_ENTRYID_INIT, + pe_id = BACKSQL_ENTRYID_INIT, + new_pid = BACKSQL_ENTRYID_INIT; backsql_oc_map_rec *oc = NULL; struct berval p_dn, p_ndn, *new_pdn = NULL, *new_npdn = NULL, @@ -205,6 +207,8 @@ 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 ); + rs->sr_err = backsql_dn2id( bi, &new_pid, dbh, new_npdn ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " @@ -373,7 +377,7 @@ modrdn_return: if ( old_rdn != NULL ) { ldap_rdnfree( old_rdn ); } - if( mod != NULL ) { + if ( mod != NULL ) { Modifications *tmp; for (; mod; mod=tmp ) { tmp = mod->sml_next; @@ -381,6 +385,10 @@ modrdn_return: } } + if ( new_pid.eid_dn.bv_val ) { + backsql_free_entryID( &pe_id, 0 ); + } + send_ldap_result( op, rs ); Debug( LDAP_DEBUG_TRACE, "<==backsql_modrdn()\n", 0, 0, 0 ); diff --git a/servers/slapd/back-sql/operational.c b/servers/slapd/back-sql/operational.c index f495d051d8..c4527d36ff 100644 --- a/servers/slapd/back-sql/operational.c +++ b/servers/slapd/back-sql/operational.c @@ -45,7 +45,7 @@ backsql_operational( Attribute **aa = a; int rc = 0; - Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry '%s'\n", + Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry \"%s\"\n", rs->sr_entry->e_nname.bv_val, 0, 0 ); diff --git a/servers/slapd/back-sql/proto-sql.h b/servers/slapd/back-sql/proto-sql.h index 19b7518887..e57e9b4d4f 100644 --- a/servers/slapd/back-sql/proto-sql.h +++ b/servers/slapd/back-sql/proto-sql.h @@ -87,6 +87,14 @@ int backsql_modify_internal( backsql_entryID *e_id, Modifications *modlist ); +/* + * api.c + */ +int backsql_api_config( backsql_info *si, const char *name ); +int backsql_api_register( backsql_api *ba ); +int backsql_api_dn2odbc( Operation *op, SlapReply *rs, struct berval *dn ); +int backsql_api_odbc2dn( Operation *op, SlapReply *rs, struct berval *dn ); + /* * entry-id.c */ @@ -138,7 +146,7 @@ int backsql_destroy_schema_map( backsql_info *si ); void 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, AttributeName *attrs ); + Operation *op, SlapReply *rs, AttributeName *attrs ); /* * sql-wrap.h diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c index 1de778c5c6..e62948adc5 100644 --- a/servers/slapd/back-sql/schema-map.c +++ b/servers/slapd/back-sql/schema-map.c @@ -241,18 +241,18 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh ) rc = backsql_Prepare( dbh, &oc_sth, si->oc_query, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): " - "error preparing oc_query: '%s'\n", + "error preparing oc_query: \"%s\"\n", si->oc_query, 0, 0 ); backsql_PrintErrors( si->db_env, dbh, oc_sth, rc ); return LDAP_OTHER; } - Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): at_query '%s'\n", + Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): at_query \"%s\"\n", si->at_query, 0, 0 ); rc = backsql_Prepare( dbh, &at_sth, si->at_query, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): " - "error preparing at_query: '%s'\n", + "error preparing at_query: \"%s\"\n", si->at_query, 0, 0 ); backsql_PrintErrors( si->db_env, dbh, at_sth, rc ); return LDAP_OTHER; @@ -287,7 +287,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh ) oc_map->bom_oc = oc_find( oc_row.cols[ 1 ] ); if ( oc_map->bom_oc == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): " - "objectClass '%s' is not defined in schema\n", + "objectClass \"%s\" is not defined in schema\n", oc_row.cols[ 1 ], 0, 0 ); return LDAP_OTHER; /* undefined objectClass ? */ } @@ -328,19 +328,19 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh ) } oc_id = oc_map->bom_id; Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): " - "objectClass '%s': keytbl='%s' keycol='%s'\n", + "objectClass \"%s\": keytbl=\"%s\" keycol=\"%s\"\n", BACKSQL_OC_NAME( oc_map ), oc_map->bom_keytbl.bv_val, oc_map->bom_keycol.bv_val ); if ( oc_map->bom_create_proc ) { - Debug( LDAP_DEBUG_TRACE, "create_proc='%s'\n", + Debug( LDAP_DEBUG_TRACE, "create_proc=\"%s\"\n", oc_map->bom_create_proc, 0, 0 ); } if ( oc_map->bom_create_keyval ) { - Debug( LDAP_DEBUG_TRACE, "create_keyval='%s'\n", + Debug( LDAP_DEBUG_TRACE, "create_keyval=\"%s\"\n", oc_map->bom_create_keyval, 0, 0 ); } if ( oc_map->bom_delete_proc ) { - Debug( LDAP_DEBUG_TRACE, "delete_proc='%s'\n", + Debug( LDAP_DEBUG_TRACE, "delete_proc=\"%s\"\n", oc_map->bom_delete_proc, 0, 0 ); } Debug( LDAP_DEBUG_TRACE, "expect_return: " @@ -369,19 +369,19 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh ) Debug( LDAP_DEBUG_TRACE, "attributeType:\n" - "\tname='%s'\n" - "\tsel_expr='%s'\n" - "\tfrom='%s'\n", + "\tname=\"%s\"\n" + "\tsel_expr=\"%s\"\n" + "\tfrom=\"%s\"\n", at_row.cols[ 0 ], at_row.cols[ 1 ], at_row.cols[ 2 ] ); Debug( LDAP_DEBUG_TRACE, - "\tjoin_where='%s'\n" - "\tadd_proc='%s'\n" - "\tdelete_proc='%s'\n", + "\tjoin_where=\"%s\"\n" + "\tadd_proc=\"%s\"\n" + "\tdelete_proc=\"%s\"\n", at_row.cols[ 3 ], at_row.cols[ 4 ], at_row.cols[ 5 ]); /* TimesTen */ - Debug( LDAP_DEBUG_TRACE, "\tsel_expr_u='%s'\n", + Debug( LDAP_DEBUG_TRACE, "\tsel_expr_u=\"%s\"\n", at_row.cols[ 8 ], 0, 0 ); at_map = (backsql_at_map_rec *)ch_calloc( 1, sizeof( backsql_at_map_rec ) ); @@ -389,7 +389,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh ) &at_map->bam_ad, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): " - "attribute '%s' for objectClass '%s' " + "attribute \"%s\" for objectClass \"%s\" " "is not defined in schema: %s\n", at_row.cols[ 0 ], BACKSQL_OC_NAME( oc_map ), text ); @@ -429,7 +429,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh ) NULL, 0 ); backsql_make_attr_query( oc_map, at_map ); Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): " - "preconstructed query '%s'\n", + "preconstructed query \"%s\"\n", at_map->bam_query, 0, 0 ); at_map->bam_next = NULL; if ( avl_insert( &oc_map->bom_attrs, at_map, backsql_cmp_attr, backsql_dup_attr ) == BACKSQL_DUPLICATE ) { @@ -469,7 +469,7 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc ) #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>backsql_oc2oc(): " - "searching for objectclass with name='%s'\n", + "searching for objectclass with name=\"%s\"\n", objclass, 0, 0 ); #endif /* BACKSQL_TRACE */ @@ -478,7 +478,7 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc ) #ifdef BACKSQL_TRACE if ( res != NULL ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): " - "found name='%s', id=%d\n", + "found name=\"%s\", id=%d\n", BACKSQL_OC_NAME( res ), res->id, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): " @@ -496,7 +496,7 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name ) #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>oc_with_name(): " - "searching for objectclass with name='%s'\n", + "searching for objectclass with name=\"%s\"\n", objclass, 0, 0 ); #endif /* BACKSQL_TRACE */ @@ -509,7 +509,7 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name ) #ifdef BACKSQL_TRACE if ( res != NULL ) { Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): " - "found name='%s', id=%d\n", + "found name=\"%s\", id=%d\n", BACKSQL_OC_NAME( res ), res->bom_id, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): " @@ -537,7 +537,7 @@ backsql_id2oc( backsql_info *si, unsigned long id ) #ifdef BACKSQL_TRACE if ( res != NULL ) { Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): " - "found name='%s', id=%d\n", + "found name=\"%s\", id=%d\n", BACKSQL_OC_NAME( res ), res->bom_id, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): " @@ -555,7 +555,7 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad ) #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>backsql_ad2at(): " - "searching for attribute '%s' for objectclass '%s'\n", + "searching for attribute \"%s\" for objectclass \"%s\"\n", attr, BACKSQL_OC_NAME( objclass ), 0 ); #endif /* BACKSQL_TRACE */ @@ -566,7 +566,7 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad ) #ifdef BACKSQL_TRACE if ( res != NULL ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): " - "found name='%s', sel_expr='%s'\n", + "found name=\"%s\", sel_expr=\"%s\"\n", res->bam_ad->ad_cname.bv_val, res->bam_sel_expr.bv_val, 0 ); } else { @@ -664,7 +664,7 @@ backsql_free_attr( void *v_at ) { backsql_at_map_rec *at = v_at; - Debug( LDAP_DEBUG_TRACE, "==>free_attr(): '%s'\n", + Debug( LDAP_DEBUG_TRACE, "==>free_attr(): \"%s\"\n", at->bam_ad->ad_cname.bv_val, 0, 0 ); ch_free( at->bam_sel_expr.bv_val ); if ( at->bam_from_tbls.bv_val != NULL ) { @@ -702,7 +702,7 @@ backsql_free_oc( void *v_oc ) { backsql_oc_map_rec *oc = v_oc; - Debug( LDAP_DEBUG_TRACE, "==>free_oc(): '%s'\n", + Debug( LDAP_DEBUG_TRACE, "==>free_oc(): \"%s\"\n", BACKSQL_OC_NAME( oc ), 0, 0 ); avl_free( oc->bom_attrs, backsql_free_attr ); ch_free( oc->bom_keytbl.bv_val ); diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 484e684084..4f91920423 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -67,7 +67,7 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad ) an = &bsi->bsi_attrs[ n_attrs ]; Debug( LDAP_DEBUG_TRACE, "==>backsql_attrlist_add(): " - "attribute '%s' is in list\n", + "attribute \"%s\" is in list\n", an->an_name.bv_val, 0, 0 ); /* * We can live with strcmp because the attribute @@ -79,7 +79,7 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad ) } Debug( LDAP_DEBUG_TRACE, "==>backsql_attrlist_add(): " - "adding '%s' to list\n", ad->ad_cname.bv_val, 0, 0 ); + "adding \"%s\" to list\n", ad->ad_cname.bv_val, 0, 0 ); an = (AttributeName *)ch_realloc( bsi->bsi_attrs, sizeof( AttributeName ) * ( n_attrs + 2 ) ); @@ -108,10 +108,11 @@ backsql_init_search( Filter *filter, SQLHDBC dbh, Operation *op, + SlapReply *rs, AttributeName *attrs ) { AttributeName *p; - + bsi->bsi_base_dn = base; bsi->bsi_scope = scope; bsi->bsi_slimit = slimit; @@ -119,6 +120,7 @@ backsql_init_search( bsi->bsi_filter = filter; bsi->bsi_dbh = dbh; bsi->bsi_op = op; + bsi->bsi_rs = rs; bsi->bsi_flags = 0; /* @@ -246,7 +248,7 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, /* * to check for matching telephone numbers - * with intermized chars, e.g. val='1234' + * with intermixed chars, e.g. val='1234' * use * * val LIKE '%1%2%3%4%' @@ -317,7 +319,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, backsql_strfcat( &bsi->bsi_flt_where, "c", '(' /* ) */ ); /* TimesTen */ - Debug( LDAP_DEBUG_TRACE, "expr: '%s%s%s'\n", at->bam_sel_expr.bv_val, + Debug( LDAP_DEBUG_TRACE, "backsql_process_sub_filter(%s):\n", + at->bam_ad->ad_cname.bv_val, 0, 0 ); + Debug(LDAP_DEBUG_TRACE, " expr: '%s%s%s'\n", at->bam_sel_expr.bv_val, at->bam_sel_expr_u.bv_val ? "' '" : "", at->bam_sel_expr_u.bv_val ? at->bam_sel_expr_u.bv_val : "" ); if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { @@ -340,6 +344,13 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, if ( f->f_sub_initial.bv_val != NULL ) { ber_len_t start; +#ifdef BACKSQL_TRACE + Debug( LDAP_DEBUG_TRACE, + "==>backsql_process_sub_filter(%s): " + "sub_initial=\"%s\"\n", at->bam_ad->ad_cname.bv_val, + f->f_sub_initial.bv_val, 0 ); +#endif /* BACKSQL_TRACE */ + start = bsi->bsi_flt_where.bb_val.bv_len; backsql_strfcat( &bsi->bsi_flt_where, "b", &f->f_sub_initial ); @@ -357,8 +368,8 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>backsql_process_sub_filter(%s): " - "sub_any='%s'\n", at->bam_ad->ad_cname.bv_val, - f->f_sub_any[ i ].bv_val, 0 ); + "sub_any[%d]=\"%s\"\n", at->bam_ad->ad_cname.bv_val, + i, f->f_sub_any[ i ].bv_val ); #endif /* BACKSQL_TRACE */ start = bsi->bsi_flt_where.bb_val.bv_len; @@ -373,16 +384,23 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } } + } - if ( f->f_sub_final.bv_val != NULL ) { - ber_len_t start; + if ( f->f_sub_final.bv_val != NULL ) { + ber_len_t start; - start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat( &bsi->bsi_flt_where, "b", - &f->f_sub_final ); - if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { - ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); - } +#ifdef BACKSQL_TRACE + Debug( LDAP_DEBUG_TRACE, + "==>backsql_process_sub_filter(%s): " + "sub_final=\"%s\"\n", at->bam_ad->ad_cname.bv_val, + f->f_sub_final.bv_val, 0 ); +#endif /* BACKSQL_TRACE */ + + start = bsi->bsi_flt_where.bb_val.bv_len; + backsql_strfcat( &bsi->bsi_flt_where, "b", + &f->f_sub_final ); + if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { + ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } } @@ -967,6 +985,19 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) } break; + case BACKSQL_SCOPE_BASE_LIKE: + if ( BACKSQL_CANUPPERCASE( bi ) ) { + backsql_strfcat( &bsi->bsi_join_where, "bl", + &bi->upper_func, + (ber_len_t)sizeof( "(ldap_entries.dn) LIKE ?" ) - 1, + "(ldap_entries.dn) LIKE ?" ); + } else { + backsql_strfcat( &bsi->bsi_join_where, "l", + (ber_len_t)sizeof( "ldap_entries.dn LIKE ?" ) - 1, + "ldap_entries.dn LIKE ?" ); + } + break; + case LDAP_SCOPE_ONELEVEL: backsql_strfcat( &bsi->bsi_join_where, "l", (ber_len_t)sizeof( "ldap_entries.parent=?" ) - 1, @@ -1041,17 +1072,23 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) struct berval query; SQLHSTMT sth; RETCODE rc; - backsql_entryID base_id, *c_id; + backsql_entryID base_id = BACKSQL_ENTRYID_INIT; int res; BACKSQL_ROW_NTS row; int i; int j; - int n_candidates = bsi->bsi_n_candidates; + /* + * + 1 because we need room for '%'; this makes a subtree + * search for a DN BACKSQL_MAX_DN_LEN long legal + * if it returns that DN only + */ + char temp_base_dn[ BACKSQL_MAX_DN_LEN + 1 + 1 ]; + bsi->bsi_status = LDAP_SUCCESS; - Debug( LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc='%s'\n", + Debug( LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc=\"%s\"\n", BACKSQL_OC_NAME( oc ), 0, 0 ); if ( bsi->bsi_n_candidates == -1 ) { @@ -1067,7 +1104,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) res = backsql_srch_query( bsi, &query ); if ( res ) { Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " - "error while constructing query for objectclass '%s'\n", + "error while constructing query for objectclass \"%s\"\n", oc->bom_oc->soc_cname.bv_val, 0, 0 ); /* * FIXME: need to separate errors from legally @@ -1092,7 +1129,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) if ( query.bv_val == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " - "could not construct query for objectclass '%s'\n", + "could not construct query for objectclass \"%s\"\n", oc->bom_oc->soc_cname.bv_val, 0, 0 ); bsi->bsi_status = LDAP_SUCCESS; return BACKSQL_CONTINUE; @@ -1122,10 +1159,29 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) switch ( bsi->bsi_scope ) { case LDAP_SCOPE_BASE: - Debug( LDAP_DEBUG_TRACE, "(base)dn: '%s'\n", - bsi->bsi_base_dn->bv_val, 0, 0 ); + case BACKSQL_SCOPE_BASE_LIKE: + /* + * We do not accept DNs longer than BACKSQL_MAX_DN_LEN; + * however this should be handled earlier + */ + if ( bsi->bsi_base_dn->bv_len > BACKSQL_MAX_DN_LEN ) { + bsi->bsi_status = LDAP_OTHER; + return BACKSQL_CONTINUE; + } + + AC_MEMCPY( temp_base_dn, bsi->bsi_base_dn->bv_val, + bsi->bsi_base_dn->bv_len + 1 ); + + /* uppercase DN only if the stored DN can be uppercased + * for comparison */ + if ( BACKSQL_CANUPPERCASE( bi ) ) { + ldap_pvt_str2upper( temp_base_dn ); + } - rc = backsql_BindParamStr( sth, 2, bsi->bsi_base_dn->bv_val, + Debug( LDAP_DEBUG_TRACE, "(base)dn: \"%s\"\n", + temp_base_dn, 0, 0 ); + + rc = backsql_BindParamStr( sth, 2, temp_base_dn, BACKSQL_MAX_DN_LEN ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " @@ -1138,20 +1194,15 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) break; case LDAP_SCOPE_SUBTREE: { - - /* - * + 1 because we need room for '%'; this makes a subtree - * search for a DN BACKSQL_MAX_DN_LEN long legal - * if it returns that DN only - */ - char temp_base_dn[ BACKSQL_MAX_DN_LEN + 1 + 1 ]; - /* * We do not accept DNs longer than BACKSQL_MAX_DN_LEN; * however this should be handled earlier */ - assert( bsi->bsi_base_dn->bv_len <= BACKSQL_MAX_DN_LEN ); - + if ( bsi->bsi_base_dn->bv_len > BACKSQL_MAX_DN_LEN ) { + bsi->bsi_status = LDAP_OTHER; + return BACKSQL_CONTINUE; + } + /* * Sets the parameters for the SQL built earlier * NOTE that all the databases could actually use @@ -1179,13 +1230,14 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) AC_MEMCPY( &temp_base_dn[ 1 ], bsi->bsi_base_dn->bv_val, bsi->bsi_base_dn->bv_len + 1 ); } + /* uppercase DN only if the stored DN can be uppercased * for comparison */ if ( BACKSQL_CANUPPERCASE( bi ) ) { ldap_pvt_str2upper( temp_base_dn ); } - Debug( LDAP_DEBUG_TRACE, "(sub)dn: '%s'\n", temp_base_dn, + Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n", temp_base_dn, 0, 0 ); rc = backsql_BindParamStr( sth, 2, temp_base_dn, @@ -1215,7 +1267,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) } #ifdef BACKSQL_ARBITRARY_KEY - Debug( LDAP_DEBUG_TRACE, "(one)id: '%s'\n", + Debug( LDAP_DEBUG_TRACE, "(one)id: \"%s\"\n", base_id.eid_id.bv_val, 0, 0 ); rc = backsql_BindParamStr( sth, 2, base_id.eid_id.bv_val, @@ -1249,6 +1301,15 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) backsql_BindRowAsStrings( sth, &row ); rc = SQLFetch( sth ); for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) { + struct berval dn; + backsql_entryID *c_id = NULL; + + ber_str2bv( row.cols[ 3 ], 0, 0, &dn ); + + if ( backsql_api_odbc2dn( bsi->bsi_op, bsi->bsi_rs, &dn ) ) { + continue; + } + c_id = (backsql_entryID *)ch_calloc( 1, sizeof( backsql_entryID ) ); #ifdef BACKSQL_ARBITRARY_KEY @@ -1259,19 +1320,25 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) c_id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 ); #endif /* ! BACKSQL_ARBITRARY_KEY */ c_id->eid_oc_id = bsi->bsi_oc->bom_id; - ber_str2bv( row.cols[ 3 ], 0, 1, &c_id->eid_dn ); + + if ( dn.bv_val == row.cols[ 3 ] ) { + ber_dupbv( &c_id->eid_dn, &dn ); + } else { + c_id->eid_dn = dn; + } + c_id->eid_next = bsi->bsi_id_list; bsi->bsi_id_list = c_id; bsi->bsi_n_candidates--; #ifdef BACKSQL_ARBITRARY_KEY Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " - "added entry id=%s, keyval=%s dn='%s'\n", + "added entry id=%s, keyval=%s dn=\"%s\"\n", c_id->eid_id.bv_val, c_id->eid_keyval.bv_val, row.cols[ 3 ] ); #else /* ! BACKSQL_ARBITRARY_KEY */ Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " - "added entry id=%ld, keyval=%ld dn='%s'\n", + "added entry id=%ld, keyval=%ld dn=\"%s\"\n", c_id->eid_id, c_id->eid_keyval, row.cols[ 3 ] ); #endif /* ! BACKSQL_ARBITRARY_KEY */ @@ -1299,11 +1366,12 @@ backsql_search( Operation *op, SlapReply *rs ) time_t stoptime = 0; backsql_srch_info srch_info; backsql_entryID *eid = NULL; + struct berval base; manageDSAit = get_manageDSAit( op ); Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): " - "base='%s', filter='%s', scope=%d,", + "base=\"%s\", filter=\"%s\", scope=%d,", op->o_req_ndn.bv_val, op->ors_filterstr.bv_val, op->ors_scope ); @@ -1341,11 +1409,22 @@ backsql_search( Operation *op, SlapReply *rs ) /* compute it anyway; root does not use it */ stoptime = op->o_time + op->ors_tlimit; - backsql_init_search( &srch_info, &op->o_req_dn, + base = op->o_req_dn; + if ( backsql_api_dn2odbc( op, rs, &base ) ) { + Debug( LDAP_DEBUG_TRACE, "backsql_search(): " + "backsql_api_dn2odbc failed\n", + 0, 0, 0 ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "SQL-backend error"; + send_ldap_result( op, rs ); + return 1; + } + + backsql_init_search( &srch_info, &base, op->ors_scope, op->ors_slimit, op->ors_tlimit, stoptime, op->ors_filter, - dbh, op, op->ors_attrs ); + dbh, op, rs, op->ors_attrs ); /* * for each objectclass we try to construct query which gets IDs @@ -1415,6 +1494,7 @@ backsql_search( Operation *op, SlapReply *rs ) if ( !manageDSAit && op->ors_scope != LDAP_SCOPE_BASE && + op->ors_scope != BACKSQL_SCOPE_BASE_LIKE && is_entry_referral( entry ) ) { BerVarray refs; struct berval matched_dn; @@ -1550,6 +1630,9 @@ end_of_search:; done:; ch_free( srch_info.bsi_attrs ); + if ( base.bv_val != op->o_req_ndn.bv_val ) { + ch_free( base.bv_val ); + } Debug( LDAP_DEBUG_TRACE, "<==backsql_search()\n", 0, 0, 0 ); return 0; diff --git a/servers/slapd/back-sql/sql-wrap.c b/servers/slapd/back-sql/sql-wrap.c index e86477c1ba..91df43f3a5 100644 --- a/servers/slapd/back-sql/sql-wrap.c +++ b/servers/slapd/back-sql/sql-wrap.c @@ -80,7 +80,7 @@ backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char *query, int timeout ) SQLGetInfo( dbh, SQL_DRIVER_NAME, drv_name, sizeof( drv_name ), &len ); #ifdef BACKSQL_TRACE - Debug( LDAP_DEBUG_TRACE, "backsql_Prepare(): driver name='%s'\n", + Debug( LDAP_DEBUG_TRACE, "backsql_Prepare(): driver name=\"%s\"\n", drv_name, 0, 0 ); #endif /* BACKSQL_TRACE */ @@ -333,7 +333,7 @@ backsql_open_db_conn( backsql_info *si, int ldap_cid, backsql_db_conn **pdbc ) SQL_NTS, si->dbpasswd, SQL_NTS ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: " - "SQLConnect() to database '%s' as user '%s' " + "SQLConnect() to database \"%s\" as user \"%s\" " "%s:\n", si->dbname, si->dbuser, rc == SQL_SUCCESS_WITH_INFO ? "succeeded with info" : "failed" ); diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c index a138989c59..4523b31377 100644 --- a/servers/slapd/back-sql/util.c +++ b/servers/slapd/back-sql/util.c @@ -119,7 +119,7 @@ backsql_strcat( struct berbuf *dest, ... ) va_end( strs ); #ifdef BACKSQL_TRACE - Debug( LDAP_DEBUG_TRACE, "<==backsql_strcat() (dest='%s')\n", + Debug( LDAP_DEBUG_TRACE, "<==backsql_strcat() (dest=\"%s\")\n", dest, 0, 0 ); #endif /* BACKSQL_TRACE */ @@ -230,7 +230,7 @@ backsql_strfcat( struct berbuf *dest, const char *fmt, ... ) va_end( strs ); #ifdef BACKSQL_TRACE - Debug( LDAP_DEBUG_TRACE, "<==backsql_strfcat() (dest='%s')\n", + Debug( LDAP_DEBUG_TRACE, "<==backsql_strfcat() (dest=\"%s\")\n", dest, 0, 0 ); #endif /* BACKSQL_TRACE */ @@ -252,7 +252,7 @@ backsql_entry_addattr( #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): " - "at_name='%s', at_val='%s'\n", + "at_name=\"%s\", at_val=\"%s\"\n", at_name->bv_val, at_val->bv_val, 0 ); #endif /* BACKSQL_TRACE */ @@ -260,7 +260,7 @@ backsql_entry_addattr( rc = slap_bv2ad( at_name, &ad, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): " - "failed to find AttributeDescription for '%s'\n", + "failed to find AttributeDescription for \"%s\"\n", at_name->bv_val, 0, 0 ); return 0; } @@ -269,7 +269,7 @@ backsql_entry_addattr( if ( rc != 0 ) { Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): " - "failed to merge value '%s' for attribute '%s'\n", + "failed to merge value \"%s\" for attribute \"%s\"\n", at_val->bv_val, at_name->bv_val, 0 ); return 0; } @@ -339,7 +339,7 @@ backsql_merge_from_clause( #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>backsql_merge_from_clause(): " - "dest_from='%s',src_from='%s'\n", + "dest_from=\"%s\",src_from=\"%s\"\n", dest_from ? dest_from->bb_val.bv_val : "", src_from, 0 ); #endif /* BACKSQL_TRACE */ @@ -355,7 +355,7 @@ backsql_merge_from_clause( #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "backsql_merge_from_clause(): " - "p='%s' s='%s'\n", p, s, 0 ); + "p=\"%s\" s=\"%s\"\n", p, s, 0 ); #endif /* BACKSQL_TRACE */ if ( res.bb_val.bv_val == NULL ) {