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 ) ) { -#ifdef BACKSQL_ARBITRARY_KEY - 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 ); -#endif /* ! BACKSQL_ARBITRARY_KEY */ - id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 ); - ber_dupbv( &id->eid_dn, dn ); - id->eid_next = NULL; - 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 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + 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; + } } 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; + } - rc = backsql_BindParamStr( sth, 2, bsi->bsi_base_dn->bv_val, + 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 ); + } + + 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 ) {