]> git.sur5r.net Git - openldap/commitdiff
fix various issues; line up with new tests
authorPierangelo Masarati <ando@openldap.org>
Tue, 24 Aug 2004 10:31:02 +0000 (10:31 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 24 Aug 2004 10:31:02 +0000 (10:31 +0000)
servers/slapd/back-sql/add.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/external.h
servers/slapd/back-sql/init.c
servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql
servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql
servers/slapd/back-sql/schema-map.c
servers/slapd/back-sql/search.c
servers/slapd/back-sql/sql-wrap.c
servers/slapd/back-sql/util.c

index b3e51aea4c17542ec9120a6040f7ae40ade1bfac..d561a6ef110d2f983275f88615078c5925419abc 100644 (file)
  * - the first occurrence of objectClass, which is used
  *   to determine how to build the SQL entry (FIXME ?!?)
  * - operational attributes
- *   empty attributes (FIXME ?!?)
+ * - empty attributes (FIXME ?!?)
  */
 #define        backsql_attr_skip(ad,vals) \
        ( \
                ( (ad) == slap_schema.si_ad_objectClass \
-                               && (vals)[ 1 ].bv_val == NULL ) \
+                               && BER_BVISNULL( &((vals)[ 1 ]) ) ) \
                || is_at_operational( (ad)->ad_type ) \
-               || ( (vals)[ 0 ].bv_val == NULL ) \
+               || ( (vals) && BER_BVISNULL( &((vals)[ 0 ]) ) ) \
        )
 
 int
@@ -290,6 +290,11 @@ del_all:
                        }
                        backsql_FreeRow( &row );
                        SQLFreeStmt( asth, SQL_DROP );
+
+                       /* LDAP_MOD_DELETE gets here if all values must be deleted */
+                       if ( c_mod->sm_op == LDAP_MOD_DELETE ) {
+                               break;
+                       }
                }
 
                /*
@@ -509,6 +514,153 @@ done:;
        return rs->sr_err;
 }
 
+static int
+backsql_add_attr(
+       Operation               *op,
+       SlapReply               *rs,
+       SQLHDBC                 dbh,
+       SQLHSTMT                *sth,
+       backsql_oc_map_rec      *oc,
+       Attribute               *at,
+       unsigned long           new_keyval )
+{
+       backsql_info            *bi = (backsql_info*)op->o_bd->be_private;
+       backsql_at_map_rec      *at_rec = NULL;
+       struct berval           *at_val;
+       unsigned long           i;
+       RETCODE                 rc;
+       /* first parameter #, parameter order */
+       SQLUSMALLINT            pno, po;
+       /* procedure return code */
+       int                     prc;
+       SQLUSMALLINT            currpos;
+
+       at_rec = backsql_ad2at( oc, at->a_desc ); 
+  
+       if ( at_rec == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       "attribute \"%s\" is not registered "
+                       "in objectclass \"%s\"\n",
+                       op->oq_add.rs_e->e_name.bv_val,
+                       at->a_desc->ad_cname.bv_val,
+                       BACKSQL_OC_NAME( oc ) );
+
+               if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
+                       rs->sr_text = "operation not permitted "
+                               "within namingContext";
+                       return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               }
+
+               return LDAP_SUCCESS;
+       }
+       
+       if ( at_rec->bam_add_proc == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       "add procedure is not defined "
+                       "for attribute \"%s\" "
+                       "of structuralObjectClass \"%s\"\n",
+                       op->oq_add.rs_e->e_name.bv_val,
+                       at->a_desc->ad_cname.bv_val,
+                       BACKSQL_OC_NAME( oc ) );
+
+               if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
+                       rs->sr_text = "operation not permitted "
+                               "within namingContext";
+                       return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               }
+
+               return LDAP_SUCCESS;
+       }
+
+       for ( i = 0, at_val = &at->a_vals[ i ];
+                       at_val->bv_val != NULL;
+                       i++, at_val = &at->a_vals[ i ] )
+       {
+               char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL";
+               
+               /*
+                * Do not deal with the objectClass that is used
+                * to build the entry
+                */
+               if ( at->a_desc == slap_schema.si_ad_objectClass ) {
+                       if ( bvmatch( at_val, &oc->bom_oc->soc_cname ) )
+                       {
+                               continue;
+                       }
+               }
+
+#ifdef BACKSQL_REALLOC_STMT
+               rc = backsql_Prepare( dbh, sth, at_rec->bam_add_proc, 0 );
+               if ( rc != SQL_SUCCESS ) {
+
+                       if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
+                               rs->sr_text = "SQL-backend error";
+                               return rs->sr_err = LDAP_OTHER;
+                       }
+
+                       return LDAP_SUCCESS;
+               }
+#endif /* BACKSQL_REALLOC_STMT */
+
+               if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) {
+                       pno = 1;
+                       SQLBindParameter( *sth, 1, SQL_PARAM_OUTPUT,
+                                       SQL_C_ULONG, SQL_INTEGER,
+                                       0, 0, &prc, 0, 0 );
+               } else {
+                       pno = 0;
+               }
+
+               po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0;
+               currpos = pno + 1 + po;
+               SQLBindParameter( *sth, currpos,
+                               SQL_PARAM_INPUT, SQL_C_ULONG,
+                               SQL_INTEGER, 0, 0, &new_keyval, 0, 0 );
+               currpos = pno + 2 - po;
+
+               /*
+                * check for syntax needed here 
+                * maybe need binary bind?
+                */
+
+               backsql_BindParamStr( *sth, currpos,
+                               at_val->bv_val, at_val->bv_len + 1 );
+
+#ifdef LDAP_DEBUG
+               snprintf( logbuf, sizeof( logbuf ), "val[%d], id=%ld",
+                               i, new_keyval );
+               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       "executing \"%s\" %s\n", 
+                       op->oq_add.rs_e->e_name.bv_val,
+                       at_rec->bam_add_proc, logbuf );
+#endif
+#ifndef BACKSQL_REALLOC_STMT
+               rc = SQLExecDirect( *sth, at_rec->bam_add_proc, SQL_NTS );
+#else /* BACKSQL_REALLOC_STMT */
+               rc = SQLExecute( *sth );
+#endif /* BACKSQL_REALLOC_STMT */
+               if ( rc != SQL_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "   backsql_add(\"%s\"): "
+                               "add_proc execution failed\n", 
+                               op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+                       backsql_PrintErrors( bi->db_env, dbh, *sth, rc );
+
+                       if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
+                               rs->sr_text = "SQL-backend error";
+                               return rs->sr_err = LDAP_OTHER;
+                       }
+               }
+#ifndef BACKSQL_REALLOC_STMT
+               SQLFreeStmt( *sth, SQL_RESET_PARAMS ); 
+#else /* BACKSQL_REALLOC_STMT */
+               SQLFreeStmt( *sth, SQL_DROP );
+#endif /* BACKSQL_REALLOC_STMT */
+       }
+
+       return LDAP_SUCCESS;
+}
+
 int
 backsql_add( Operation *op, SlapReply *rs )
 {
@@ -522,7 +674,8 @@ backsql_add( Operation *op, SlapReply *rs )
        backsql_at_map_rec      *at_rec = NULL;
        backsql_entryID         parent_id = BACKSQL_ENTRYID_INIT;
        Entry                   p;
-       Attribute               *at;
+       Attribute               *at,
+                               *at_objectClass = NULL;
        struct berval           *at_val;
        struct berval           pdn;
        /* first parameter #, parameter order */
@@ -879,141 +1032,23 @@ backsql_add( Operation *op, SlapReply *rs )
                /*
                 * Skip:
                 * - the first occurrence of objectClass, which is used
-                *   to determine how to bulid the SQL entry (FIXME ?!?)
+                *   to determine how to build the SQL entry (FIXME ?!?)
                 * - operational attributes
-                *   empty attributes (FIXME ?!?)
+                * - empty attributes (FIXME ?!?)
                 */
                if ( backsql_attr_skip( at->a_desc, at->a_vals ) ) {
                        continue;
                }
 
-               at_rec = backsql_ad2at( oc, at->a_desc ); 
-  
-               if ( at_rec == NULL ) {
-                       Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
-                               "attribute \"%s\" is not registered "
-                               "in objectclass \"%s\"\n",
-                               op->oq_add.rs_e->e_name.bv_val,
-                               at->a_desc->ad_cname.bv_val,
-                               BACKSQL_OC_NAME( oc ) );
-
-                       if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
-                               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-                               rs->sr_text = "operation not permitted "
-                                       "within namingContext";
-                               goto done;
-                       }
-
+               if ( at->a_desc == slap_schema.si_ad_objectClass ) {
+                       at_objectClass = at;
                        continue;
                }
-               
-               if ( at_rec->bam_add_proc == NULL ) {
-                       Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
-                               "add procedure is not defined "
-                               "for attribute \"%s\" "
-                               "of structuralObjectClass \"%s\"\n",
-                               op->oq_add.rs_e->e_name.bv_val,
-                               at->a_desc->ad_cname.bv_val,
-                               BACKSQL_OC_NAME( oc ) );
 
-                       if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
-                               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-                               rs->sr_text = "operation not permitted "
-                                       "within namingContext";
-                               goto done;
-                       }
-
-                       continue;
-               }
-
-               for ( i = 0, at_val = &at->a_vals[ i ];
-                               at_val->bv_val != NULL;
-                               i++, at_val = &at->a_vals[ i ] )
-               {
-                       char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL";
-                       
-#ifdef BACKSQL_REALLOC_STMT
-                       rc = backsql_Prepare( dbh, &sth, at_rec->bam_add_proc, 0 );
-                       if ( rc != SQL_SUCCESS ) {
-
-                               if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
-                                       rs->sr_err = LDAP_OTHER;
-                                       rs->sr_text = "SQL-backend error";
-                                       goto done;
-                               }
-
-                               goto next_attr;
-                       }
-#endif /* BACKSQL_REALLOC_STMT */
-
-                       if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) {
-                               pno = 1;
-                               SQLBindParameter( sth, 1, SQL_PARAM_OUTPUT,
-                                               SQL_C_ULONG, SQL_INTEGER,
-                                               0, 0, &prc, 0, 0 );
-                       } else {
-                               pno = 0;
-                       }
-
-                       po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0;
-                       currpos = pno + 1 + po;
-                       SQLBindParameter( sth, currpos,
-                                       SQL_PARAM_INPUT, SQL_C_ULONG,
-                                       SQL_INTEGER, 0, 0, &new_keyval, 0, 0 );
-                       currpos = pno + 2 - po;
-
-                       /*
-                        * Do not deal with the objectClass that is used
-                        * to build the entry
-                        */
-                       if ( at->a_desc == slap_schema.si_ad_objectClass ) {
-                               if ( bvmatch( at_val, &oc->bom_oc->soc_cname ) ) {
-                                       continue;
-                               }
-                       }
-
-                       /*
-                        * check for syntax needed here 
-                        * maybe need binary bind?
-                        */
-
-                       backsql_BindParamStr( sth, currpos,
-                                       at_val->bv_val, at_val->bv_len + 1 );
-
-#ifdef LDAP_DEBUG
-                       snprintf( logbuf, sizeof( logbuf ), "val[%d], id=%ld",
-                                       i, new_keyval );
-                       Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
-                               "executing \"%s\" %s\n", 
-                               op->oq_add.rs_e->e_name.bv_val,
-                               at_rec->bam_add_proc, logbuf );
-#endif
-#ifndef BACKSQL_REALLOC_STMT
-                       rc = SQLExecDirect( sth, at_rec->bam_add_proc, SQL_NTS );
-#else /* BACKSQL_REALLOC_STMT */
-                       rc = SQLExecute( sth );
-#endif /* BACKSQL_REALLOC_STMT */
-                       if ( rc != SQL_SUCCESS ) {
-                               Debug( LDAP_DEBUG_TRACE,
-                                       "   backsql_add(\"%s\"): "
-                                       "add_proc execution failed\n", 
-                                       op->oq_add.rs_e->e_name.bv_val, 0, 0 );
-                               backsql_PrintErrors( bi->db_env, dbh, sth, rc );
-
-                               if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
-                                       rs->sr_err = LDAP_OTHER;
-                                       rs->sr_text = "SQL-backend error";
-                                       goto done;
-                               }
-                       }
-#ifndef BACKSQL_REALLOC_STMT
-                       SQLFreeStmt( sth, SQL_RESET_PARAMS ); 
-#else /* BACKSQL_REALLOC_STMT */
-                       SQLFreeStmt( sth, SQL_DROP );
-#endif /* BACKSQL_REALLOC_STMT */
+               rs->sr_err = backsql_add_attr( op, rs, dbh, &sth, oc, at, new_keyval );
+               if ( rs->sr_err != LDAP_SUCCESS ) {
+                       goto done;
                }
-
-next_attr:;
        }
 
 #ifdef BACKSQL_REALLOC_STMT
@@ -1068,14 +1103,27 @@ next_attr:;
                rs->sr_text = "SQL-backend error";
                goto done;
        }
-       
+
+       /* FIXME: need ldap_entries.id of newly added entry */
+       if ( at_objectClass ) {
+               rs->sr_err = backsql_add_attr( op, rs, dbh, &sth, oc, at_objectClass, new_keyval );
+               if ( rs->sr_err != LDAP_SUCCESS ) {
+                       goto done;
+               }
+       }
+
        SQLFreeStmt( sth, SQL_DROP );
 
+done:;
        /*
         * Commit only if all operations succeed
         */
-       SQLTransact( SQL_NULL_HENV, dbh, 
-                       op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
+       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+               SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
+       } else {
+               SQLTransact( SQL_NULL_HENV, dbh, SQL_ROLLBACK );
+
+       }
 
        /*
         * FIXME: NOOP does not work for add -- it works for all 
@@ -1088,7 +1136,6 @@ next_attr:;
         * in deleting that row.
         */
 
-done:;
        send_ldap_result( op, rs );
 
        if ( !BER_BVISNULL( &realdn )
index 747f8bf968e95ffcc22e963ee134821443f78b29..b6cecd659e88096aa545998353580625291678c8 100644 (file)
@@ -341,6 +341,18 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                return 1;
        }
 
+#ifdef BACKSQL_TRACE
+#ifdef BACKSQL_ARBITRARY_KEY
+       Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+               "query=%s keyval=%s\n", at->bam_query,
+               bsi->bsi_c_eid->eid_keyval.bv_val, 0 );
+#else /* !BACKSQL_ARBITRARY_KEY */
+       Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+               "query=%s keyval=%d\n", at->bam_query,
+               bsi->bsi_c_eid->eid_keyval, 0 );
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+#endif /* BACKSQL_TRACE */
+
        rc = SQLExecute( sth );
        if ( ! BACKSQL_SUCCESS( rc ) ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
index 527172aa1b8e1d25ba1b2e4b5734832695c3fb49..57c05321be803b191586963571b35b3d51682e32 100644 (file)
@@ -23,7 +23,7 @@
 
 LDAP_BEGIN_DECL
 
-extern BI_init         sql_back_initialize;
+extern BI_init         backsql_initialize;
 extern BI_destroy      backsql_destroy;
 
 extern BI_db_init      backsql_db_init;
index d2d0e9808384eac1d5af542580f166183a19fa92..f92406278bc5f14fb46cda497d73bed67accde0f 100644 (file)
@@ -41,7 +41,7 @@ init_module(
 
        memset( &bi, '\0', sizeof( bi ) );
        bi.bi_type = "sql";
-       bi.bi_init = sql_back_initialize;
+       bi.bi_init = backsql_initialize;
 
        backend_add( &bi );
        return 0;
@@ -50,7 +50,7 @@ init_module(
 #endif /* SLAPD_SQL == SLAPD_MOD_DYNAMIC */
 
 int
-sql_back_initialize(
+backsql_initialize(
        BackendInfo     *bi )
 { 
        static char *controls[] = {
@@ -177,7 +177,7 @@ backsql_db_open(
        ber_len_t       idq_len;
        struct berbuf   bb = BB_NULL;
 
-       Operation       otmp;
+       Operation       otmp = { 0 };
                
        Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
                "testing RDBMS connection\n", 0, 0, 0 );
@@ -383,7 +383,7 @@ backsql_db_open(
                si->delentry_query = ch_strdup( backsql_def_delentry_query );
        }
 
-       otmp.o_connid = -1;
+       otmp.o_connid = (unsigned long)(-1);
        otmp.o_bd = bd;
        if ( backsql_get_db_conn( &otmp, &dbh ) != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
@@ -399,6 +399,7 @@ backsql_db_open(
 
        if ( si->upper_func.bv_val == NULL ) {
                backsql_strcat( &bb, backsql_id_query, "dn=?", NULL );
+
        } else {
                if ( BACKSQL_HAS_LDAPINFO_DN_RU( si ) ) {
                        backsql_strcat( &bb, backsql_id_query,
@@ -461,13 +462,14 @@ backsql_db_close(
 int
 backsql_connection_destroy( Backend *bd, Connection *c )
 {
-       Operation o;
+       Operation o = { 0 };
        o.o_bd = bd;
        o.o_connid = c->c_connid;
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_connection_destroy()\n", 0, 0, 0 );
        backsql_free_db_conn( &o );
        Debug( LDAP_DEBUG_TRACE, "<==backsql_connection_destroy()\n", 0, 0, 0 );
+
        return 0;
 }
 
index 4958b1fc16f5b6fe6ad7459a1047a83b95f2cd20..8933a4c87803f4f47f28cab8908ee6c5f30ae986 100644 (file)
@@ -66,6 +66,11 @@ values (10,2,'documentIdentifier','concat(''document '',documents.id)','document
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
 values (11,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0);
 
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
+values (12,3,'dc','lower(institutes.name)','institutes,ldap_entries AS dcObject,ldap_entry_objclasses as auxObjectClass',
+       'institutes.id=dcObject.keyval AND dcObject.oc_map_id=3 AND dcObject.id=auxObjectClass.entry_id AND auxObjectClass.oc_name=''dcObject''',
+       NULL,NULL,3,0);
+
 -- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context
 --     id              a unique number > 0 identifying the entry
 --     dn              the DN of the entry, in "pretty" form
@@ -73,32 +78,32 @@ values (11,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0);
 --     parent          the "ldap_entries.id" of the parent of this objectClass; 0 if it is the "suffix" of the database
 --     keyval          the value of the "keytbl.keycol" defined for this objectClass
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval)
-values (1,'o=Example,c=RU',3,0,1);
+values (1,'dc=example,dc=com',3,0,1);
 
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval)
-values (2,'cn=Mitya Kovalev,o=Example,c=RU',1,1,1);
+values (2,'cn=Mitya Kovalev,dc=example,dc=com',1,1,1);
 
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval)
-values (3,'cn=Torvlobnor Puzdoy,o=Example,c=RU',1,1,2);
+values (3,'cn=Torvlobnor Puzdoy,dc=example,dc=com',1,1,2);
 
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval)
-values (4,'cn=Akakiy Zinberstein,o=Example,c=RU',1,1,3);
+values (4,'cn=Akakiy Zinberstein,dc=example,dc=com',1,1,3);
 
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval)
-values (5,'documentTitle=book1,o=Example,c=RU',2,1,1);
+values (5,'documentTitle=book1,dc=example,dc=com',2,1,1);
 
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval)
-values (6,'documentTitle=book2,o=Example,c=RU',2,1,2);
+values (6,'documentTitle=book2,dc=example,dc=com',2,1,2);
        
 
 -- objectClass mapping: entries that have multiple objectClass instances are listed here with the objectClass name (view them as auxiliary objectClass)
 --     entry_id        the "ldap_entries.id" of the entry this objectClass value must be added
 --     oc_name         the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema
 insert into ldap_entry_objclasses (entry_id,oc_name)
-values (4,'referral');
+values (1,'dcObject');
 
 insert into ldap_entry_objclasses (entry_id,oc_name)
-values (2,'posixAccount');
+values (4,'referral');
 
 -- referrals mapping: entries that should be treated as referrals are stored here
 --     entry_id        the "ldap_entries.id" of the entry that should be treated as a referral
index d42103370a4cae29423343f19d20158e1016a3c2..cf2ffa452fd4aa75056ee94f11e8819b8f226981 100644 (file)
@@ -47,6 +47,8 @@ insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,
 
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (11,3,'o','institutes.name','institutes',NULL,'update institutes set name=? where id=?',NULL,3,0);
 
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (12,3,'dc','lower(institutes.name)','institutes,ldap_entries AS dcObject,ldap_entry_objclasses as auxObjectClass','institutes.id=dcObject.keyval AND dcObject.oc_map_id=3 AND dcObject.id=auxObjectClass.entry_id AND auxObjectClass.oc_name=''dcObject''',NULL,NULL,3,0);
+
 
 -- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context
 --     id              a unique number > 0 identifying the entry
@@ -54,25 +56,25 @@ insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,
 --     oc_map_id       the "ldap_oc_mappings.id" of the main objectClass of this entry (view it as the structuralObjectClass)
 --     parent          the "ldap_entries.id" of the parent of this objectClass; 0 if it is the "suffix" of the database
 --     keyval          the value of the "keytbl.keycol" defined for this objectClass
-insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (1,'o=Example,c=RU',3,0,1);
+insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (1,'dc=example,dc=com',3,0,1);
 
-insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (2,'cn=Mitya Kovalev,o=Example,c=RU',1,1,1);
+insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (2,'cn=Mitya Kovalev,dc=example,dc=com',1,1,1);
 
-insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (3,'cn=Torvlobnor Puzdoy,o=Example,c=RU',1,1,2);
+insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (3,'cn=Torvlobnor Puzdoy,dc=example,dc=com',1,1,2);
 
-insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (4,'cn=Akakiy Zinberstein,o=Example,c=RU',1,1,3);
+insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (4,'cn=Akakiy Zinberstein,dc=example,dc=com',1,1,3);
 
-insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (5,'documentTitle=book1,o=Example,c=RU',2,1,1);
+insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (5,'documentTitle=book1,dc=example,dc=com',2,1,1);
 
-insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (6,'documentTitle=book2,o=Example,c=RU',2,1,2);
+insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (6,'documentTitle=book2,dc=example,dc=com',2,1,2);
        
        
 -- objectClass mapping: entries that have multiple objectClass instances are listed here with the objectClass name (view them as auxiliary objectClass)
 --     entry_id        the "ldap_entries.id" of the entry this objectClass value must be added
 --     oc_name         the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema
-insert into ldap_entry_objclasses (entry_id,oc_name) values (4,'referral');
+insert into ldap_entry_objclasses (entry_id,oc_name) values (1,'dcObject');
 
-insert into ldap_entry_objclasses (entry_id,oc_name) values (2,'posixAccount');
+insert into ldap_entry_objclasses (entry_id,oc_name) values (4,'referral');
 
 -- referrals mapping: entries that should be treated as referrals are stored here
 --     entry_id        the "ldap_entries.id" of the entry that should be treated as a referral
@@ -85,7 +87,7 @@ create function create_person () returns int
 as '
        select setval (''persons_id_seq'', (select case when max(id) is null then 1 else max(id) end from persons));
        insert into persons (id,name,surname) 
-               values (nextval(''persons_id_seq''),'''','''');
+               values ((select case when max(id) is null then 1 else nextval(''persons_id_seq'') end from persons),'''','''');
        select max(id) from persons
 ' language 'sql';
 
@@ -110,6 +112,8 @@ as '
        delete from phones where pers_id = $1;
        delete from authors_docs where pers_id = $1;
        delete from persons where id = $1;
+       delete from ldap_entry_objclasses where entry_id=(select id from ldap_entries where oc_map_id=1 and keyval = $1);
+       delete from ldap_referrals where entry_id=(select id from ldap_entries where oc_map_id=1 and keyval = $1);
        select $1 as return
 ' language 'sql';
 
@@ -131,13 +135,15 @@ create function create_doc () returns int
 as '
        select setval (''documents_id_seq'', (select case when max(id) is null then 1 else max(id) end from documents));
        insert into documents (id,title,abstract) 
-               values (nextval(''documents_id_seq''),'''','''');
+               values ((select case when max(id) is null then 1 else nextval(''documents_id_seq'') end from documents),'''','''');
        select max(id) from documents
 ' language 'sql';
 
 create function delete_doc (int) returns int
 as '
        delete from documents where id = $1;
+       delete from ldap_entry_objclasses where entry_id=(select id from ldap_entries where oc_map_id=2 and keyval = $1);
+       delete from ldap_referrals where entry_id=(select id from ldap_entries where oc_map_id=2 and keyval = $1);
        select $1 as return
 ' language 'sql';
 
@@ -145,13 +151,15 @@ create function create_o () returns int
 as '
        select setval (''institutes_id_seq'', (select case when max(id) is null then 1 else max(id) end from institutes));
        insert into institutes (id,name) 
-               values (nextval(''institutes_id_seq''),'''');
+               values ((select case when max(id) is null then 1 else nextval(''institutes_id_seq'') end from institutes),'''');
        select max(id) from institutes
 ' language 'sql';
 
 create function delete_o (int) returns int
 as '
        delete from institutes where id = $1;
+       delete from ldap_entry_objclasses where entry_id=(select id from ldap_entries where oc_map_id=3 and keyval = $1);
+       delete from ldap_referrals where entry_id=(select id from ldap_entries where oc_map_id=3 and keyval = $1);
        select $1 as return
 ' language 'sql';
 
index e7d701b8bce4dfd52fceef50a1ae30b31abf5f09..29b1e06a0a6d2ed48259be68f24d699f3426ae35 100644 (file)
 
 #define BACKSQL_DUPLICATE      (-1)
 
+/* NOTE: by default, cannot just compare pointers because
+ * objectClass/attributeType order would be machine-dependent
+ * (and tests would fail!); however, if you don't want to run
+ * tests, or see attributeTypes written in the same order
+ * they are defined, define */
+/* #undef BACKSQL_USE_PTR_CMP */
+
 /*
  * Uses the pointer to the ObjectClass structure
  */
 static int
 backsql_cmp_oc( const void *v_m1, const void *v_m2 )
 {
-       const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2;
+       const backsql_oc_map_rec        *m1 = v_m1,
+                                       *m2 = v_m2;
 
-#if 0
+#ifdef BACKSQL_USE_PTR_CMP
        return SLAP_PTRCMP( m1->bom_oc, m2->bom_oc );
-#endif
+#else /* ! BACKSQL_USE_PTR_CMP */
        return ber_bvcmp( &m1->bom_oc->soc_cname, &m2->bom_oc->soc_cname );
+#endif /* ! BACKSQL_USE_PTR_CMP */
 }
 
 static int
 backsql_cmp_oc_id( const void *v_m1, const void *v_m2 )
 {
-       const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2;
+       const backsql_oc_map_rec        *m1 = v_m1,
+                                       *m2 = v_m2;
 
        return ( m1->bom_id < m2->bom_id ? -1 : ( m1->bom_id > m2->bom_id ? 1 : 0 ) );
 }
@@ -61,21 +71,27 @@ backsql_cmp_oc_id( const void *v_m1, const void *v_m2 )
 static int
 backsql_cmp_attr( const void *v_m1, const void *v_m2 )
 {
-       const backsql_at_map_rec *m1 = v_m1, *m2 = v_m2;
+       const backsql_at_map_rec        *m1 = v_m1,
+                                       *m2 = v_m2;
 
-#if 0
+#ifdef BACKSQL_USE_PTR_CMP
        return SLAP_PTRCMP( m1->bam_ad, m2->bam_ad );
-#endif
+#else /* ! BACKSQL_USE_PTR_CMP */
        return ber_bvcmp( &m1->bam_ad->ad_cname, &m2->bam_ad->ad_cname );
+#endif /* ! BACKSQL_USE_PTR_CMP */
 }
 
 int
 backsql_dup_attr( void *v_m1, void *v_m2 )
 {
-       backsql_at_map_rec *m1 = v_m1, *m2 = v_m2;
+       backsql_at_map_rec              *m1 = v_m1,
+                                       *m2 = v_m2;
 
        assert( m1->bam_ad == m2->bam_ad );
-       
+
+       /* duplicate definitions of attributeTypes are appended;
+        * this allows to define multiple rules for the same 
+        * attributeType.  Use with care! */
        for ( ; m1->bam_next ; m1 = m1->bam_next );
        m1->bam_next = m2;
        m2->bam_next = NULL;
@@ -103,7 +119,7 @@ backsql_make_attr_query(
                        &oc_map->bom_keycol,
                        (ber_len_t)STRLENOF( "=?" ), "=?" );
 
-       if ( at_map->bam_join_where.bv_val != NULL ) {
+       if ( !BER_BVISNULL( &at_map->bam_join_where ) ) {
                backsql_strfcat( &bb, "lb",
                                (ber_len_t)STRLENOF( " AND " ), " AND ", 
                                &at_map->bam_join_where );
@@ -140,23 +156,56 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
        backsql_merge_from_clause( &bb, &oc_map->bom_keytbl );
        at_map->bam_from_tbls = bb.bb_val;
 
-       bb.bb_val.bv_val = NULL;
-       bb.bb_val.bv_len = 0;
+       BER_BVZERO( &bb.bb_val );
        bb.bb_len = 0;
        backsql_strfcat( &bb, "lbcblb",
-                       (ber_len_t)STRLENOF( "ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=" ),
-                               "ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=",
+                       (ber_len_t)STRLENOF( "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=" ),
+                               "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=",
                        &oc_map->bom_keytbl, 
                        '.', 
                        &oc_map->bom_keycol,
                        (ber_len_t)STRLENOF( " and ldap_entries.oc_map_id=" ), 
                                " and ldap_entries.oc_map_id=", 
                        &sbv );
+       at_map->bam_join_where = bb.bb_val;
 
        at_map->bam_oc = oc_map->bom_oc;
-       at_map->bam_join_where = bb.bb_val;
+
        at_map->bam_add_proc = NULL;
+       {
+               char    tmp[] =
+                       "INSERT INTO ldap_entry_objclasses "
+                       "(entry_id,oc_name) VALUES "
+                       "((SELECT id FROM ldap_entries "
+                       "WHERE oc_map_id="
+                       "18446744073709551615UL "       /* 64 bit ULONG */
+                       "AND keyval=?),?)";
+               snprintf( tmp, sizeof(tmp), 
+                       "INSERT INTO ldap_entry_objclasses "
+                       "(entry_id,oc_name) VALUES "
+                       "((SELECT id FROM ldap_entries "
+                       "WHERE oc_map_id=%lu "
+                       "AND keyval=?),?)", oc_map->bom_id );
+               at_map->bam_add_proc = ch_strdup( tmp );
+       }
+
        at_map->bam_delete_proc = NULL;
+       {
+               char    tmp[] =
+                       "DELETE FROM ldap_entry_objclasses "
+                       "WHERE entry_id=(SELECT id FROM ldap_entries "
+                       "WHERE oc_map_id="
+                       "18446744073709551615UL "       /* 64 bit ULONG */
+                       "AND keyval=?) AND oc_name=?";
+               snprintf( tmp, sizeof(tmp), 
+                       "DELETE FROM ldap_entry_objclasses "
+                       "WHERE entry_id=(SELECT id FROM ldap_entries "
+                       "WHERE oc_map_id=%lu"
+                       "AND keyval=?) AND oc_name=?",
+                       oc_map->bom_id );
+               at_map->bam_delete_proc = ch_strdup( tmp );
+       }
+
        at_map->bam_param_order = 0;
        at_map->bam_expect_return = 0;
        at_map->bam_next = NULL;
@@ -169,6 +218,22 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
                                oc_map->bom_oc->soc_cname.bv_val, 0 );
        }
 
+       /* FIXME: whe need to correct the objectClass join_where 
+        * after the attribute query is built */
+       ch_free( at_map->bam_join_where.bv_val );
+       BER_BVZERO( &bb.bb_val );
+       bb.bb_len = 0;
+       backsql_strfcat( &bb, "lbcblb",
+                       (ber_len_t)STRLENOF( "ldap_entries.keyval=" ),
+                               "ldap_entries.keyval=",
+                       &oc_map->bom_keytbl, 
+                       '.', 
+                       &oc_map->bom_keycol,
+                       (ber_len_t)STRLENOF( " AND ldap_entries.oc_map_id=" ), 
+                               " AND ldap_entries.oc_map_id=", 
+                       &sbv );
+       at_map->bam_join_where = bb.bb_val;
+
        /* referral attribute */
        at_map = (backsql_at_map_rec *)ch_calloc( 1, 
                        sizeof( backsql_at_map_rec ) );
@@ -181,23 +246,57 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
        backsql_merge_from_clause( &bb, &oc_map->bom_keytbl );
        at_map->bam_from_tbls = bb.bb_val;
 
-       bb.bb_val.bv_val = NULL;
-       bb.bb_val.bv_len = 0;
+       BER_BVZERO( &bb.bb_val );
        bb.bb_len = 0;
        backsql_strfcat( &bb, "lbcblb",
-                       (ber_len_t)STRLENOF( "ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=" ),
-                               "ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=",
+                       (ber_len_t)STRLENOF( "ldap_entries.id=ldap_referrals.entry_id AND ldap_entries.keyval=" ),
+                               "ldap_entries.id=ldap_referrals.entry_id AND ldap_entries.keyval=",
                        &oc_map->bom_keytbl, 
                        '.', 
                        &oc_map->bom_keycol,
-                       (ber_len_t)STRLENOF( " and ldap_entries.oc_map_id=" ), 
-                               " and ldap_entries.oc_map_id=", 
+                       (ber_len_t)STRLENOF( " AND ldap_entries.oc_map_id=" ), 
+                               " AND ldap_entries.oc_map_id=", 
                        &sbv );
 
-       at_map->bam_oc = NULL;
        at_map->bam_join_where = bb.bb_val;
+
+       at_map->bam_oc = NULL;
+
        at_map->bam_add_proc = NULL;
+       {
+               char    tmp[] =
+                       "INSERT INTO ldap_referrals "
+                       "(entry_id,url) VALUES "
+                       "((SELECT id FROM ldap_entries "
+                       "WHERE oc_map_id="
+                       "18446744073709551615UL "       /* 64 bit ULONG */
+                       "AND keyval=?),?)";
+               snprintf( tmp, sizeof(tmp), 
+                       "INSERT INTO ldap_referrals "
+                       "(entry_id,url) VALUES "
+                       "((SELECT id FROM ldap_entries "
+                       "WHERE oc_map_id=%lu "
+                       "AND keyval=?),?)", oc_map->bom_id );
+               at_map->bam_add_proc = ch_strdup( tmp );
+       }
+
        at_map->bam_delete_proc = NULL;
+       {
+               char    tmp[] =
+                       "DELETE FROM ldap_referrals "
+                       "WHERE entry_id=(SELECT id FROM ldap_entries "
+                       "WHERE oc_map_id="
+                       "18446744073709551615UL "       /* 64 bit ULONG */
+                       "AND keyval=?) and url=?";
+               snprintf( tmp, sizeof(tmp), 
+                       "DELETE FROM ldap_referrals "
+                       "WHERE entry_id=(SELECT id FROM ldap_entries "
+                       "WHERE oc_map_id=%lu"
+                       "AND keyval=?) and url=?",
+                       oc_map->bom_id );
+               at_map->bam_delete_proc = ch_strdup( tmp );
+       }
+
        at_map->bam_param_order = 0;
        at_map->bam_expect_return = 0;
        at_map->bam_next = NULL;
@@ -295,8 +394,7 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
 
                ber_str2bv( at_row.cols[ 1 ], 0, 1, &at_map->bam_sel_expr );
                if ( at_row.value_len[ 8 ] < 0 ) {
-                       at_map->bam_sel_expr_u.bv_val = NULL;
-                       at_map->bam_sel_expr_u.bv_len = 0;
+                       BER_BVZERO( &at_map->bam_sel_expr_u );
 
                } else {
                        ber_str2bv( at_row.cols[ 8 ], 0, 1, 
@@ -307,8 +405,7 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
                backsql_merge_from_clause( &bb, &bv );
                at_map->bam_from_tbls = bb.bb_val;
                if ( at_row.value_len[ 3 ] < 0 ) {
-                       at_map->bam_join_where.bv_val = NULL;
-                       at_map->bam_join_where.bv_len = 0;
+                       BER_BVZERO( &at_map->bam_join_where );
 
                } else {
                        ber_str2bv( at_row.cols[ 3 ], 0, 1, 
@@ -339,7 +436,9 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
                                        oc_map->bom_oc->soc_cname.bv_val, 0 );
                }
 
-               if ( bas->bas_si->upper_func.bv_val && at_map->bam_sel_expr_u.bv_val == NULL ) {
+               if ( !BER_BVISNULL( &bas->bas_si->upper_func ) &&
+                               BER_BVISNULL( &at_map->bam_sel_expr_u ) )
+               {
                        struct berbuf   bb = BB_NULL;
 
                        backsql_strfcat( &bb, "bcbc",
@@ -353,6 +452,12 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
        backsql_FreeRow( &at_row );
        SQLFreeStmt( bas->bas_sth, SQL_CLOSE );
 
+       Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(\"%s\"): "
+               "autoadding 'objectClass' and 'ref' mappings\n",
+               BACKSQL_OC_NAME( oc_map ), 0, 0 );
+
+       (void)backsql_add_sysmaps( oc_map );
+
        return BACKSQL_AVL_CONTINUE;
 }
 
@@ -481,12 +586,6 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
                        "add=%d, del=%d; attributes:\n",
                        BACKSQL_IS_ADD( oc_map->bom_expect_return ), 
                        BACKSQL_IS_DEL( oc_map->bom_expect_return ), 0 );
-
-               Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
-                       "autoadding 'objectClass' and 'ref' mappings\n",
-                       0, 0, 0 );
-
-               backsql_add_sysmaps( oc_map );
        }
 
        backsql_FreeRow( &oc_row );
@@ -736,10 +835,10 @@ backsql_free_attr( void *v_at )
        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 ) {
+       if ( !BER_BVISNULL( &at->bam_from_tbls ) ) {
                ch_free( at->bam_from_tbls.bv_val );
        }
-       if ( at->bam_join_where.bv_val != NULL ) {
+       if ( !BER_BVISNULL( &at->bam_join_where ) ) {
                ch_free( at->bam_join_where.bv_val );
        }
        if ( at->bam_add_proc != NULL ) {
@@ -753,7 +852,7 @@ backsql_free_attr( void *v_at )
        }
 
        /* TimesTen */
-       if ( at->bam_sel_expr_u.bv_val ) {
+       if ( !BER_BVISNULL( &at->bam_sel_expr_u ) ) {
                ch_free( at->bam_sel_expr_u.bv_val );
        }
 
index ed43829b12ce0de978507c1fcc38b6a54d140c8c..7f9c4ab8abbaa5e8c2a3c618ba1810e7eba86f0a 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include "ac/string.h"
+#include "ac/ctype.h"
 
 #include "slap.h"
 #include "lber_pvt.h"
@@ -142,6 +143,7 @@ backsql_init_search(
 
                        } else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) {
                                continue;
+
                        } else if ( p->an_desc == slap_schema.si_ad_objectClass ) {
                                is_oc = 1;
                        }
@@ -409,11 +411,55 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f,
        }
 
        backsql_strfcat( &bsi->bsi_flt_where, "l", 
-                       (ber_len_t)sizeof( /* (' */ "')" ) - 1, /* ( */ "')" );
+                       (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" );
  
        return 1;
 }
 
+static int
+backsql_merge_from_tbls( backsql_srch_info *bsi, struct berval *from_tbls )
+{
+       if ( BER_BVISNULL( from_tbls ) ) {
+               return LDAP_SUCCESS;
+       }
+
+       if ( !BER_BVISNULL( &bsi->bsi_from.bb_val ) ) {
+               char    *start, *end, *tmp;
+
+               tmp = ch_strdup( from_tbls->bv_val );
+
+               for ( start = tmp, end = strchr( start, ',' ); start; ) {
+                       if ( end ) {
+                               end[0] = '\0';
+                       }
+
+                       if ( strstr( bsi->bsi_from.bb_val.bv_val, start) == NULL )
+                       {
+                               backsql_strfcat( &bsi->bsi_from, "cs", ',', start );
+                       }
+
+                       if ( end ) {
+                               /* in case there are spaces after the comma... */
+                               for ( start = &end[1]; isspace( start[0] ); start++ );
+                               if ( start[0] ) {
+                                       end = strchr( start, ',' );
+                               } else {
+                                       start = NULL;
+                               }
+                       } else {
+                               start = NULL;
+                       }
+               }
+
+               ch_free( tmp );
+
+       } else {
+               backsql_strfcat( &bsi->bsi_from, "b", from_tbls );
+       }
+
+       return LDAP_SUCCESS;
+}
+
 static int
 backsql_process_filter( backsql_srch_info *bsi, Filter *f )
 {
@@ -446,7 +492,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
 
        case LDAP_FILTER_NOT:
                backsql_strfcat( &bsi->bsi_flt_where, "l",
-                               (ber_len_t)sizeof( "NOT (" /* ) */ ) - 1,
+                               (ber_len_t)STRLENOF( "NOT (" /* ) */ ),
                                        "NOT (" /* ) */ );
                rc = backsql_process_filter( bsi, f->f_not );
                backsql_strfcat( &bsi->bsi_flt_where, "c", /* ( */ ')' );
@@ -523,19 +569,32 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                         * - a search for "top" will return everything
                         */
                        if ( is_object_subclass( oc, bsi->bsi_oc->bom_oc ) ) {
-                               goto filter_oc_success;
+                               static struct berval ldap_entry_objclasses = BER_BVC( "ldap_entry_objclasses" );
+
+                               backsql_merge_from_tbls( bsi, &ldap_entry_objclasses );
+
+                               backsql_strfcat( &bsi->bsi_flt_where, "lbl",
+                                               (ber_len_t)STRLENOF( "1=1 OR (ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entry_objclasses.oc_name='" /* ') */ ),
+                                                       "1=1 OR (ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entry_objclasses.oc_name='" /* ') */,
+                                               &bsi->bsi_oc->bom_oc->soc_cname,
+                                               (ber_len_t)STRLENOF( /* (' */ "')" ),
+                                                       /* (' */ "')" );
+                               bsi->bsi_status = LDAP_SUCCESS;
+                               rc = 1;
+                               goto done;
                        }
 
                        break;
                }
 
                case LDAP_FILTER_PRESENT:
-filter_oc_success:;
                        backsql_strfcat( &bsi->bsi_flt_where, "l",
                                        (ber_len_t)STRLENOF( "1=1" ), "1=1" );
                        bsi->bsi_status = LDAP_SUCCESS;
                        rc = 1;
                        goto done;
+
+                       /* FIXME: LDAP_FILTER_EXT? */
                        
                default:
                        Debug( LDAP_DEBUG_TRACE,
@@ -675,7 +734,7 @@ backsql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at,
 
                backsql_strfcat( &bsi->bsi_flt_where, "bl",
                                filter_value, 
-                               (ber_len_t)sizeof( /* (' */ "')" ) - 1,
+                               (ber_len_t)STRLENOF( /* (' */ "')" ),
                                        /* (' */ "')" );
 
                ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );
@@ -686,7 +745,7 @@ backsql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at,
                                &at->bam_sel_expr,
                                (ber_len_t)STRLENOF( "='" ), "='",
                                filter_value,
-                               (ber_len_t)sizeof( /* (' */ "')" ) - 1,
+                               (ber_len_t)STRLENOF( /* (' */ "')" ),
                                        /* (' */ "')" );
        }
 
@@ -716,7 +775,7 @@ backsql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at,
 
                backsql_strfcat( &bsi->bsi_flt_where, "bl",
                                filter_value, 
-                               (ber_len_t)sizeof( /* (' */ "%')" ) - 1,
+                               (ber_len_t)STRLENOF( /* (' */ "%')" ),
                                        /* (' */ "%')" );
 
                ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );
@@ -728,7 +787,7 @@ backsql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at,
                                (ber_len_t)STRLENOF( " LIKE '%" ),
                                        " LIKE '%",
                                filter_value,
-                               (ber_len_t)sizeof( /* (' */ "%')" ) - 1,
+                               (ber_len_t)STRLENOF( /* (' */ "%')" ),
                                        /* (' */ "%')" );
        }
 
@@ -747,16 +806,18 @@ backsql_process_filter_attr( backsql_srch_info *bsi, Filter *f, backsql_at_map_r
        Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter_attr(%s)\n",
                at->bam_ad->ad_cname.bv_val, 0, 0 );
 
-       backsql_merge_from_clause( &bsi->bsi_from, &at->bam_from_tbls );
-
        /*
         * need to add this attribute to list of attrs to load,
         * so that we can do test_filter() later
         */
        backsql_attrlist_add( bsi, at->bam_ad );
 
+       backsql_merge_from_tbls( bsi, &at->bam_from_tbls );
+
        if ( !BER_BVISNULL( &at->bam_join_where )
-                       && strstr( bsi->bsi_join_where.bb_val.bv_val, at->bam_join_where.bv_val ) == NULL ) {
+                       && strstr( bsi->bsi_join_where.bb_val.bv_val,
+                               at->bam_join_where.bv_val ) == NULL )
+       {
                backsql_strfcat( &bsi->bsi_join_where, "lb",
                                (ber_len_t)STRLENOF( " AND " ), " AND ",
                                &at->bam_join_where );
@@ -855,7 +916,7 @@ equality_match:;
 
                        backsql_strfcat( &bsi->bsi_flt_where, "bl",
                                        filter_value, 
-                                       (ber_len_t)sizeof( /* (' */ "')" ) - 1,
+                                       (ber_len_t)STRLENOF( /* (' */ "')" ),
                                                /* (' */ "')" );
 
                        ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );
@@ -867,17 +928,17 @@ equality_match:;
                                        &ordering,
                                        '\'',
                                        &f->f_av_value,
-                                       (ber_len_t)sizeof( /* (' */ "')" ) - 1,
+                                       (ber_len_t)STRLENOF( /* (' */ "')" ),
                                                /* ( */ "')" );
                }
                break;
 
        case LDAP_FILTER_PRESENT:
                backsql_strfcat( &bsi->bsi_flt_where, "lbl",
-                               (ber_len_t)sizeof( "NOT (" /* ) */) - 1,
+                               (ber_len_t)STRLENOF( "NOT (" /* ) */),
                                        "NOT (", /* ) */
                                &at->bam_sel_expr, 
-                               (ber_len_t)sizeof( /* ( */ " IS NULL)" ) - 1,
+                               (ber_len_t)STRLENOF( /* ( */ " IS NULL)" ),
                                        /* ( */ " IS NULL)" );
                break;
 
@@ -943,10 +1004,10 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
        if ( !BER_BVISNULL( &bi->strcast_func ) ) {
                backsql_strfcat( &bsi->bsi_sel, "blbl",
                                &bi->strcast_func, 
-                               (ber_len_t)sizeof( "('" /* ') */ ) - 1,
+                               (ber_len_t)STRLENOF( "('" /* ') */ ),
                                        "('" /* ') */ ,
                                &bsi->bsi_oc->bom_oc->soc_cname,
-                               (ber_len_t)sizeof( /* (' */ "')" ) - 1,
+                               (ber_len_t)STRLENOF( /* (' */ "')" ),
                                        /* (' */ "')" );
        } else {
                backsql_strfcat( &bsi->bsi_sel, "cbc",
@@ -1387,7 +1448,7 @@ backsql_search( Operation *op, SlapReply *rs )
 
        if ( op->o_req_ndn.bv_len > BACKSQL_MAX_DN_LEN ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
-                       "search base length (%ld) exceeds max length (%ld)\n", 
+                       "search base length (%ld) exceeds max length (%d)\n", 
                        op->o_req_ndn.bv_len, BACKSQL_MAX_DN_LEN, 0 );
                /*
                 * FIXME: a LDAP_NO_SUCH_OBJECT could be appropriate
@@ -1501,6 +1562,32 @@ backsql_search( Operation *op, SlapReply *rs )
                        continue;
                }
 
+               /* check scope */
+               switch ( op->ors_scope ) {
+               case LDAP_SCOPE_BASE:
+               case BACKSQL_SCOPE_BASE_LIKE:
+                       if ( !bvmatch( &user_entry.e_nname, &op->o_req_ndn ) ) {
+                               goto next_entry;
+                       }
+                       break;
+
+               case LDAP_SCOPE_ONE:
+               {
+                       struct berval   rdn = user_entry.e_nname;
+                       rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," );
+                       if ( !dnIsOneLevelRDN( &rdn ) ) {
+                               goto next_entry;
+                       }
+                       /* fall thru */
+               }
+
+               case LDAP_SCOPE_SUBTREE:
+                       if ( !dnIsSuffix( &user_entry.e_nname, &op->o_req_ndn ) ) {
+                               goto next_entry;
+                       }
+                       break;
+               }
+
                if ( !manageDSAit &&
                                op->ors_scope != LDAP_SCOPE_BASE &&
                                op->ors_scope != BACKSQL_SCOPE_BASE_LIKE &&
index 86b46893163929f3c865a7ce598cf4e51f0a3b33..7709f817de9cc4da892c1d4339ae8bf60a54c530 100644 (file)
@@ -145,6 +145,7 @@ backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row )
 #endif /* BACKSQL_TRACE */
                
                backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, sth, rc );
+
        } else {
 #ifdef BACKSQL_TRACE
                Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
@@ -270,6 +271,7 @@ int
 backsql_init_db_env( backsql_info *si )
 {
        RETCODE         rc;
+       int             ret = SQL_SUCCESS;
        
        Debug( LDAP_DEBUG_TRACE, "==>backsql_init_db_env()\n", 0, 0, 0 );
        rc = SQLAllocEnv( &si->db_env );
@@ -278,9 +280,10 @@ backsql_init_db_env( backsql_info *si )
                                0, 0, 0 );
                backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC,
                                SQL_NULL_HENV, rc );
+               ret = SQL_ERROR;
        }
-       Debug( LDAP_DEBUG_TRACE, "<==backsql_init_db_env()\n", 0, 0, 0 );
-       return SQL_SUCCESS;
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_init_db_env()=%d\n", ret, 0, 0 );
+       return ret;
 }
 
 int
@@ -303,7 +306,7 @@ backsql_free_db_env( backsql_info *si )
 }
 
 static int
-backsql_open_db_conn( backsql_info *si, int ldap_cid, backsql_db_conn **pdbc )
+backsql_open_db_conn( backsql_info *si, unsigned long ldap_cid, backsql_db_conn **pdbc )
 {
        /* TimesTen */
        char                    DBMSName[ 32 ];
@@ -389,7 +392,8 @@ int
 backsql_free_db_conn( Operation *op )
 {
        backsql_info            *si = (backsql_info *)op->o_bd->be_private;
-       backsql_db_conn         tmp, *conn;
+       backsql_db_conn         tmp = { 0 },
+                               *conn;
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_conn()\n", 0, 0, 0 );
        tmp.ldap_cid = op->o_connid;
@@ -414,8 +418,8 @@ int
 backsql_get_db_conn( Operation *op, SQLHDBC *dbh )
 {
        backsql_info            *si = (backsql_info *)op->o_bd->be_private;
-       backsql_db_conn         *dbc;
-       backsql_db_conn         tmp;
+       backsql_db_conn         *dbc,
+                               tmp = { 0 };
        int                     rc = LDAP_SUCCESS;
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_get_db_conn()\n", 0, 0, 0 );
index 4fb534ae26150606e08cfbc56c4f8a241f89b3ef..d70b884da35b823628b49990c925e30c65465de1 100644 (file)
@@ -173,7 +173,7 @@ backsql_strfcat( struct berbuf *dest, const char *fmt, ... )
                        cslen = va_arg( strs, ber_len_t );
                        cstr = va_arg( strs, char * );
                        break;
-                       
+
                /* string */
                case 's':
                        cstr = va_arg( strs, char * );