]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Fri, 30 Aug 2002 02:57:50 +0000 (02:57 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 30 Aug 2002 02:57:50 +0000 (02:57 +0000)
22 files changed:
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/init.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/search.c
servers/slapd/back-meta/add.c
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/init.c
servers/slapd/back-meta/modify.c
servers/slapd/back-monitor/external.h [new file with mode: 0644]
servers/slapd/back-monitor/init.c
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/init.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/other.c
servers/slapd/back-sql/schema-map.c
servers/slapd/back-sql/schema-map.h
servers/slapd/back-sql/search.c
servers/slapd/back-sql/util.c
servers/slapd/back-sql/util.h

index c12a313e8bd78d5ccbbdc07808f9cdb665c4885b..db1382042767276542b0a494b20eb69a4967c672 100644 (file)
@@ -134,6 +134,10 @@ ldap_back_add(
                }
 #endif
                
+               if ( a->a_desc->ad_type->sat_no_user_mod  ) {
+                       continue;
+               }
+
                ldap_back_map(&li->at_map, &a->a_desc->ad_cname, &mapped, 0);
                if (mapped.bv_val == NULL) {
                        continue;
index 92d5856fa1ff00c248a15e707f036e3d4ad69d10..e65ea665a6804aa5f274a95d9d08dbb0663bb4b6 100644 (file)
@@ -74,6 +74,14 @@ ldap_back_bind(
                return( -1 );
        }
 
+       if ( op->o_ctrls ) {
+               if ( ldap_set_option( lc->ld, LDAP_OPT_SERVER_CONTROLS,
+                                       op->o_ctrls ) != LDAP_SUCCESS ) {
+                       ldap_back_op_result( lc, op );
+                       return( -1 );
+               }
+       }
+       
        /*
         * Rewrite the bind dn if needed
         */
@@ -350,15 +358,23 @@ ldap_back_getconn(struct ldapinfo *li, Connection *conn, Operation *op)
  * it can be used to simplify the check.
  */
 int
-ldap_back_dobind(struct ldapconn *lc, Operation *op)
-{
-       if (lc->bound) {
+ldap_back_dobind( struct ldapconn *lc, Operation *op )
+{      
+       if ( op->o_ctrls ) {
+               if ( ldap_set_option( lc->ld, LDAP_OPT_SERVER_CONTROLS,
+                               op->o_ctrls ) != LDAP_SUCCESS ) {
+                       ldap_back_op_result( lc, op );
+                       return( 0 );
+               }
+       }
+       
+       if ( lc->bound ) {
                return( lc->bound );
        }
 
-       if (ldap_bind_s(lc->ld, lc->bound_dn.bv_val, lc->cred.bv_val, LDAP_AUTH_SIMPLE) !=
-               LDAP_SUCCESS) {
-               ldap_back_op_result(lc, op);
+       if ( ldap_bind_s( lc->ld, lc->bound_dn.bv_val, lc->cred.bv_val, 
+                               LDAP_AUTH_SIMPLE ) != LDAP_SUCCESS ) {
+               ldap_back_op_result( lc, op );
                return( 0 );
        } /* else */
        return( lc->bound = 1 );
index 2b4a1c81f93f08626acf720d46e3228b2c09b530..6cc3078363d59777a8dc757bf4b5911a8720fe70 100644 (file)
@@ -64,6 +64,8 @@ ldap_back_initialize(
     BackendInfo        *bi
 )
 {
+       bi->bi_controls = slap_known_controls;
+
        bi->bi_open = 0;
        bi->bi_config = 0;
        bi->bi_close = 0;
index 0bbb52e867201712336622da03e14e83028d760d..bea4dcbcd7506dad6d97c44963fd0492a01e4e91 100644 (file)
@@ -114,6 +114,10 @@ ldap_back_modify(
        }
 
        for (i=0, ml=modlist; ml; ml=ml->sml_next) {
+               if ( ml->sml_desc->ad_type->sat_no_user_mod  ) {
+                       continue;
+               }
+
                ldap_back_map(&li->at_map, &ml->sml_desc->ad_cname, &mapped, 0);
                if (mapped.bv_val == NULL) {
                        continue;
index c2e278d5c7da2d4da400cff694e41c624be0e41f..a80de47198fda54e65b57ed200fcbe6c1473ef70 100644 (file)
@@ -137,7 +137,14 @@ ldap_back_search(
                ldap_set_option( lc->ld, LDAP_OPT_TIMELIMIT, (void *)&tlimit);
        if (slimit != -1)
                ldap_set_option( lc->ld, LDAP_OPT_SIZELIMIT, (void *)&slimit);
-       
+
+
+       /*
+        * controls are set in ldap_back_dobind()
+        * 
+        * FIXME: in case of values return filter, we might want
+        * to map attrs and maybe rewrite value
+        */
        if ( !ldap_back_dobind( lc, op ) ) {
                return( -1 );
        }
@@ -455,12 +462,18 @@ ldap_send_entry(
                        continue;
                }
                
-               if (ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR ) {
+               if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
+                               || attr->a_vals == NULL ) {
+                       /*
+                        * Note: attr->a_vals can be null when using
+                        * values result filter
+                        */
                        attr->a_vals = &dummy;
+
                } else if ( attr->a_desc == slap_schema.si_ad_objectClass
                                || attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
                        int i, last;
-                       assert( attr->a_vals );
+
                        for ( last = 0; attr->a_vals[last].bv_val; last++ ) ;
                        for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
                                ldap_back_map(&li->oc_map, bv, &mapped, 1);
@@ -497,7 +510,6 @@ ldap_send_entry(
                } else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
                                        SLAPD_DN_SYNTAX ) == 0 ) {
                        int i;
-                       assert( attr->a_vals );
                        for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
                                struct berval newval;
                                
index 58555bbdfebd9b9e4d246ef7ebf6edf7d9f8cd4a..e0d52e1173816311c022a1b4b48b49cde1c3f008 100644 (file)
@@ -148,25 +148,11 @@ meta_back_add(
 
        for ( i = 0, a = e->e_attrs; a; a = a->a_next ) {
                int j;
-               /*
-                * lastmod should always be <off>, so that
-                * creation/modification operational attrs
-                * of the target directory are used, if available
-                */
-#if 0
-               if ( !strcasecmp( a->a_desc->ad_cname.bv_val,
-                       slap_schema.si_ad_creatorsName->ad_cname.bv_val )
-                       || !strcasecmp( a->a_desc->ad_cname.bv_val,
-                       slap_schema.si_ad_createTimestamp->ad_cname.bv_val )
-                       || !strcasecmp( a->a_desc->ad_cname.bv_val,
-                       slap_schema.si_ad_modifiersName->ad_cname.bv_val )
-                       || !strcasecmp( a->a_desc->ad_cname.bv_val,
-                       slap_schema.si_ad_modifyTimestamp->ad_cname.bv_val )
-               ) {
+
+               if ( a->a_desc->ad_type->sat_no_user_mod  ) {
                        continue;
                }
-#endif
-               
+
                ldap_back_map( &li->targets[ candidate ]->at_map,
                                &a->a_desc->ad_cname, &mapped, 0);
                if ( mapped.bv_val == NULL ) {
index 3bf9285cf00186f78a03b1dc1c013355694f5703..f14345a208268af751a6fb7b54f03a648f654aca 100644 (file)
@@ -151,18 +151,6 @@ struct metainfo {
        Avlnode                 *conntree;
 };
 
-extern int
-meta_back_do_single_bind(
-               struct metainfo         *li,
-               struct metaconn         *lc,
-               struct berval           *dn,
-               struct berval           *ndn,
-               struct berval           *cred,
-               int                     method,
-               int                     candidate
-);
-
-
 #define META_OP_ALLOW_MULTIPLE         0x00
 #define META_OP_REQUIRE_SINGLE         0x01
 #define META_OP_REQUIRE_ALL            0x02
index 8735d3e0946d836bcfdc21edc2d7d4c95f3d0a53..2a800c5c5c1728c445c48bf48902d70fbe23b2c5 100644 (file)
 #include "../back-ldap/back-ldap.h"
 #include "back-meta.h"
 
+static int
+meta_back_do_single_bind(
+               struct metainfo         *li,
+               struct metaconn         *lc,
+               Operation               *op,
+               struct berval           *dn,
+               struct berval           *ndn,
+               struct berval           *cred,
+               int                     method,
+               int                     candidate
+);
+
 int
 meta_back_bind(
                Backend         *be,
@@ -177,7 +189,7 @@ meta_back_bind(
                        realmethod = method;
                }
                
-               lerr = meta_back_do_single_bind( li, lc,
+               lerr = meta_back_do_single_bind( li, lc, op,
                                realdn, realndn, realcred, realmethod, i );
                if ( lerr != LDAP_SUCCESS ) {
                        err = lerr;
@@ -223,10 +235,11 @@ meta_back_bind(
  *
  * attempts to perform a bind with creds
  */
-int
+static int
 meta_back_do_single_bind(
                struct metainfo         *li,
                struct metaconn         *lc,
+               Operation               *op,
                struct berval           *dn,
                struct berval           *ndn,
                struct berval           *cred,
@@ -263,6 +276,15 @@ meta_back_do_single_bind(
                return LDAP_OTHER;
        }
 
+       if ( op->o_ctrls ) {
+               rc = ldap_set_option( lc->conns[ candidate ].ld, 
+                               LDAP_OPT_SERVER_CONTROLS, op->o_ctrls );
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = ldap_back_map_result( rc );
+                       goto return_results;
+               }
+       }
+       
        rc = ldap_bind_s( lc->conns[ candidate ].ld, mdn.bv_val, cred->bv_val, method );
        if ( rc != LDAP_SUCCESS ) {
                rc = ldap_back_map_result( rc );
@@ -277,6 +299,8 @@ meta_back_do_single_bind(
                                        ndn, candidate );
                }
        }
+
+return_results:;
        
        if ( mdn.bv_val != dn->bv_val ) {
                free( mdn.bv_val );
@@ -311,6 +335,17 @@ meta_back_dobind( struct metaconn *lc, Operation *op )
                        continue;
                }
 
+               /*
+                * If required, set controls
+                */
+               if ( op->o_ctrls ) {
+                       if ( ldap_set_option( lsc->ld, LDAP_OPT_SERVER_CONTROLS,
+                                       op->o_ctrls ) != LDAP_SUCCESS ) {
+                               ( void )meta_clear_one_candidate( lsc, 1 );
+                               continue;
+                       }
+               }
+       
                /*
                 * If the target is already bound it is skipped
                 */
@@ -329,6 +364,8 @@ meta_back_dobind( struct metaconn *lc, Operation *op )
                        lsc->bound_dn.bv_val = NULL;
                        lsc->bound_dn.bv_len = 0;
                }
+               
+
                rc = ldap_bind_s( lsc->ld, 0, NULL, LDAP_AUTH_SIMPLE );
                if ( rc != LDAP_SUCCESS ) {
                        
index 3ca62e4d52f1ce1bb8264c7d4f28ce535db4a980..eae98ba6aa90842217fceda899fca19004af8ce2 100644 (file)
@@ -95,6 +95,8 @@ meta_back_initialize(
                BackendInfo     *bi
 )
 {
+       bi->bi_controls = slap_known_controls;
+
        bi->bi_open = 0;
        bi->bi_config = 0;
        bi->bi_close = 0;
index 45429332c4bb8f233f0321d201b305607b3c0d14..b6890382c87a809c5504ec730c7b025978d9d02b 100644 (file)
@@ -152,21 +152,10 @@ meta_back_modify(
 
        for ( i = 0, ml = modlist; ml; ml = ml->sml_next ) {
                int j;
-               /*
-                * lastmod should always be <off>
-                */
-#if 0
-               if ( !strcasecmp( a->a_desc->ad_cname.bv_val,
-                       slap_schema.si_ad_creatorsName->ad_cname.bv_val )
-                       || !strcasecmp( a->a_desc->ad_cname.bv_val,
-                       slap_schema.si_ad_createTimestamp->ad_cname.bv_val )
-                       || !strcasecmp( a->a_desc->ad_cname.bv_val,
-                       slap_schema.si_ad_modifiersName->ad_cname.bv_val )
-                       || !strcasecmp( a->a_desc->ad_cname.bv_val,
-                       slap_schema.si_ad_modifyTimestamp->ad_cname.bv_val ) ) {
+
+               if ( ml->sml_desc->ad_type->sat_no_user_mod  ) {
                        continue;
                }
-#endif
 
                ldap_back_map( &li->targets[ candidate ]->at_map,
                                &ml->sml_desc->ad_cname, &mapped, 0 );
diff --git a/servers/slapd/back-monitor/external.h b/servers/slapd/back-monitor/external.h
new file mode 100644 (file)
index 0000000..48d4e44
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
+ * 
+ * This work has beed deveolped for the OpenLDAP Foundation 
+ * in the hope that it may be useful to the Open Source community, 
+ * but WITHOUT ANY WARRANTY.
+ * 
+ * Permission is granted to anyone to use this software for any purpose
+ * on any computer system, and to alter it and redistribute it, subject
+ * to the following restrictions:
+ * 
+ * 1. The author and SysNet s.n.c. are not responsible for the consequences
+ *    of use of this software, no matter how awful, even if they arise from
+ *    flaws in it.
+ * 
+ * 2. The origin of this software must not be misrepresented, either by
+ *    explicit claim or by omission.  Since few users ever read sources,
+ *    credits should appear in the documentation.
+ * 
+ * 3. Altered versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.  Since few users
+ *    ever read sources, credits should appear in the documentation.
+ *    SysNet s.n.c. cannot be responsible for the consequences of the
+ *    alterations.
+ * 
+ * 4. This notice may not be removed or altered.
+ */
+
+#ifndef _MONITOR_EXTERNAL_H
+#define _MONITOR_EXTERNAL_H
+
+LDAP_BEGIN_DECL
+
+extern BI_init monitor_back_initialize;
+extern BI_db_init      monitor_back_db_init;
+extern BI_db_open      monitor_back_db_open;
+extern BI_config       monitor_back_config;
+extern BI_db_config    monitor_back_db_config;
+
+extern BI_db_destroy   monitor_back_db_destroy;
+
+extern BI_op_search    monitor_back_search;
+extern BI_op_compare   monitor_back_compare;
+extern BI_op_modify    monitor_back_modify;
+extern BI_op_bind      monitor_back_bind;
+extern BI_operational  monitor_back_operational;
+
+LDAP_END_DECL
+
+#endif /* _MONITOR_EXTERNAL_H */
index 240f64e1119801307a6734fcd20d571e14c6f990..04ce6664ca9641039018e1b33ffd1aebb0c263c8 100644 (file)
@@ -37,6 +37,7 @@
 #include <ac/string.h>
 
 #include "slap.h"
+#include "lber_pvt.h"
 #include "back-monitor.h"
 
 /*
@@ -51,7 +52,7 @@ BackendDB *be_monitor = NULL;
 struct monitorsubsys monitor_subsys[] = {
        { 
                SLAPD_MONITOR_LISTENER, SLAPD_MONITOR_LISTENER_NAME,    
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_PERSISTENT_CH,
                monitor_subsys_listener_init,
                NULL,   /* update */
@@ -59,7 +60,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_DATABASE, SLAPD_MONITOR_DATABASE_NAME,    
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_PERSISTENT_CH,
                monitor_subsys_database_init,
                NULL,   /* update */
@@ -67,7 +68,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_BACKEND, SLAPD_MONITOR_BACKEND_NAME, 
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_PERSISTENT_CH,
                monitor_subsys_backend_init,
                NULL,   /* update */
@@ -75,7 +76,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_THREAD, SLAPD_MONITOR_THREAD_NAME,        
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_NONE,
                monitor_subsys_thread_init,
                monitor_subsys_thread_update,
@@ -83,7 +84,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_SASL, SLAPD_MONITOR_SASL_NAME,    
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_NONE,
                NULL,   /* init */
                NULL,   /* update */
@@ -91,7 +92,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_TLS, SLAPD_MONITOR_TLS_NAME,
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_NONE,
                NULL,   /* init */
                NULL,   /* update */
@@ -99,7 +100,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_CONN, SLAPD_MONITOR_CONN_NAME,
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_VOLATILE_CH,
                monitor_subsys_conn_init,
                monitor_subsys_conn_update,
@@ -107,7 +108,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_READW, SLAPD_MONITOR_READW_NAME,
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_NONE,
                NULL,   /* init */
                monitor_subsys_readw_update,
@@ -115,7 +116,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_WRITEW, SLAPD_MONITOR_WRITEW_NAME,
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_NONE,
                NULL,   /* init */
                monitor_subsys_writew_update,
@@ -123,7 +124,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL    /* modify */
                }, { 
                SLAPD_MONITOR_LOG, SLAPD_MONITOR_LOG_NAME,
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_NONE,
                monitor_subsys_log_init,
                NULL,   /* update */
@@ -131,7 +132,7 @@ struct monitorsubsys monitor_subsys[] = {
                monitor_subsys_log_modify
                }, { 
                SLAPD_MONITOR_OPS, SLAPD_MONITOR_OPS_NAME,
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_PERSISTENT_CH,
                monitor_subsys_ops_init,
                monitor_subsys_ops_update,
@@ -139,7 +140,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL,   /* modify */
                }, { 
                SLAPD_MONITOR_SENT, SLAPD_MONITOR_SENT_NAME,
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_PERSISTENT_CH,
                monitor_subsys_sent_init,
                monitor_subsys_sent_update,
@@ -147,7 +148,7 @@ struct monitorsubsys monitor_subsys[] = {
                NULL,   /* modify */
                }, { 
                SLAPD_MONITOR_TIME, SLAPD_MONITOR_TIME_NAME,
-               { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
+               BER_BVNULL, BER_BVNULL, BER_BVNULL,
                MONITOR_F_PERSISTENT_CH,
                monitor_subsys_time_init,
                monitor_subsys_time_update,
@@ -156,6 +157,22 @@ struct monitorsubsys monitor_subsys[] = {
        }, { -1, NULL }
 };
 
+#ifdef SLAPD_MONITOR_DYNAMIC
+
+int
+back_monitor_LTX_init_module( int argc, char *argv[] )
+{
+       BackendInfo bi;
+
+       memset( &bi, '\0', sizeof(bi) );
+       bi.bi_type = "monitor";
+       bi.bi_init = monitor_back_initialize;
+       backend_add( &bi );
+       return 0;
+}
+
+#endif /* SLAPD_MONITOR_DYNAMIC */
+
 int
 monitor_back_initialize(
        BackendInfo     *bi
@@ -170,14 +187,14 @@ monitor_back_initialize(
        bi->bi_controls = controls;
 
        bi->bi_init = 0;
-       bi->bi_open = monitor_back_open;
+       bi->bi_open = 0;
        bi->bi_config = monitor_back_config;
        bi->bi_close = 0;
        bi->bi_destroy = 0;
 
        bi->bi_db_init = monitor_back_db_init;
        bi->bi_db_config = monitor_back_db_config;
-       bi->bi_db_open = 0;
+       bi->bi_db_open = monitor_back_db_open;
        bi->bi_db_close = 0;
        bi->bi_db_destroy = monitor_back_db_destroy;
 
@@ -449,46 +466,17 @@ monitor_back_db_init(
 }
 
 int
-monitor_back_open(
-       BackendInfo     *bi
+monitor_back_db_open(
+       BackendDB       *be
 )
 {
-       BackendDB               *be;
        struct monitorsubsys    *ms;
-       struct berval dn = { sizeof(SLAPD_MONITOR_DN)-1, SLAPD_MONITOR_DN };
-       struct berval ndn;
-       int rc;
+
+       assert( be );
 
        /*
-        * adds the monitor backend
+        * opens the monitor backend
         */
-       rc = dnNormalize2( NULL, &dn, &ndn );
-       if( rc != LDAP_SUCCESS ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, CRIT,
-                       "monitor DN \"" SLAPD_MONITOR_DN "\" is invalid\n" , 0, 0, 0);
-#else
-               Debug( LDAP_DEBUG_ANY,
-                       "monitor DN \"" SLAPD_MONITOR_DN "\" is invalid\n",
-                       0, 0, 0 );
-#endif
-               return( -1 );
-       }
-
-       be = select_backend( &ndn , 0, 0 );
-       free( ndn.bv_val );
-
-       if ( be == NULL ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, CRIT,
-                       "unable to get monitor backend\n" , 0, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_ANY,
-                       "unable to get monitor backend\n", 0, 0, 0 );
-#endif
-               return( -1 );
-       }
-
        for ( ms = monitor_subsys; ms->mss_name != NULL; ms++ ) {
                if ( ms->mss_init && ( *ms->mss_init )( be ) ) {
                        return( -1 );
@@ -522,6 +510,9 @@ monitor_back_db_config(
        char        **argv
 )
 {
+       /*
+        * eventually, will hold database specific configuration parameters
+        */
 #ifdef NEW_LOGGING
        LDAP_LOG( CONFIG, INFO,
                "line %d of file '%s' will be ignored\n", lineno, fname, 0 );
index a456351479103a1cf41e4786d451930daf1331e0..2fb550867065986bdd19c4b9b6e66a4f4216fc0b 100644 (file)
  *                             statements (needed by PostgreSQL)
  *       - upper_needs_cast    cast the argument of upper when required
  *                             (basically when building dn substring queries)
+ *   - added noop control
+ *   - added values return filter control
+ *   - hasSubordinate can be used in search filters (with limitations)
+ *   - eliminated oc->name; use oc->oc->soc_cname instead
  * 
  * Todo:
  *   - add security checks for SQL statements that can be injected (?)
@@ -80,7 +84,6 @@
  */
 #undef BACKSQL_TRACE
 
-
 typedef struct {
        char            *dbhost;
        int             dbport;
index 90564463acf41fdccb85d7a275e12c162760725d..e1a45c7f1e9b6b36f8d0a89d4162bb168a508027 100644 (file)
@@ -14,6 +14,7 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include "ac/string.h"
+#include "lber_pvt.h"
 #include "ldap_pvt.h"
 #include "slap.h"
 #include "back-sql.h"
@@ -255,8 +256,7 @@ backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
  
        Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
                "oc='%s' attr='%s' keyval=%ld\n",
-               // bsi->oc->name.bv_val, at->name.bv_val, 
-               bsi->oc->oc->soc_names[0], at->ad->ad_cname.bv_val, 
+               BACKSQL_OC_NAME( bsi->oc ), at->ad->ad_cname.bv_val, 
                bsi->c_eid->keyval );
 
        rc = backsql_Prepare( bsi->dbh, &sth, at->query, 0 );
@@ -363,7 +363,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
 #if 0
                                backsql_entry_addattr( bsi->e, 
                                                &bv_n_objectclass,
-                                               &bsi->oc->name );
+                                               BACKSQL_OC_NAME( bsi->oc ) );
 #endif
                                continue;
                        }
@@ -376,7 +376,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
                                        "attribute '%s' is not defined "
                                        "for objectlass '%s'\n",
                                        attr->an_name.bv_val, 
-                                       bsi->oc->name.bv_val, 0 );
+                                       BACKSQL_OC_NAME( bsi->oc ), 0 );
                        }
                }
 
@@ -387,7 +387,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
                                bsi, 0, AVL_INORDER );
        }
 
-       if ( attr_merge_one( bsi->e, ad_oc, &bsi->oc->name ) ) {
+       if ( attr_merge_one( bsi->e, ad_oc, &bsi->oc->oc->soc_cname ) ) {
                entry_free( e );
                return NULL;
        }
@@ -396,7 +396,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
                const char      *text = NULL;
                char            textbuf[ 1024 ];
                size_t          textlen = sizeof( textbuf );
-               struct berval   bv[ 2 ] = { bsi->oc->name, { 0, NULL } };
+               struct berval   bv[ 2 ] = { bsi->oc->oc->soc_cname, BER_BVNULL };
                struct berval   soc;
                AttributeDescription    *ad_soc
                        = slap_schema.si_ad_structuralObjectClass;
@@ -408,7 +408,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
                        return NULL;
                }
 
-               if ( bsi->attr_flags | BSQL_SF_ALL_OPER 
+               if ( bsi->bsi_flags | BSQL_SF_ALL_OPER 
                                || an_find( bsi->attrs, &AllOper ) ) {
                        if ( attr_merge_one( bsi->e, ad_soc, &soc ) ) {
                                entry_free( e );
index 3d4e30242fbbda57de828d00eec374d8b2a62a57..301646ccdab519c1d86c343cfa541499b7d1adc3 100644 (file)
@@ -43,6 +43,18 @@ int
 sql_back_initialize(
        BackendInfo     *bi )
 { 
+       static char *controls[] = {
+#ifdef LDAP_CONTROL_NOOP
+               LDAP_CONTROL_NOOP,
+#endif
+#ifdef LDAP_CONTROL_VALUESRETURNFILTER
+               LDAP_CONTROL_VALUESRETURNFILTER,
+#endif
+               NULL
+       };
+
+       bi->bi_controls = controls;
+
        Debug( LDAP_DEBUG_TRACE,"==>backsql_initialize()\n", 0, 0, 0 );
        
        bi->bi_open = 0;
index 6966c2c6fdb5bf136f361b0e63c3881631b8a67c..bff2f9f8ed8bf009cc40b39e3f5fde60058d6658 100644 (file)
@@ -549,9 +549,10 @@ backsql_modify(
                 * or if a single operation on an attribute fails 
                 * for any reason
                 */
-               SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
+               SQLTransact( SQL_NULL_HENV, dbh, 
+                               op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
        }
-       send_ldap_result( conn, op, res, "", text, NULL, NULL );
+       send_ldap_result( conn, op, res, NULL, text, NULL, NULL );
        Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
 
        return 0;
@@ -865,7 +866,8 @@ backsql_modrdn(
                 * or if a single operation on an attribute fails for any
                 * reason
                 */
-               SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
+               SQLTransact( SQL_NULL_HENV, dbh,
+                               op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
        }
 
 modrdn_return:
@@ -1239,7 +1241,7 @@ backsql_add(
                                "attribute '%s' is not registered "
                                "in objectclass '%s'\n",
                                at->a_desc->ad_cname.bv_val,
-                               oc->name.bv_val, 0 );
+                               BACKSQL_OC_NAME( oc ), 0 );
 
                        if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
                                send_ldap_result( conn, op, 
@@ -1312,7 +1314,7 @@ backsql_add(
                         * to build the entry
                         */
                        if ( at->a_desc == slap_schema.si_ad_objectClass ) {
-                               if ( ber_bvcmp( at_val, &oc->name ) == 0 ) {
+                               if ( bvmatch( at_val, &oc->oc->soc_cname ) ) {
                                        continue;
                                }
                        }
@@ -1411,7 +1413,8 @@ backsql_add(
         * or if a single operation on an attribute fails 
         * for any reason
         */
-       SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
+       SQLTransact( SQL_NULL_HENV, dbh, 
+                               op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
 
        send_ldap_result( conn, op, LDAP_SUCCESS, "",
                        NULL, NULL, NULL );
@@ -1570,7 +1573,8 @@ backsql_delete(
         * or if a single operation on an attribute fails 
         * for any reason
         */
-       SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
+       SQLTransact( SQL_NULL_HENV, dbh, 
+                               op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
 
        send_ldap_result( conn, op, LDAP_SUCCESS, "", NULL, NULL, NULL );
        Debug( LDAP_DEBUG_TRACE, "<==backsql_delete()\n", 0, 0, 0 );
index 1629a086e30b2b7f57619ec1f678cb83fc635935..b2638960f4c697c6b7f0ea3991e64db1183e92d4 100644 (file)
@@ -63,13 +63,18 @@ backsql_operational(
        backsql_info            *bi = (backsql_info*)be->be_private;
        SQLHDBC                 dbh = SQL_NULL_HDBC;
        Attribute               **aa = a;
-       int                     rc;
+       int                     rc = 0;
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry '%s'\n",
                        e->e_nname.bv_val, 0, 0 );
 
 
-       if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
+       if ( ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+                       && attr_find( e->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+                       ) {
+               
                rc = backsql_get_db_conn( be, conn, &dbh );
                if ( rc != LDAP_SUCCESS ) {
                        goto no_connection;
index eaa63ab69228919cf43f04952db6cba74bc7e243..d3a7956dcda41e3ce1115b8e08894019d7edceb1 100644 (file)
 #include <sys/types.h>
 #include <string.h>
 #include "slap.h"
+#include "lber_pvt.h"
 #include "ldap_pvt.h"
 #include "back-sql.h"
 #include "sql-wrap.h"
 #include "schema-map.h"
 #include "util.h"
 
-/*
- * Deprecated
- */
-#if 0
-static int
-backsql_cmp_oc_name( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
-{
-       return BACKSQL_NCMP( &m1->name, &m2->name );
-}
-#endif
-
 /*
  * Uses the pointer to the ObjectClass structure
  */
@@ -47,17 +37,6 @@ backsql_cmp_oc_id( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
        return ( m1->id < m2->id ? -1 : ( m1->id > m2->id ? 1 : 0 ) );
 }
 
-/*
- * Deprecated
- */
-#if 0
-static int
-backsql_cmp_attr_name( backsql_at_map_rec *m1, backsql_at_map_rec *m2 )
-{
-       return BACKSQL_NCMP( &m1->name, &m2->name );
-}
-#endif
-
 /*
  * Uses the pointer to the AttributeDescription structure
  */
@@ -72,7 +51,7 @@ backsql_make_attr_query(
        backsql_oc_map_rec      *oc_map,
        backsql_at_map_rec      *at_map )
 {
-       struct berval   tmps = { 0, NULL };
+       struct berval   tmps = BER_BVNULL;
        ber_len_t       tmpslen = 0;
 
        backsql_strfcat( &tmps, &tmpslen, "lblblblbcbl", 
@@ -250,12 +229,11 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
 
                oc_map->id = strtol( oc_row.cols[ 0 ], NULL, 0 );
 
-               ber_str2bv( oc_row.cols[ 1 ], 0, 1, &oc_map->name );
-               oc_map->oc = oc_bvfind( &oc_map->name );
+               oc_map->oc = oc_find( oc_row.cols[ 1 ] );
                if ( oc_map->oc == NULL ) {
                        Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
                                "objectClass '%s' is not defined in schema\n", 
-                               oc_map->name.bv_val, 0, 0 );
+                               oc_row.cols[ 1 ], 0, 0 );
                        return LDAP_OTHER;      /* undefined objectClass ? */
                }
                
@@ -288,7 +266,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
                oc_id = oc_map->id;
                Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
                        "objectClass '%s': keytbl='%s' keycol='%s'\n",
-                       oc_map->name.bv_val, 
+                       BACKSQL_OC_NAME( oc_map ),
                        oc_map->keytbl.bv_val, oc_map->keycol.bv_val );
                if ( oc_map->create_proc ) {
                        Debug( LDAP_DEBUG_TRACE, "create_proc='%s'\n",
@@ -349,7 +327,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
                                        "attribute '%s' for objectClass '%s' "
                                        "is not defined in schema: %s\n", 
                                        at_map->ad->ad_cname.bv_val, 
-                                       oc_map->name.bv_val, text );
+                                       BACKSQL_OC_NAME( oc_map ), text );
                                return LDAP_CONSTRAINT_VIOLATION;
                        }
                                
@@ -415,7 +393,8 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc )
 #ifdef BACKSQL_TRACE
        if ( res != NULL ) {
                Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
-                       "found name='%s', id=%d\n", res->name, res->id, 0 );
+                       "found name='%s', id=%d\n", 
+                       BACKSQL_OC_NAME( res ), res->id, 0 );
        } else {
                Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
                        "not found\n", 0, 0, 0 );
@@ -425,9 +404,6 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc )
        return res;
 }
 
-/*
- * Deprecated
- */
 backsql_oc_map_rec *
 backsql_name2oc( backsql_info *si, struct berval *oc_name )
 {
@@ -449,7 +425,8 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name )
 #ifdef BACKSQL_TRACE
        if ( res != NULL ) {
                Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
-                       "found name='%s', id=%d\n", res->name, res->id, 0 );
+                       "found name='%s', id=%d\n", 
+                       BACKSQL_OC_NAME( res ), res->id, 0 );
        } else {
                Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
                        "not found\n", 0, 0, 0 );
@@ -476,7 +453,8 @@ backsql_id2oc( backsql_info *si, unsigned long id )
 #ifdef BACKSQL_TRACE
        if ( res != NULL ) {
                Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
-                       "found name='%s', id=%d\n", res->name, res->id, 0 );
+                       "found name='%s', id=%d\n",
+                       BACKSQL_OC_NAME( res ), res->id, 0 );
        } else {
                Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
                        "not found\n", 0, 0, 0 );
@@ -494,7 +472,7 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
 #ifdef BACKSQL_TRACE
        Debug( LDAP_DEBUG_TRACE, "==>backsql_ad2at(): "
                "searching for attribute '%s' for objectclass '%s'\n",
-               attr, objclass->name, 0 );
+               attr, BACKSQL_OC_NAME( objclass ), 0 );
 #endif /* BACKSQL_TRACE */
 
        tmp.ad = ad;
@@ -505,7 +483,7 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
        if ( res != NULL ) {
                Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
                        "found name='%s', sel_expr='%s'\n",
-                       res->name, res->sel_expr.bv_val, 0 );
+                       res->ad->ad_cname.bv_val, res->sel_expr.bv_val, 0 );
        } else {
                Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
                        "not found\n", 0, 0, 0 );
@@ -527,7 +505,7 @@ backsql_name2at( backsql_oc_map_rec* objclass, struct berval *attr )
 #ifdef BACKSQL_TRACE
        Debug( LDAP_DEBUG_TRACE, "==>backsql_name2at(): "
                "searching for attribute '%s' for objectclass '%s'\n",
-               attr, objclass->name, 0 );
+               attr, BACKSQL_OC_NAME( objclass ), 0 );
 #endif /* BACKSQL_TRACE */
 
        if ( slap_bv2ad( attr, &tmp.ad, &text ) != LDAP_SUCCESS ) {
@@ -587,9 +565,8 @@ static void
 backsql_free_oc( backsql_oc_map_rec *oc )
 {
        Debug( LDAP_DEBUG_TRACE, "==>free_oc(): '%s'\n", 
-                       oc->name.bv_val, 0, 0 );
+                       BACKSQL_OC_NAME( oc ), 0, 0 );
        avl_free( oc->attrs, (AVL_FREE)backsql_free_attr );
-       ch_free( oc->name.bv_val );
        ch_free( oc->keytbl.bv_val );
        ch_free( oc->keycol.bv_val );
        if ( oc->create_proc != NULL ) {
index 7c7f0cf39efeba05a3e81fb77c01ed49784c0041..5467523fad8bd2ec28b249ce1d522788ab019c4d 100644 (file)
  */
 
 typedef struct {
-       /*
-        * FIXME: we explicitly keep the objectClass name because
-        * the ObjectClass structure does not use bervals (yet?)
-        */
-       struct berval   name;
        /*
         * Structure of corresponding LDAP objectClass definition
         */
        ObjectClass     *oc;
+#define BACKSQL_OC_NAME(ocmap) ((ocmap)->oc->soc_cname.bv_val)
+       
        struct berval   keytbl;
        struct berval   keycol;
        /* expected to return keyval of newly created entry */
index ffd1856fd8715168f192d75b725c450b36f10d0d..462eba442693becafdd1018ff590c365ab44197a 100644 (file)
 #include "entry-id.h"
 #include "util.h"
 
+#define BACKSQL_STOP           0
+#define BACKSQL_CONTINUE       1
+
+static int backsql_process_filter( backsql_srch_info *bsi, Filter *f );
+
 static int
 backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
 {
@@ -33,6 +38,15 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
                return 1;
        }
 
+       /*
+        * clear the list (retrieve all attrs)
+        */
+       if ( ad == NULL ) {
+               ch_free( bsi->attrs );
+               bsi->attrs = NULL;
+               return 1;
+       }
+
        for ( ; bsi->attrs[ n_attrs ].an_name.bv_val; n_attrs++ ) {
                an = &bsi->attrs[ n_attrs ];
                
@@ -94,12 +108,8 @@ backsql_init_search(
        bsi->be = be;
        bsi->conn = conn;
        bsi->op = op;
-       bsi->attr_flags = 0;
+       bsi->bsi_flags = 0;
 
-       /*
-        * FIXME: need to discover how to deal with 1.1 (NoAttrs)
-        */
-       
        /*
         * handle "*"
         */
@@ -114,13 +124,13 @@ backsql_init_search(
                
                for ( p = attrs; p->an_name.bv_val; p++ ) {
                        /*
-                        * ignore "+"
+                        * ignore "1.1"; handle "+"
                         */
                        if ( BACKSQL_NCMP( &p->an_name, &AllOper ) == 0 ) {
+                               bsi->bsi_flags |= BSQL_SF_ALL_OPER;
                                continue;
 
                        } else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) {
-                               bsi->attr_flags |= BSQL_SF_ALL_OPER;
                                continue;
                        }
 
@@ -149,7 +159,7 @@ backsql_init_search(
        bsi->status = LDAP_SUCCESS;
 }
 
-int
+static int
 backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
 {
        int             res;
@@ -195,7 +205,7 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
        return 1;
 }
 
-int
+static int
 backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
 {
        int                     i;
@@ -301,13 +311,13 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
        return 1;
 }
 
-int
+static int
 backsql_process_filter( backsql_srch_info *bsi, Filter *f )
 {
        backsql_at_map_rec      *at;
        backsql_at_map_rec      oc_attr = {
                slap_schema.si_ad_objectClass, BER_BVC(""), BER_BVC(""), 
-               { 0, NULL }, NULL, NULL, NULL };
+               BER_BVNULL, NULL, NULL, NULL };
        AttributeDescription    *ad = NULL;
        int                     done = 0;
        ber_len_t               len = 0;
@@ -328,7 +338,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                
        case LDAP_FILTER_AND:
                rc = backsql_process_filter_list( bsi, f->f_and,
-                               LDAP_FILTER_AND);
+                               LDAP_FILTER_AND );
                done = 1;
                break;
 
@@ -346,6 +356,10 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                ad = f->f_desc;
                break;
                
+       case LDAP_FILTER_EXT:
+               ad = f->f_mra->ma_desc;
+               break;
+               
        default:
                ad = f->f_av_desc;
                break;
@@ -360,23 +374,58 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                goto done;
        }
 
-       if ( ad != slap_schema.si_ad_objectClass ) {
-               at = backsql_ad2at( bsi->oc, ad );
-
-       } else {
+       /*
+        * Turn structuralObjectClass into objectClass
+        */
+       if ( ad == slap_schema.si_ad_objectClass 
+                       || ad == slap_schema.si_ad_structuralObjectClass ) {
                at = &oc_attr;
                backsql_strfcat( &at->sel_expr, &len, "cbc",
                                '\'', 
-                               &bsi->oc->name, 
+                               &bsi->oc->oc->soc_cname, 
                                '\'' );
+
+#if defined(SLAP_X_FILTER_HASSUBORDINATES) || defined(SLAP_X_MRA_MATCH_DNATTRS)
+       } else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) {
+               /*
+                * FIXME: this is not robust; e.g. a filter
+                * '(!(hasSubordinates=TRUE))' fails because
+                * in SQL it would read 'NOT (1=1)' instead 
+                * of no condition.  
+                * Note however that hasSubordinates is boolean, 
+                * so a more appropriate filter would be 
+                * '(hasSubordinates=FALSE)'
+                */
+               backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
+                               (ber_len_t)sizeof( "1=1" ) - 1, "1=1" );
+               if ( ad != NULL ) {
+                       /*
+                        * We use this flag since we need to parse
+                        * the filter anyway; we should have used
+                        * the frontend API function
+                        * filter_has_subordinates()
+                        */
+                       bsi->bsi_flags |= BSQL_SF_FILTER_HASSUBORDINATE;
+               } else {
+                       /*
+                        * clear attributes to fetch, to require ALL
+                        * and try extended match on all attributes
+                        */
+                       backsql_attrlist_add( bsi, NULL );
+               }
+               goto done;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES || SLAP_X_MRA_MATCH_DNATTRS */
+               
+       } else {
+               at = backsql_ad2at( bsi->oc, ad );
        }
 
        if ( at == NULL ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
                        "attribute '%s' is not defined for objectclass '%s'\n",
-                       ad->ad_cname.bv_val, bsi->oc->name.bv_val, 0 );
+                       ad->ad_cname.bv_val, BACKSQL_OC_NAME( bsi->oc ), 0 );
                backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
-                               (ber_len_t)sizeof( " 1=0 " ) - 1, " 1=0 " );
+                               (ber_len_t)sizeof( "1=0" ) - 1, "1=0" );
                goto impossible;
        }
 
@@ -461,6 +510,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                break;
 
        case LDAP_FILTER_GE:
+               /*
+                * FIXME: should we uppercase the operands?
+                */
                backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "cblbc",
                                '(' /* ) */ ,
                                &at->sel_expr,
@@ -470,6 +522,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                break;
                
        case LDAP_FILTER_LE:
+               /*
+                * FIXME: should we uppercase the operands?
+                */
                backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "cblbc",
                                '(' /* ) */ ,
                                &at->sel_expr,
@@ -558,13 +613,13 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
                                &bi->strcast_func, 
                                (ber_len_t)sizeof( "('" /* ') */ ) - 1,
                                        "('" /* ') */ ,
-                               &bsi->oc->name,
+                               &bsi->oc->oc->soc_cname,
                                (ber_len_t)sizeof( /* (' */ "')" ) - 1,
                                        /* (' */ "')" );
        } else {
                backsql_strfcat( &bsi->sel, &bsi->sel_len, "cbc",
                                '\'',
-                               &bsi->oc->name,
+                               &bsi->oc->oc->soc_cname,
                                '\'' );
        }
        backsql_strfcat( &bsi->sel, &bsi->sel_len, "l",
@@ -669,12 +724,14 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
        int                     j;
  
        Debug(  LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc='%s'\n",
-                       oc->name.bv_val, 0, 0 );
+                       BACKSQL_OC_NAME( oc ), 0, 0 );
 
        if ( bsi->n_candidates == -1 ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
                        "unchecked limit has been overcome\n", 0, 0, 0 );
-               return 1;
+               /* should never get here */
+               assert( 0 );
+               return BACKSQL_STOP;
        }
        
        bsi->oc = oc;
@@ -682,7 +739,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
                Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
                        "could not construct query for objectclass\n",
                        0, 0, 0 );
-               return 1;
+               return BACKSQL_CONTINUE;
        }
 
        Debug( LDAP_DEBUG_TRACE, "Constructed query: %s\n", 
@@ -694,13 +751,13 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
                Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
                        "error preparing query\n", 0, 0, 0 );
                backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
-               return 1;
+               return BACKSQL_CONTINUE;
        }
 
        if ( backsql_BindParamID( sth, 1, &bsi->oc->id ) != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
                        "error binding objectclass id parameter\n", 0, 0, 0 );
-               return 1;
+               return BACKSQL_CONTINUE;
        }
 
        switch ( bsi->scope ) {
@@ -712,7 +769,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
                                "error binding base_dn parameter\n", 0, 0, 0 );
                        backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, 
                                        sth, rc );
-                       return 1;
+                       return BACKSQL_CONTINUE;
                }
                break;
 
@@ -771,7 +828,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
                                0, 0, 0 );
                        backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, 
                                        sth, rc );
-                       return 1;
+                       return BACKSQL_CONTINUE;
                }
                break;
        }
@@ -785,7 +842,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
                                res == LDAP_NO_SUCH_OBJECT ? ": no such entry"
                                : "", 0, 0 );
                        bsi->status = res;
-                       return 0;
+                       return BACKSQL_CONTINUE;
                }
                
                rc = backsql_BindParamID( sth, 2, &base_id.id );
@@ -793,7 +850,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
                if ( rc != SQL_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
                                "error binding base id parameter\n", 0, 0, 0 );
-                       return 1;
+                       return BACKSQL_CONTINUE;
                }
                break;
        }
@@ -804,7 +861,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
                        "error executing query\n", 0, 0, 0 );
                backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
-               return 1;
+               return BACKSQL_CONTINUE;
        }
 
        backsql_BindRowAsStrings( sth, &row );
@@ -833,7 +890,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
 
        Debug( LDAP_DEBUG_TRACE, "<==backsql_oc_get_candidates()\n", 0, 0, 0 );
 
-       return 1;
+       return ( bsi->n_candidates == -1 ? BACKSQL_STOP : BACKSQL_CONTINUE );
 }
 
 int
@@ -980,7 +1037,7 @@ backsql_search(
        srch_info.n_candidates = ( isroot ? -2 : limit->lms_s_unchecked == -1 
                        ? -2 : limit->lms_s_unchecked );
        avl_apply( bi->oc_by_oc, (AVL_APPLY)backsql_oc_get_candidates,
-                       &srch_info, 0, AVL_INORDER );
+                       &srch_info, BACKSQL_STOP, AVL_INORDER );
        if ( !isroot && limit->lms_s_unchecked != -1 ) {
                if ( srch_info.n_candidates == -1 ) {
                        send_search_result( conn, op,
@@ -998,6 +1055,10 @@ backsql_search(
         */
        for ( eid = srch_info.id_list; eid != NULL; 
                        eid = backsql_free_entryID( eid, 1 ) ) {
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+               Attribute       *hasSubordinate = NULL,
+                               *a = NULL;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
                /* check for abandon */
                if ( op->o_abandon ) {
@@ -1035,10 +1096,68 @@ backsql_search(
                        continue;
                }
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+               /*
+                * We use this flag since we need to parse the filter
+                * anyway; we should have used the frontend API function
+                * filter_has_subordinates()
+                */
+               if ( srch_info.bsi_flags & BSQL_SF_FILTER_HASSUBORDINATE ) {
+                       int             rc;
+
+                       rc = backsql_has_children( bi, dbh, &entry->e_nname );
+
+                       switch( rc ) {
+                       case LDAP_COMPARE_TRUE:
+                       case LDAP_COMPARE_FALSE:
+                               hasSubordinate = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
+                               if ( hasSubordinate != NULL ) {
+                                       for ( a = entry->e_attrs; 
+                                                       a && a->a_next; 
+                                                       a = a->a_next );
+
+                                       a->a_next = hasSubordinate;
+                               }
+                               rc = 0;
+                               break;
+
+                       default:
+                               Debug(LDAP_DEBUG_TRACE, 
+                                       "backsql_search(): "
+                                       "has_children failed( %d)\n", 
+                                       rc, 0, 0 );
+                               rc = 1;
+                               break;
+                       }
+
+                       if ( rc ) {
+                               continue;
+                       }
+               }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
                if ( test_filter( be, conn, op, entry, filter ) 
                                == LDAP_COMPARE_TRUE ) {
-                       sres = send_search_entry( be, conn, op, entry,
-                                       attrs, attrsonly, NULL );
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+                       if ( hasSubordinate && !( srch_info.bsi_flags & BSQL_SF_ALL_OPER ) 
+                                       && !ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
+                               a->a_next = NULL;
+                               attr_free( hasSubordinate );
+                               hasSubordinate = NULL;
+                       }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
+#if 0  /* noop is masked SLAP_CTRL_UPDATE */
+                       if ( op->o_noop ) {
+                               sres = 0;
+                       } else {
+#endif
+                               sres = send_search_entry( be, conn, op, entry,
+                                               attrs, attrsonly, NULL );
+#if 0
+                       }
+#endif
+
                        switch ( sres ) {
                        case 0:
                                nentries++;
index ffd10efc9516e7f813661025ee440e895a0aeb3f..402d36fbab5aa077fa292080e8129bc5fcd5aa50 100644 (file)
@@ -273,7 +273,7 @@ char *
 backsql_get_table_spec( char **p )
 {
        char            *s, *q;
-       struct berval   res = { 0, NULL };
+       struct berval   res = BER_BVNULL;
        ber_len_t       res_len = 0;
 
        assert( p );
index a9f1042d03d0e34836d97358f4da73587041d284..06e38d5824b19db090b7f251c87e2b291609a3d7 100644 (file)
@@ -42,14 +42,14 @@ typedef struct backsql_srch_info {
        Connection              *conn;
        Operation               *op;
        AttributeName           *attrs;
-       int                     attr_flags;
-#define        BSQL_SF_ALL_OPER        0x0001
+       int                     bsi_flags;
+#define        BSQL_SF_ALL_OPER                0x0001
+#define BSQL_SF_FILTER_HASSUBORDINATE  0x0002
        Entry                   *e;
        /* 1 if the db is TimesTen; 0 if it's not */
        int                     use_reverse_dn; 
 } backsql_srch_info;
 
-int backsql_process_filter( backsql_srch_info *bsi, Filter *f );
 void backsql_init_search( backsql_srch_info *bsi, backsql_info *bi,
                struct berval *nbase, int scope, int slimit, int tlimit,
                time_t stoptime, Filter *filter, SQLHDBC dbh,