]> git.sur5r.net Git - openldap/commitdiff
General improvements:
authorPierangelo Masarati <ando@openldap.org>
Thu, 8 Apr 2004 09:08:28 +0000 (09:08 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 8 Apr 2004 09:08:28 +0000 (09:08 +0000)
- 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).

servers/slapd/back-sql/add.c
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/delete.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/init.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/search.c

index 36370b825909b9a3b0bc401756fef46379a4a78f..6f00d487f0527c3bd048b5f248d6ba41889801d6 100644 (file)
@@ -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 */
index 0241eeb170ae18b790e1d45c3190ced1d5aad49e..eb513f0043bd24f60febfe994e40a22874cd578b 100644 (file)
  */
 #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;
index a5cf70046209772251ebeb24e5b00bc1d5cab2f0..ecb404ecf8493b67d33aacd9048b03139456a289 100644 (file)
@@ -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(): "
index 55a4f55d7cb3c3ab437e105cf00082d57586dd70..931b4f571cd1e1909a9fc8922feaa4ecb64cabf2 100644 (file)
@@ -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(): "
index a07a786d4901f085e3abd51bf6ae236779300aea..663f3225f9a9eaf7140541ec9e556cb4f9b8c2d1 100644 (file)
@@ -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(): "
index c36db54f4ccc45daa37e6409936df5c0c1463c7d..2c392a36504125cf43db85ec3b05f24abc7baa69 100644 (file)
@@ -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",
index 8dcc1cc6fc282b65bc271e32ad0e4c0e48472916..bf58cddead4f06f69872dfd6c6e5633b9ca48fa6 100644 (file)
@@ -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 ) {
index 0eca1f703b2ede7ea8b620089a84692f1b867765..484e6840842bb08da30e680494449a30d41553e4 100644 (file)
 #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 );