From: Pierangelo Masarati Date: Thu, 8 Apr 2004 09:08:28 +0000 (+0000) Subject: General improvements: X-Git-Tag: OPENLDAP_REL_ENG_2_2_BP~80 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=354372987f0a9da9058afb48847cc136d7d67f2b;p=openldap General improvements: - There might be special cases that require the unique key to be a string (just ran into one); since this is not a generally useful change, it's hidden behind #defines. - Added essential support for telephoneNumber match; the same infrastructure might be useful for other specialized matches (also regular matches should use it to handle multiple spaces and so!). - Fixed dynamic backend initialization. - Cleaned up search base DN normalization (works also if no uppercase function is available, using case exact matches). --- diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index 36370b8259..6f00d487f0 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -179,7 +179,13 @@ del_all: break; } - rc = backsql_BindParamID( asth, 1, &e_id->keyval ); +#ifdef BACKSQL_ARBITRARY_KEY + rc = backsql_BindParamStr( asth, 1, + e_id->eid_keyval.bv_val, + BACKSQL_MAX_KEY_LEN ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + rc = backsql_BindParamID( asth, 1, &e_id->eid_keyval ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): " @@ -232,10 +238,18 @@ del_all: pno = 0; } po = ( BACKSQL_IS_DEL( at->bam_param_order ) ) > 0; +#ifdef BACKSQL_ARBITRARY_KEY + SQLBindParameter( sth, pno + 1 + po, + SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_VARCHAR, + 0, 0, e_id->eid_keyval.bv_val, + 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ SQLBindParameter( sth, pno + 1 + po, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, - 0, 0, &e_id->keyval, 0, 0 ); + 0, 0, &e_id->eid_keyval, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ /* * check for syntax needed here @@ -317,10 +331,17 @@ add_only:; pno = 0; } po = ( BACKSQL_IS_ADD( at->bam_param_order ) ) > 0; +#ifdef BACKSQL_ARBITRARY_KEY + SQLBindParameter( sth, pno + 1 + po, + SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_VARCHAR, + 0, 0, e_id->eid_keyval.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ SQLBindParameter( sth, pno + 1 + po, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, - 0, 0, &e_id->keyval, 0, 0 ); + 0, 0, &e_id->eid_keyval, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ /* * check for syntax needed here @@ -404,10 +425,17 @@ add_only:; pno = 0; } po = ( BACKSQL_IS_DEL( at->bam_param_order ) ) > 0; +#ifdef BACKSQL_ARBITRARY_KEY + SQLBindParameter( sth, pno + 1 + po, + SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_VARCHAR, + 0, 0, e_id->eid_keyval.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ SQLBindParameter( sth, pno + 1 + po, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, - 0, 0, &e_id->keyval, 0, 0 ); + 0, 0, &e_id->eid_keyval, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ /* * check for syntax needed here @@ -908,15 +936,27 @@ backsql_add( Operation *op, SlapReply *rs ) BACKSQL_MAX_DN_LEN ); SQLBindParameter( sth, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &oc->bom_id, 0, 0 ); +#ifdef BACKSQL_ARBITRARY_KEY + SQLBindParameter( sth, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, + 0, 0, parent_id.eid_id.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ SQLBindParameter( sth, 3, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, - 0, 0, &parent_id.id, 0, 0 ); + 0, 0, &parent_id.eid_id, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ SQLBindParameter( sth, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &new_keyval, 0, 0 ); Debug( LDAP_DEBUG_TRACE, " backsql_add(): executing \"%s\" for dn \"%s\"\n", bi->insentry_query, op->oq_add.rs_e->e_name.bv_val, 0 ); - Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, parent_id=%ld, " - "keyval=%ld\n", oc->bom_id, parent_id.id, new_keyval ); +#ifdef BACKSQL_ARBITRARY_KEY + Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, " + "parent_id=%s, keyval=%ld\n", + oc->bom_id, parent_id.eid_id.bv_val, new_keyval ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, " + "parent_id=%ld, keyval=%ld\n", + oc->bom_id, parent_id.eid_id, new_keyval ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ #ifndef BACKSQL_REALLOC_STMT rc = SQLExecDirect( sth, bi->insentry_query, SQL_NTS ); #else /* BACKSQL_REALLOC_STMT */ diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index 0241eeb170..eb513f0043 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -93,15 +93,33 @@ */ #undef BACKSQL_TRACE +/* + * define to enable varchars as unique keys in user tables + */ +#undef BACKSQL_ARBITRARY_KEY + /* * Entry ID structure */ typedef struct backsql_entryID { - unsigned long id; - unsigned long keyval; - unsigned long oc_id; - struct berval dn; - struct backsql_entryID *next; + /* #define BACKSQL_ARBITRARY_KEY to allow a non-numeric key. + * It is required by some special applications that use + * strings as keys for the main table. + * In this case, #define BACKSQL_MAX_KEY_LEN consistently + * with the key size definition */ +#ifdef BACKSQL_ARBITRARY_KEY + struct berval eid_id; + struct berval eid_keyval; +#define BACKSQL_MAX_KEY_LEN 64 +#else /* ! BACKSQL_ARBITRARY_KEY */ + /* The original numeric key is maintained as default. */ + unsigned long eid_id; + unsigned long eid_keyval; +#endif /* ! BACKSQL_ARBITRARY_KEY */ + + unsigned long eid_oc_id; + struct berval eid_dn; + struct backsql_entryID *eid_next; } backsql_entryID; /* @@ -253,6 +271,7 @@ typedef struct { char *has_children_query; MatchingRule *bi_caseIgnoreMatch; + MatchingRule *bi_telephoneNumberMatch; struct berval upper_func; struct berval upper_func_open; @@ -282,6 +301,8 @@ typedef struct { ((si)->bsql_flags & BSQLF_DONTCHECK_LDAPINFO_DN_RU) #define BACKSQL_USE_REVERSE_DN(si) \ ((si)->bsql_flags & BSQLF_USE_REVERSE_DN) +#define BACKSQL_CANUPPERCASE(si) \ + ((si)->upper_func.bv_val) struct berval strcast_func; Avlnode *db_conns; diff --git a/servers/slapd/back-sql/delete.c b/servers/slapd/back-sql/delete.c index a5cf700462..ecb404ecf8 100644 --- a/servers/slapd/back-sql/delete.c +++ b/servers/slapd/back-sql/delete.c @@ -95,7 +95,7 @@ backsql_delete( Operation *op, SlapReply *rs ) goto done; } - oc = backsql_id2oc( bi, e_id.oc_id ); + oc = backsql_id2oc( bi, e_id.eid_oc_id ); if ( oc == NULL ) { Debug( LDAP_DEBUG_TRACE, " backsql_delete(): " "cannot determine objectclass of entry -- aborting\n", @@ -137,8 +137,15 @@ backsql_delete( Operation *op, SlapReply *rs ) pno = 0; } +#ifdef BACKSQL_ARBITRARY_KEY SQLBindParameter( sth, pno + 1, SQL_PARAM_INPUT, - SQL_C_ULONG, SQL_INTEGER, 0, 0, &e_id.keyval, 0, 0 ); + SQL_C_CHAR, SQL_VARCHAR, 0, 0, e_id.eid_keyval.bv_val, + 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + SQLBindParameter( sth, pno + 1, SQL_PARAM_INPUT, + SQL_C_ULONG, SQL_INTEGER, 0, 0, &e_id.eid_keyval, + 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { @@ -170,8 +177,13 @@ backsql_delete( Operation *op, SlapReply *rs ) goto done; } +#ifdef BACKSQL_ARBITRARY_KEY + SQLBindParameter( sth, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, + 0, 0, e_id.eid_id.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ SQLBindParameter( sth, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, - 0, 0, &e_id.id, 0, 0 ); + 0, 0, &e_id.eid_id, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_delete(): " diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index 55a4f55d7c..931b4f571c 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -38,12 +38,22 @@ backsql_free_entryID( backsql_entryID *id, int freeit ) assert( id ); - next = id->next; + next = id->eid_next; - if ( id->dn.bv_val != NULL ) { - free( id->dn.bv_val ); + if ( id->eid_dn.bv_val != NULL ) { + free( id->eid_dn.bv_val ); } +#ifdef BACKSQL_ARBITRARY_KEY + if ( id->eid_id.bv_val ) { + free( id->eid_id.bv_val ); + } + + if ( id->eid_keyval.bv_val ) { + free( id->eid_keyval.bv_val ); + } +#endif /* BACKSQL_ARBITRARY_KEY */ + if ( freeit ) { free( id ); } @@ -147,11 +157,16 @@ backsql_dn2id( backsql_BindRowAsStrings( sth, &row ); rc = SQLFetch( sth ); if ( BACKSQL_SUCCESS( rc ) ) { - id->id = strtol( row.cols[ 0 ], NULL, 0 ); - id->keyval = strtol( row.cols[ 1 ], NULL, 0 ); - id->oc_id = strtol( row.cols[ 2 ], NULL, 0 ); - ber_dupbv( &id->dn, dn ); - id->next = 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; res = LDAP_SUCCESS; @@ -162,8 +177,13 @@ backsql_dn2id( 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->id, 0, 0 ); + id->eid_id, 0, 0 ); +#endif /* !BACKSQL_ARBITRARY_KEY */ } else { Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): no match\n", 0, 0, 0 ); @@ -287,11 +307,18 @@ backsql_get_attr_vals( void *v_at, void *v_bsi ) assert( at ); assert( bsi ); - + +#ifdef BACKSQL_ARBITRARY_KEY + Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): " + "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", BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val, - bsi->bsi_c_eid->keyval ); + bsi->bsi_c_eid->eid_keyval ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_query, 0 ); if ( rc != SQL_SUCCESS ) { @@ -301,7 +328,12 @@ backsql_get_attr_vals( void *v_at, void *v_bsi ) return 1; } - rc = backsql_BindParamID( sth, 1, &bsi->bsi_c_eid->keyval ); +#ifdef BACKSQL_ARBITRARY_KEY + rc = backsql_BindParamStr( sth, 1, bsi->bsi_c_eid->eid_keyval.bv_val, + BACKSQL_MAX_KEY_LEN ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + rc = backsql_BindParamID( sth, 1, &bsi->bsi_c_eid->eid_keyval ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): " "error binding key value parameter\n", 0, 0, 0 ); @@ -372,19 +404,22 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid ) Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 ); - rc = dnPrettyNormal( NULL, &eid->dn, &e->e_name, &e->e_nname, + rc = dnPrettyNormal( NULL, &eid->eid_dn, &e->e_name, &e->e_nname, bsi->bsi_op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { return NULL; } - bsi->bsi_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private, eid->oc_id ); + bsi->bsi_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private, + eid->eid_oc_id ); bsi->bsi_e = e; bsi->bsi_c_eid = eid; e->e_attrs = NULL; e->e_private = NULL; - - e->e_id = eid->id; + +#ifndef BACKSQL_ARBITRARY_KEY + e->e_id = eid->eid_id; +#endif /* ! BACKSQL_ARBITRARY_KEY */ if ( bsi->bsi_attrs != NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): " diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index a07a786d49..663f3225f9 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -29,7 +29,7 @@ #include "ldap_pvt.h" #include "proto-sql.h" -#if SLAPD_SQL == SLAPD_MOD_DYNAMIC +#if defined(SLAPD_SQL_DYNAMIC) int init_module( @@ -46,7 +46,7 @@ init_module( return 0; } -#endif /* SLAPD_SQL */ +#endif /* SLAPD_SQL_DYNAMIC */ int sql_back_initialize( @@ -229,6 +229,10 @@ backsql_db_open( /* normalize filter values only if necessary */ si->bi_caseIgnoreMatch = mr_find( "caseIgnoreMatch" ); + assert( si->bi_caseIgnoreMatch ); + + si->bi_telephoneNumberMatch = mr_find( "telephoneNumberMatch" ); + assert( si->bi_telephoneNumberMatch ); if ( si->dbuser == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index c36db54f4c..2c392a3650 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -72,11 +72,17 @@ backsql_modify( Operation *op, SlapReply *rs ) return 1; } +#ifdef BACKSQL_ARBITRARY_KEY + Debug( LDAP_DEBUG_TRACE, " backsql_modify(): " + "modifying entry \"%s\" (id=%s)\n", + e_id.eid_dn.bv_val, e_id.eid_id.bv_val, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ Debug( LDAP_DEBUG_TRACE, " backsql_modify(): " "modifying entry \"%s\" (id=%ld)\n", - e_id.dn.bv_val, e_id.id, 0 ); + e_id.eid_dn.bv_val, e_id.eid_id, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ - oc = backsql_id2oc( bi, e_id.oc_id ); + oc = backsql_id2oc( bi, e_id.eid_oc_id ); if ( oc == NULL ) { Debug( LDAP_DEBUG_TRACE, " backsql_modify(): " "cannot determine objectclass of entry -- aborting\n", diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index 8dcc1cc6fc..bf58cddead 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -73,8 +73,13 @@ backsql_modrdn( Operation *op, SlapReply *rs ) return 1; } +#ifdef BACKSQL_ARBITRARY_KEY + Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): entry id=%s\n", + e_id.eid_id.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): entry id=%ld\n", - e_id.id, 0, 0 ); + e_id.eid_id, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ if ( backsql_has_children( bi, dbh, &op->o_req_ndn ) == LDAP_COMPARE_TRUE ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " @@ -192,8 +197,13 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto modrdn_return; } +#ifdef BACKSQL_ARBITRARY_KEY Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " - "old parent entry id is %ld\n", pe_id.id, 0, 0 ); + "old parent entry id is %s\n", pe_id.eid_id.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " + "old parent entry id is %ld\n", pe_id.eid_id, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ rs->sr_err = backsql_dn2id( bi, &new_pid, dbh, new_npdn ); if ( rs->sr_err != LDAP_SUCCESS ) { @@ -204,16 +214,26 @@ backsql_modrdn( Operation *op, SlapReply *rs ) send_ldap_result( op, rs ); goto modrdn_return; } - + +#ifdef BACKSQL_ARBITRARY_KEY + Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " + "new parent entry id=%s\n", new_pid.eid_id.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " - "new parent entry id=%ld\n", new_pid.id, 0, 0 ); + "new parent entry id=%ld\n", new_pid.eid_id, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " "executing delentry_query\n", 0, 0, 0 ); SQLAllocStmt( dbh, &sth ); +#ifdef BACKSQL_ARBITRARY_KEY + SQLBindParameter( sth, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, + 0, 0, e_id.eid_id.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ SQLBindParameter( sth, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, - 0, 0, &e_id.id, 0, 0 ); + 0, 0, &e_id.eid_id, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ rc = SQLExecDirect( sth, bi->delentry_query, SQL_NTS ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " @@ -232,11 +252,18 @@ backsql_modrdn( Operation *op, SlapReply *rs ) "executing insentry_query\n", 0, 0, 0 ); backsql_BindParamStr( sth, 1, new_dn.bv_val, BACKSQL_MAX_DN_LEN ); SQLBindParameter( sth, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, - 0, 0, &e_id.oc_id, 0, 0 ); + 0, 0, &e_id.eid_oc_id, 0, 0 ); +#ifdef BACKSQL_ARBITRARY_KEY + SQLBindParameter( sth, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, + 0, 0, new_pid.eid_id.bv_val, 0, 0 ); + SQLBindParameter( sth, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, + 0, 0, e_id.eid_keyval.bv_val, 0, 0 ); +#else /* ! BACKSQL_ARBITRARY_KEY */ SQLBindParameter( sth, 3, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, - 0, 0, &new_pid.id, 0, 0 ); + 0, 0, &new_pid.eid_id, 0, 0 ); SQLBindParameter( sth, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, - 0, 0, &e_id.keyval, 0, 0 ); + 0, 0, &e_id.eid_keyval, 0, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ rc = SQLExecDirect( sth, bi->insentry_query, SQL_NTS ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " @@ -316,7 +343,7 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto modrdn_return; } - oc = backsql_id2oc( bi, e_id.oc_id ); + oc = backsql_id2oc( bi, e_id.eid_oc_id ); rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, mod ); if ( rs->sr_err == LDAP_SUCCESS ) { diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 0eca1f703b..484e684084 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -35,7 +35,12 @@ #define BACKSQL_CONTINUE 1 static int backsql_process_filter( backsql_srch_info *bsi, Filter *f ); - +static int backsql_process_filter_eq( backsql_srch_info *bsi, + backsql_at_map_rec *at, + int casefold, struct berval *filter_value ); +static int backsql_process_filter_like( backsql_srch_info *bsi, + backsql_at_map_rec *at, + int casefold, struct berval *filter_value ); static int backsql_process_filter_attr( backsql_srch_info *bsi, Filter *f, backsql_at_map_rec *at ); @@ -215,9 +220,7 @@ static int backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, backsql_at_map_rec *at ) { -#ifdef BACKSQL_UPPERCASE_FILTER backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; -#endif /* BACKSQL_UPPERCASE_FILTER */ int i; int casefold = 0; @@ -234,6 +237,77 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, casefold = 1; } + if ( SLAP_MR_ASSOCIATED( f->f_sub_desc->ad_type->sat_substr, + bi->bi_telephoneNumberMatch ) ) + { + + struct berval bv; + ber_len_t i, s, a; + + /* + * to check for matching telephone numbers + * with intermized chars, e.g. val='1234' + * use + * + * val LIKE '%1%2%3%4%' + */ + + bv.bv_len = 0; + if ( f->f_sub_initial.bv_val ) { + bv.bv_len += f->f_sub_initial.bv_len; + } + if ( f->f_sub_any != NULL ) { + for ( a = 0; f->f_sub_any[ a ].bv_val != NULL; a++ ) { + bv.bv_len += f->f_sub_any[ a ].bv_len; + } + } + if ( f->f_sub_final.bv_val ) { + bv.bv_len += f->f_sub_final.bv_len; + } + bv.bv_len = 2 * bv.bv_len - 1; + bv.bv_val = ch_malloc( bv.bv_len + 1 ); + + s = 0; + if ( f->f_sub_initial.bv_val ) { + bv.bv_val[ s ] = f->f_sub_initial.bv_val[ 0 ]; + for ( i = 1; i < f->f_sub_initial.bv_len; i++ ) { + bv.bv_val[ s + 2 * i - 1 ] = '%'; + bv.bv_val[ s + 2 * i ] = f->f_sub_initial.bv_val[ i ]; + } + bv.bv_val[ s + 2 * i - 1 ] = '%'; + s += 2 * i; + } + + if ( f->f_sub_any != NULL ) { + for ( a = 0; f->f_sub_any[ a ].bv_val != NULL; a++ ) { + bv.bv_val[ s ] = f->f_sub_any[ a ].bv_val[ 0 ]; + for ( i = 1; i < f->f_sub_any[ a ].bv_len; i++ ) { + bv.bv_val[ s + 2 * i - 1 ] = '%'; + bv.bv_val[ s + 2 * i ] = f->f_sub_any[ a ].bv_val[ i ]; + } + bv.bv_val[ s + 2 * i - 1 ] = '%'; + s += 2 * i; + } + } + + if ( f->f_sub_final.bv_val ) { + bv.bv_val[ s ] = f->f_sub_final.bv_val[ 0 ]; + for ( i = 1; i < f->f_sub_final.bv_len; i++ ) { + bv.bv_val[ s + 2 * i - 1 ] = '%'; + bv.bv_val[ s + 2 * i ] = f->f_sub_final.bv_val[ i ]; + } + bv.bv_val[ s + 2 * i - 1 ] = '%'; + s += 2 * i; + } + + bv.bv_val[ s - 1 ] = '\0'; + + (void)backsql_process_filter_like( bsi, at, casefold, &bv ); + ch_free( bv.bv_val ); + + return 1; + } + /* * When dealing with case-sensitive strings * we may omit normalization; however, normalized @@ -556,9 +630,93 @@ done:; return rc; } +static int +backsql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at, + int casefold, struct berval *filter_value ) +{ + /* + * maybe we should check type of at->sel_expr here somehow, + * to know whether upper_func is applicable, but for now + * upper_func stuff is made for Oracle, where UPPER is + * safely applicable to NUMBER etc. + */ + if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { + ber_len_t start; + + backsql_strfcat( &bsi->bsi_flt_where, "cbl", + '(', /* ) */ + &at->bam_sel_expr_u, + (ber_len_t)sizeof( "='" ) - 1, + "='" ); + + start = bsi->bsi_flt_where.bb_val.bv_len; + + backsql_strfcat( &bsi->bsi_flt_where, "bl", + filter_value, + (ber_len_t)sizeof( /* (' */ "')" ) - 1, + /* (' */ "')" ); + + ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); + + } else { + backsql_strfcat( &bsi->bsi_flt_where, "cblbl", + '(', /* ) */ + &at->bam_sel_expr, + (ber_len_t)sizeof( "='" ) - 1, "='", + filter_value, + (ber_len_t)sizeof( /* (' */ "')" ) - 1, + /* (' */ "')" ); + } + + return 1; +} + +static int +backsql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at, + int casefold, struct berval *filter_value ) +{ + /* + * maybe we should check type of at->sel_expr here somehow, + * to know whether upper_func is applicable, but for now + * upper_func stuff is made for Oracle, where UPPER is + * safely applicable to NUMBER etc. + */ + if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { + ber_len_t start; + + backsql_strfcat( &bsi->bsi_flt_where, "cbl", + '(', /* ) */ + &at->bam_sel_expr_u, + (ber_len_t)sizeof( " LIKE '%" ) - 1, + " LIKE '%" ); + + start = bsi->bsi_flt_where.bb_val.bv_len; + + backsql_strfcat( &bsi->bsi_flt_where, "bl", + filter_value, + (ber_len_t)sizeof( /* (' */ "%')" ) - 1, + /* (' */ "%')" ); + + ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); + + } else { + backsql_strfcat( &bsi->bsi_flt_where, "cblbl", + '(', /* ) */ + &at->bam_sel_expr, + (ber_len_t)sizeof( " LIKE '%" ) - 1, + " LIKE '%", + filter_value, + (ber_len_t)sizeof( /* (' */ "%')" ) - 1, + /* (' */ "%')" ); + } + + return 1; +} + static int backsql_process_filter_attr( backsql_srch_info *bsi, Filter *f, backsql_at_map_rec *at ) { + backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; int casefold = 0; struct berval *filter_value = NULL; MatchingRule *matching_rule = NULL; @@ -605,39 +763,43 @@ equality_match:; casefold = 1; } - /* - * maybe we should check type of at->sel_expr here somehow, - * to know whether upper_func is applicable, but for now - * upper_func stuff is made for Oracle, where UPPER is - * safely applicable to NUMBER etc. - */ - if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { - ber_len_t start; + if ( SLAP_MR_ASSOCIATED( matching_rule, + bi->bi_telephoneNumberMatch ) ) + { + struct berval bv; + ber_len_t i; - backsql_strfcat( &bsi->bsi_flt_where, "cbl", - '(', /* ) */ - &at->bam_sel_expr_u, - (ber_len_t)sizeof( "='" ) - 1, - "='" ); + /* + * to check for matching telephone numbers + * with intermized chars, e.g. val='1234' + * use + * + * val LIKE '%1%2%3%4%' + */ - start = bsi->bsi_flt_where.bb_val.bv_len; + bv.bv_len = 2 * filter_value->bv_len - 1; + bv.bv_val = ch_malloc( bv.bv_len + 1 ); - backsql_strfcat( &bsi->bsi_flt_where, "bl", - filter_value, - (ber_len_t)sizeof( /* (' */ "')" ) - 1, - /* (' */ "')" ); + bv.bv_val[ 0 ] = filter_value->bv_val[ 0 ]; + for ( i = 1; i < filter_value->bv_len; i++ ) { + bv.bv_val[ 2 * i - 1 ] = '%'; + bv.bv_val[ 2 * i ] = filter_value->bv_val[ i ]; + } + bv.bv_val[ 2 * i - 1 ] = '\0'; - ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); + (void)backsql_process_filter_like( bsi, at, casefold, &bv ); + ch_free( bv.bv_val ); - } else { - backsql_strfcat( &bsi->bsi_flt_where, "cblbl", - '(', /* ) */ - &at->bam_sel_expr, - (ber_len_t)sizeof( "='" ) - 1, "='", - filter_value, - (ber_len_t)sizeof( /* (' */ "')" ) - 1, - /* (' */ "')" ); + break; } + + /* + * maybe we should check type of at->sel_expr here somehow, + * to know whether upper_func is applicable, but for now + * upper_func stuff is made for Oracle, where UPPER is + * safely applicable to NUMBER etc. + */ + (void)backsql_process_filter_eq( bsi, at, casefold, filter_value ); break; case LDAP_FILTER_GE: @@ -710,34 +872,7 @@ equality_match:; * upper_func stuff is made for Oracle, where UPPER is * safely applicable to NUMBER etc. */ - if ( at->bam_sel_expr_u.bv_val ) { - ber_len_t start; - - backsql_strfcat( &bsi->bsi_flt_where, "cbl", - '(', /* ) */ - &at->bam_sel_expr_u, - (ber_len_t)sizeof( " LIKE '%" ) - 1, - " LIKE '%" ); - - start = bsi->bsi_flt_where.bb_val.bv_len; - - backsql_strfcat( &bsi->bsi_flt_where, "bl", - &f->f_av_value, - (ber_len_t)sizeof( /* (' */ "%')" ) - 1, - /* (' */ "%')" ); - - ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); - - } else { - backsql_strfcat( &bsi->bsi_flt_where, "cblbl", - '(', /* ) */ - &at->bam_sel_expr, - (ber_len_t)sizeof( " LIKE '%" ) - 1, - " LIKE '%", - &f->f_av_value, - (ber_len_t)sizeof( /* (' */ "%')" ) - 1, - /* (' */ "%')" ); - } + (void)backsql_process_filter_like( bsi, at, 1, &f->f_av_value ); break; default: @@ -820,14 +955,11 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) switch ( bsi->bsi_scope ) { case LDAP_SCOPE_BASE: - if ( bi->upper_func.bv_val ) { - backsql_strfcat( &bsi->bsi_join_where, "blbcb", + if ( BACKSQL_CANUPPERCASE( bi ) ) { + backsql_strfcat( &bsi->bsi_join_where, "bl", &bi->upper_func, - (ber_len_t)sizeof( "(ldap_entries.dn)=" ) - 1, - "(ldap_entries.dn)=", - &bi->upper_func_open, - '?', - &bi->upper_func_close ); + (ber_len_t)sizeof( "(ldap_entries.dn)=?" ) - 1, + "(ldap_entries.dn)=?" ); } else { backsql_strfcat( &bsi->bsi_join_where, "l", (ber_len_t)sizeof( "ldap_entries.dn=?" ) - 1, @@ -842,14 +974,11 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) break; case LDAP_SCOPE_SUBTREE: - if ( bi->upper_func.bv_val ) { - backsql_strfcat( &bsi->bsi_join_where, "blbcb", + 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 ", - &bi->upper_func_open, - '?', - &bi->upper_func_close ); + (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, @@ -1050,7 +1179,11 @@ 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 ); } - ldap_pvt_str2upper( temp_base_dn ); + /* 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, 0, 0 ); @@ -1080,11 +1213,19 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) bsi->bsi_status = res; return BACKSQL_CONTINUE; } - - Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n", base_id.id, + +#ifdef BACKSQL_ARBITRARY_KEY + 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, + BACKSQL_MAX_KEY_LEN ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n", base_id.eid_id, 0, 0 ); - rc = backsql_BindParamID( sth, 2, &base_id.id ); + rc = backsql_BindParamID( sth, 2, &base_id.eid_id ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ backsql_free_entryID( &base_id, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): " @@ -1110,17 +1251,29 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) { c_id = (backsql_entryID *)ch_calloc( 1, sizeof( backsql_entryID ) ); - c_id->id = strtol( row.cols[ 0 ], NULL, 0 ); - c_id->keyval = strtol( row.cols[ 1 ], NULL, 0 ); - c_id->oc_id = bsi->bsi_oc->bom_id; - ber_str2bv( row.cols[ 3 ], 0, 1, &c_id->dn ); - c_id->next = bsi->bsi_id_list; +#ifdef BACKSQL_ARBITRARY_KEY + ber_str2bv( row.cols[ 0 ], 0, 1, &c_id->eid_id ); + ber_str2bv( row.cols[ 1 ], 0, 1, &c_id->eid_keyval ); +#else /* ! BACKSQL_ARBITRARY_KEY */ + c_id->eid_id = strtol( row.cols[ 0 ], NULL, 0 ); + 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 ); + 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", + 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", - c_id->id, c_id->keyval, row.cols[ 3 ] ); + c_id->eid_id, c_id->eid_keyval, row.cols[ 3 ] ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ if ( bsi->bsi_n_candidates == -1 ) { break; @@ -1240,9 +1393,16 @@ backsql_search( Operation *op, SlapReply *rs ) goto end_of_search; } +#ifdef BACKSQL_ARBITRARY_KEY + Debug(LDAP_DEBUG_TRACE, "backsql_search(): loading data " + "for entry id=%s, oc_id=%ld, keyval=%s\n", + eid->eid_id.bv_val, eid->eid_oc_id, + eid->eid_keyval.bv_val ); +#else /* ! BACKSQL_ARBITRARY_KEY */ Debug(LDAP_DEBUG_TRACE, "backsql_search(): loading data " "for entry id=%ld, oc_id=%ld, keyval=%ld\n", - eid->id, eid->oc_id, eid->keyval ); + eid->eid_id, eid->eid_oc_id, eid->eid_keyval ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ entry = (Entry *)ch_calloc( sizeof( Entry ), 1 ); res = backsql_id2entry( &srch_info, entry, eid );