From: Kurt Zeilenga Date: Fri, 30 Aug 2002 02:57:50 +0000 (+0000) Subject: Sync with HEAD X-Git-Tag: OPENLDAP_REL_ENG_2_1_5~88 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=92b22b242751e202a6ddcbf34e338f22a097dc58;p=openldap Sync with HEAD --- diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c index c12a313e8b..db13820427 100644 --- a/servers/slapd/back-ldap/add.c +++ b/servers/slapd/back-ldap/add.c @@ -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; diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 92d5856fa1..e65ea665a6 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -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 ); diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index 2b4a1c81f9..6cc3078363 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -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; diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c index 0bbb52e867..bea4dcbcd7 100644 --- a/servers/slapd/back-ldap/modify.c +++ b/servers/slapd/back-ldap/modify.c @@ -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; diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index c2e278d5c7..a80de47198 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -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; diff --git a/servers/slapd/back-meta/add.c b/servers/slapd/back-meta/add.c index 58555bbdfe..e0d52e1173 100644 --- a/servers/slapd/back-meta/add.c +++ b/servers/slapd/back-meta/add.c @@ -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 , 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 ) { diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 3bf9285cf0..f14345a208 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -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 diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 8735d3e094..2a800c5c5c 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -77,6 +77,18 @@ #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 ) { diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c index 3ca62e4d52..eae98ba6aa 100644 --- a/servers/slapd/back-meta/init.c +++ b/servers/slapd/back-meta/init.c @@ -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; diff --git a/servers/slapd/back-meta/modify.c b/servers/slapd/back-meta/modify.c index 45429332c4..b6890382c8 100644 --- a/servers/slapd/back-meta/modify.c +++ b/servers/slapd/back-meta/modify.c @@ -152,21 +152,10 @@ meta_back_modify( for ( i = 0, ml = modlist; ml; ml = ml->sml_next ) { int j; - /* - * lastmod should always be - */ -#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 index 0000000000..48d4e446df --- /dev/null +++ b/servers/slapd/back-monitor/external.h @@ -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. + * + * 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 */ diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c index 240f64e111..04ce6664ca 100644 --- a/servers/slapd/back-monitor/init.c +++ b/servers/slapd/back-monitor/init.c @@ -37,6 +37,7 @@ #include #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 ); diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index a456351479..2fb5508670 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -49,6 +49,10 @@ * 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; diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index 90564463ac..e1a45c7f1e 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -14,6 +14,7 @@ #include #include #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 ); diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index 3d4e30242f..301646ccda 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -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; diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index 6966c2c6fd..bff2f9f8ed 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -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 ); diff --git a/servers/slapd/back-sql/other.c b/servers/slapd/back-sql/other.c index 1629a086e3..b2638960f4 100644 --- a/servers/slapd/back-sql/other.c +++ b/servers/slapd/back-sql/other.c @@ -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; diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c index eaa63ab692..d3a7956dcd 100644 --- a/servers/slapd/back-sql/schema-map.c +++ b/servers/slapd/back-sql/schema-map.c @@ -15,23 +15,13 @@ #include #include #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 ) { diff --git a/servers/slapd/back-sql/schema-map.h b/servers/slapd/back-sql/schema-map.h index 7c7f0cf39e..5467523fad 100644 --- a/servers/slapd/back-sql/schema-map.h +++ b/servers/slapd/back-sql/schema-map.h @@ -11,15 +11,12 @@ */ 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 */ diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index ffd1856fd8..462eba4426 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -23,6 +23,11 @@ #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++; diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c index ffd10efc95..402d36fbab 100644 --- a/servers/slapd/back-sql/util.c +++ b/servers/slapd/back-sql/util.c @@ -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 ); diff --git a/servers/slapd/back-sql/util.h b/servers/slapd/back-sql/util.h index a9f1042d03..06e38d5824 100644 --- a/servers/slapd/back-sql/util.h +++ b/servers/slapd/back-sql/util.h @@ -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,