}
#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;
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
*/
* 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 );
BackendInfo *bi
)
{
+ bi->bi_controls = slap_known_controls;
+
bi->bi_open = 0;
bi->bi_config = 0;
bi->bi_close = 0;
}
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;
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 );
}
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);
} 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;
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 ) {
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
#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,
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;
*
* 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,
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 );
ndn, candidate );
}
}
+
+return_results:;
if ( mdn.bv_val != dn->bv_val ) {
free( mdn.bv_val );
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
*/
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 ) {
BackendInfo *bi
)
{
+ bi->bi_controls = slap_known_controls;
+
bi->bi_open = 0;
bi->bi_config = 0;
bi->bi_close = 0;
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 );
--- /dev/null
+/*
+ * 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 */
#include <ac/string.h>
#include "slap.h"
+#include "lber_pvt.h"
#include "back-monitor.h"
/*
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 */
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 */
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 */
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,
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 */
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 */
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,
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,
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,
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 */
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,
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,
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,
}, { -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
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;
}
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 );
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 );
* 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 (?)
*/
#undef BACKSQL_TRACE
-
typedef struct {
char *dbhost;
int dbport;
#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"
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 );
#if 0
backsql_entry_addattr( bsi->e,
&bv_n_objectclass,
- &bsi->oc->name );
+ BACKSQL_OC_NAME( bsi->oc ) );
#endif
continue;
}
"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 );
}
}
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;
}
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;
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 );
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;
* 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;
* 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:
"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,
* 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;
}
}
* 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 );
* 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 );
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;
#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
*/
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
*/
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",
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 ? */
}
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",
"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;
}
#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 );
return res;
}
-/*
- * Deprecated
- */
backsql_oc_map_rec *
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 );
#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 );
#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;
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 );
#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 ) {
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 ) {
*/
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 */
#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 )
{
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 ];
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 "*"
*/
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;
}
bsi->status = LDAP_SUCCESS;
}
-int
+static int
backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
{
int res;
return 1;
}
-int
+static int
backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
{
int i;
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;
case LDAP_FILTER_AND:
rc = backsql_process_filter_list( bsi, f->f_and,
- LDAP_FILTER_AND);
+ LDAP_FILTER_AND );
done = 1;
break;
ad = f->f_desc;
break;
+ case LDAP_FILTER_EXT:
+ ad = f->f_mra->ma_desc;
+ break;
+
default:
ad = f->f_av_desc;
break;
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;
}
break;
case LDAP_FILTER_GE:
+ /*
+ * FIXME: should we uppercase the operands?
+ */
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "cblbc",
'(' /* ) */ ,
&at->sel_expr,
break;
case LDAP_FILTER_LE:
+ /*
+ * FIXME: should we uppercase the operands?
+ */
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "cblbc",
'(' /* ) */ ,
&at->sel_expr,
&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",
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;
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",
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 ) {
"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;
0, 0, 0 );
backsql_PrintErrors( bsi->bi->db_env, bsi->dbh,
sth, rc );
- return 1;
+ return BACKSQL_CONTINUE;
}
break;
}
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 );
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;
}
"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 );
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc_get_candidates()\n", 0, 0, 0 );
- return 1;
+ return ( bsi->n_candidates == -1 ? BACKSQL_STOP : BACKSQL_CONTINUE );
}
int
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,
*/
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 ) {
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++;
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 );
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,