X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fback-meta%2Fconfig.c;h=924ed88754fdb12282ecc511ff4b01b872c6bfd4;hb=d0e86d485dd4c99b3469aa40fec19994894b3463;hp=e4197a4000cf0054a75a33849f133f9656d3d944;hpb=0f1522418ebb621affa4aa819c7e4241deb4f015;p=openldap
diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c
index e4197a4000..924ed88754 100644
--- a/servers/slapd/back-meta/config.c
+++ b/servers/slapd/back-meta/config.c
@@ -1,7 +1,7 @@
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software .
*
- * Copyright 1999-2011 The OpenLDAP Foundation.
+ * Copyright 1999-2012 The OpenLDAP Foundation.
* Portions Copyright 2001-2003 Pierangelo Masarati.
* Portions Copyright 1999-2003 Howard Chu.
* All rights reserved.
@@ -28,27 +28,492 @@
#include
#include "slap.h"
+#include "config.h"
#include "lutil.h"
#include "../back-ldap/back-ldap.h"
#include "back-meta.h"
+#ifdef LDAP_DEVEL
+#define SLAP_AUTH_DN 1
+#endif
+
+static ConfigDriver meta_back_cf_gen;
+static ConfigLDAPadd meta_ldadd;
+static ConfigCfAdd meta_cfadd;
+
+static int ldap_back_map_config(
+ ConfigArgs *c,
+ struct ldapmap *oc_map,
+ struct ldapmap *at_map );
+
+/* Three sets of enums:
+ * 1) attrs that are only valid in the base config
+ * 2) attrs that are valid in base or target
+ * 3) attrs that are only valid in a target
+ */
+
+/* Base attrs */
+enum {
+ LDAP_BACK_CFG_CONN_TTL = 1,
+ LDAP_BACK_CFG_DNCACHE_TTL,
+ LDAP_BACK_CFG_IDLE_TIMEOUT,
+ LDAP_BACK_CFG_ONERR,
+ LDAP_BACK_CFG_PSEUDOROOT_BIND_DEFER,
+ LDAP_BACK_CFG_SINGLECONN,
+ LDAP_BACK_CFG_USETEMP,
+ LDAP_BACK_CFG_CONNPOOLMAX,
+ LDAP_BACK_CFG_LAST_BASE
+};
+
+/* Base or target */
+enum {
+ LDAP_BACK_CFG_BIND_TIMEOUT = LDAP_BACK_CFG_LAST_BASE,
+ LDAP_BACK_CFG_CANCEL,
+ LDAP_BACK_CFG_CHASE,
+ LDAP_BACK_CFG_CLIENT_PR,
+ LDAP_BACK_CFG_DEFAULT_T,
+ LDAP_BACK_CFG_NETWORK_TIMEOUT,
+ LDAP_BACK_CFG_NOREFS,
+ LDAP_BACK_CFG_NOUNDEFFILTER,
+ LDAP_BACK_CFG_NRETRIES,
+ LDAP_BACK_CFG_QUARANTINE,
+ LDAP_BACK_CFG_REBIND,
+ LDAP_BACK_CFG_TIMEOUT,
+ LDAP_BACK_CFG_VERSION,
+ LDAP_BACK_CFG_ST_REQUEST,
+ LDAP_BACK_CFG_T_F,
+ LDAP_BACK_CFG_TLS,
+ LDAP_BACK_CFG_LAST_BOTH
+};
+
+/* Target attrs */
+enum {
+ LDAP_BACK_CFG_URI = LDAP_BACK_CFG_LAST_BOTH,
+ LDAP_BACK_CFG_ACL_AUTHCDN,
+ LDAP_BACK_CFG_ACL_PASSWD,
+ LDAP_BACK_CFG_IDASSERT_AUTHZFROM,
+ LDAP_BACK_CFG_IDASSERT_BIND,
+ LDAP_BACK_CFG_REWRITE,
+ LDAP_BACK_CFG_SUFFIXM,
+ LDAP_BACK_CFG_MAP,
+ LDAP_BACK_CFG_SUBTREE_EX,
+ LDAP_BACK_CFG_SUBTREE_IN,
+ LDAP_BACK_CFG_PSEUDOROOTDN,
+ LDAP_BACK_CFG_PSEUDOROOTPW,
+
+ LDAP_BACK_CFG_LAST
+};
+
+static ConfigTable metacfg[] = {
+ { "uri", "uri", 2, 0, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_URI,
+ meta_back_cf_gen, "( OLcfgDbAt:0.14 "
+ "NAME 'olcDbURI' "
+ "DESC 'URI (list) for remote DSA' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "tls", "what", 2, 0, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_TLS,
+ meta_back_cf_gen, "( OLcfgDbAt:3.1 "
+ "NAME 'olcDbStartTLS' "
+ "DESC 'StartTLS' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "acl-authcDN", "DN", 2, 2, 0,
+ ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN,
+ meta_back_cf_gen, "( OLcfgDbAt:3.2 "
+ "NAME 'olcDbACLAuthcDn' "
+ "DESC 'Remote ACL administrative identity' "
+ "OBSOLETE "
+ "SYNTAX OMsDN "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ /* deprecated, will be removed; aliases "acl-authcDN" */
+ { "binddn", "DN", 2, 2, 0,
+ ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN,
+ meta_back_cf_gen, NULL, NULL, NULL },
+ { "acl-passwd", "cred", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD,
+ meta_back_cf_gen, "( OLcfgDbAt:3.3 "
+ "NAME 'olcDbACLPasswd' "
+ "DESC 'Remote ACL administrative identity credentials' "
+ "OBSOLETE "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ /* deprecated, will be removed; aliases "acl-passwd" */
+ { "bindpw", "cred", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD,
+ meta_back_cf_gen, NULL, NULL, NULL },
+ { "idassert-bind", "args", 2, 0, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_BIND,
+ meta_back_cf_gen, "( OLcfgDbAt:3.7 "
+ "NAME 'olcDbIDAssertBind' "
+ "DESC 'Remote Identity Assertion administrative identity auth bind configuration' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "idassert-authzFrom", "authzRule", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHZFROM,
+ meta_back_cf_gen, "( OLcfgDbAt:3.9 "
+ "NAME 'olcDbIDAssertAuthzFrom' "
+ "DESC 'Remote Identity Assertion authz rules' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString "
+ "X-ORDERED 'VALUES' )",
+ NULL, NULL },
+ { "rebind-as-user", "true|FALSE", 1, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_REBIND,
+ meta_back_cf_gen, "( OLcfgDbAt:3.10 "
+ "NAME 'olcDbRebindAsUser' "
+ "DESC 'Rebind as user' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "chase-referrals", "true|FALSE", 2, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_CHASE,
+ meta_back_cf_gen, "( OLcfgDbAt:3.11 "
+ "NAME 'olcDbChaseReferrals' "
+ "DESC 'Chase referrals' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "t-f-support", "true|FALSE|discover", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_T_F,
+ meta_back_cf_gen, "( OLcfgDbAt:3.12 "
+ "NAME 'olcDbTFSupport' "
+ "DESC 'Absolute filters support' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "timeout", "timeout(list)", 2, 0, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_TIMEOUT,
+ meta_back_cf_gen, "( OLcfgDbAt:3.14 "
+ "NAME 'olcDbTimeout' "
+ "DESC 'Per-operation timeouts' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "idle-timeout", "timeout", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_IDLE_TIMEOUT,
+ meta_back_cf_gen, "( OLcfgDbAt:3.15 "
+ "NAME 'olcDbIdleTimeout' "
+ "DESC 'connection idle timeout' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "conn-ttl", "ttl", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_CONN_TTL,
+ meta_back_cf_gen, "( OLcfgDbAt:3.16 "
+ "NAME 'olcDbConnTtl' "
+ "DESC 'connection ttl' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "network-timeout", "timeout", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_NETWORK_TIMEOUT,
+ meta_back_cf_gen, "( OLcfgDbAt:3.17 "
+ "NAME 'olcDbNetworkTimeout' "
+ "DESC 'connection network timeout' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "protocol-version", "version", 2, 2, 0,
+ ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_VERSION,
+ meta_back_cf_gen, "( OLcfgDbAt:3.18 "
+ "NAME 'olcDbProtocolVersion' "
+ "DESC 'protocol version' "
+ "SYNTAX OMsInteger "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "single-conn", "true|FALSE", 2, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_SINGLECONN,
+ meta_back_cf_gen, "( OLcfgDbAt:3.19 "
+ "NAME 'olcDbSingleConn' "
+ "DESC 'cache a single connection per identity' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "cancel", "ABANDON|ignore|exop", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_CANCEL,
+ meta_back_cf_gen, "( OLcfgDbAt:3.20 "
+ "NAME 'olcDbCancel' "
+ "DESC 'abandon/ignore/exop operations when appropriate' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "quarantine", "retrylist", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_QUARANTINE,
+ meta_back_cf_gen, "( OLcfgDbAt:3.21 "
+ "NAME 'olcDbQuarantine' "
+ "DESC 'Quarantine database if connection fails and retry according to rule' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "use-temporary-conn", "true|FALSE", 2, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_USETEMP,
+ meta_back_cf_gen, "( OLcfgDbAt:3.22 "
+ "NAME 'olcDbUseTemporaryConn' "
+ "DESC 'Use temporary connections if the cached one is busy' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "conn-pool-max", "", 2, 2, 0,
+ ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_CONNPOOLMAX,
+ meta_back_cf_gen, "( OLcfgDbAt:3.23 "
+ "NAME 'olcDbConnectionPoolMax' "
+ "DESC 'Max size of privileged connections pool' "
+ "SYNTAX OMsInteger "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+ { "session-tracking-request", "true|FALSE", 2, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_ST_REQUEST,
+ meta_back_cf_gen, "( OLcfgDbAt:3.24 "
+ "NAME 'olcDbSessionTrackingRequest' "
+ "DESC 'Add session tracking control to proxied requests' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+ { "norefs", "true|FALSE", 2, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_NOREFS,
+ meta_back_cf_gen, "( OLcfgDbAt:3.25 "
+ "NAME 'olcDbNoRefs' "
+ "DESC 'Do not return search reference responses' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "noundeffilter", "true|FALSE", 2, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_NOUNDEFFILTER,
+ meta_back_cf_gen, "( OLcfgDbAt:3.26 "
+ "NAME 'olcDbNoUndefFilter' "
+ "DESC 'Do not propagate undefined search filters' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+
+ { "rewrite", "arglist", 2, 0, STRLENOF( "rewrite" ),
+ ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
+ meta_back_cf_gen, "( OLcfgDbAt:3.101 "
+ "NAME 'olcDbRewrite' "
+ "DESC 'DN rewriting rules' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString "
+ "X-ORDERED 'VALUES' )",
+ NULL, NULL },
+ { "suffixmassage", "virtual> [*|] *|]", 1, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_DEFAULT_T,
+ meta_back_cf_gen, "( OLcfgDbAt:3.105 "
+ "NAME 'olcDbDefaultTarget' "
+ "DESC 'Specify the default target' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "dncache-ttl", "ttl", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_DNCACHE_TTL,
+ meta_back_cf_gen, "( OLcfgDbAt:3.106 "
+ "NAME 'olcDbDnCacheTtl' "
+ "DESC 'dncache ttl' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "bind-timeout", "microseconds", 2, 2, 0,
+ ARG_MAGIC|ARG_ULONG|LDAP_BACK_CFG_BIND_TIMEOUT,
+ meta_back_cf_gen, "( OLcfgDbAt:3.107 "
+ "NAME 'olcDbBindTimeout' "
+ "DESC 'bind timeout' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "onerr", "CONTINUE|report|stop", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_ONERR,
+ meta_back_cf_gen, "( OLcfgDbAt:3.108 "
+ "NAME 'olcDbOnErr' "
+ "DESC 'error handling' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "pseudoroot-bind-defer", "TRUE|false", 2, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_PSEUDOROOT_BIND_DEFER,
+ meta_back_cf_gen, "( OLcfgDbAt:3.109 "
+ "NAME 'olcDbPseudoRootBindDefer' "
+ "DESC 'error handling' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "root-bind-defer", "TRUE|false", 2, 2, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_PSEUDOROOT_BIND_DEFER,
+ meta_back_cf_gen, NULL, NULL, NULL },
+ { "pseudorootdn", "dn", 2, 2, 0,
+ ARG_MAGIC|ARG_DN|LDAP_BACK_CFG_PSEUDOROOTDN,
+ meta_back_cf_gen, NULL, NULL, NULL },
+ { "pseudorootpw", "password", 2, 2, 0,
+ ARG_MAGIC|ARG_STRING|LDAP_BACK_CFG_PSEUDOROOTDN,
+ meta_back_cf_gen, NULL, NULL, NULL },
+ { "nretries", "NEVER|forever|", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_NRETRIES,
+ meta_back_cf_gen, "( OLcfgDbAt:3.110 "
+ "NAME 'olcDbNretries' "
+ "DESC 'retry handling' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+ { "client-pr", "accept-unsolicited|disable|", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_CLIENT_PR,
+ meta_back_cf_gen, "( OLcfgDbAt:3.111 "
+ "NAME 'olcDbClientPr' "
+ "DESC 'PagedResults handling' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
+
+ { "", "", 0, 0, 0, ARG_IGNORED,
+ NULL, "( OLcfgDbAt:3.100 NAME 'olcMetaSub' "
+ "DESC 'Placeholder to name a Target entry' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE X-ORDERED 'SIBLINGS' )", NULL, NULL },
+
+ { NULL, NULL, 0, 0, 0, ARG_IGNORED,
+ NULL, NULL, NULL, NULL }
+};
+
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+#define ST_ATTR "$ olcDbSessionTrackingRequest "
+#else
+#define ST_ATTR ""
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
+#define COMMON_ATTRS \
+ "$ olcDbBindTimeout " \
+ "$ olcDbCancel " \
+ "$ olcDbChaseReferrals " \
+ "$ olcDbClientPr " \
+ "$ olcDbDefaultTarget " \
+ "$ olcDbNetworkTimeout " \
+ "$ olcDbNoRefs " \
+ "$ olcDbNoUndefFilter " \
+ "$ olcDbNretries " \
+ "$ olcDbProtocolVersion " \
+ "$ olcDbQuarantine " \
+ "$ olcDbRebindAsUser " \
+ ST_ATTR \
+ "$ olcDbStartTLS " \
+ "$ olcDbTFSupport "
+
+static ConfigOCs metaocs[] = {
+ { "( OLcfgDbOc:3.2 "
+ "NAME 'olcMetaConfig' "
+ "DESC 'Meta backend configuration' "
+ "SUP olcDatabaseConfig "
+ "MAY ( olcDbConnTtl "
+ "$ olcDbDnCacheTtl "
+ "$ olcDbIdleTimeout "
+ "$ olcDbOnErr "
+ "$ olcDbPseudoRootBindDefer "
+ "$ olcDbSingleConn "
+ "$ olcDbUseTemporaryConn "
+ "$ olcDbConnectionPoolMax "
+
+ /* defaults, may be overridden per-target */
+ COMMON_ATTRS
+ ") )",
+ Cft_Database, metacfg, NULL, meta_cfadd },
+ { "( OLcfgDbOc:3.3 "
+ "NAME 'olcMetaTargetConfig' "
+ "DESC 'Meta target configuration' "
+ "SUP olcConfig STRUCTURAL "
+ "MUST ( olcMetaSub $ olcDbURI ) "
+ "MAY ( olcDbACLAuthcDn "
+ "$ olcDbACLPasswd "
+ "$ olcDbIDAssertAuthzFrom "
+ "$ olcDbIDAssertBind "
+ "$ olcDbMap "
+ "$ olcDbRewrite "
+ "$ olcDbSubtreeExclude "
+ "$ olcDbSubtreeInclude "
+ "$ olcDbTimeout "
+
+ /* defaults may be inherited */
+ COMMON_ATTRS
+ ") )",
+ Cft_Misc, metacfg, meta_ldadd },
+ { NULL, 0, NULL }
+};
+
static int
-meta_back_new_target(
- metatarget_t **mtp )
+meta_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *c )
{
- char *rargv[ 3 ];
- metatarget_t *mt;
+ if ( p->ce_type != Cft_Database || !p->ce_be ||
+ p->ce_be->be_cf_ocs != metaocs )
+ return LDAP_CONSTRAINT_VIOLATION;
- *mtp = NULL;
+ c->be = p->ce_be;
+ return LDAP_SUCCESS;
+}
- mt = ch_calloc( sizeof( metatarget_t ), 1 );
+static int
+meta_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *c )
+{
+ metainfo_t *mi = ( metainfo_t * )c->be->be_private;
+ struct berval bv;
+ int i;
- mt->mt_rwmap.rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
- if ( mt->mt_rwmap.rwm_rw == NULL ) {
- ch_free( mt );
- return -1;
+ bv.bv_val = c->cr_msg;
+ for ( i=0; imi_ntargets; i++ ) {
+ bv.bv_len = snprintf( c->cr_msg, sizeof(c->cr_msg),
+ "olcMetaSub=" SLAP_X_ORDERED_FMT "uri", i );
+ c->ca_private = mi->mi_targets[i];
+ c->valx = i;
+ config_build_entry( op, rs, p->e_private, c,
+ &bv, &metaocs[1], NULL );
}
+ return LDAP_SUCCESS;
+}
+
+static int
+meta_rwi_init( struct rewrite_info **rwm_rw )
+{
+ char *rargv[ 3 ];
+
+ *rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
+ if ( *rwm_rw == NULL ) {
+ return -1;
+ }
/*
* the filter rewrite as a string must be disabled
* by default; it can be re-enabled by adding rules;
@@ -57,12 +522,30 @@ meta_back_new_target(
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "searchFilter";
rargv[ 2 ] = NULL;
- rewrite_parse( mt->mt_rwmap.rwm_rw, "", 1, 2, rargv );
+ rewrite_parse( *rwm_rw, "", 1, 2, rargv );
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "default";
rargv[ 2 ] = NULL;
- rewrite_parse( mt->mt_rwmap.rwm_rw, "", 1, 2, rargv );
+ rewrite_parse( *rwm_rw, "", 1, 2, rargv );
+
+ return 0;
+}
+
+static int
+meta_back_new_target(
+ metatarget_t **mtp )
+{
+ metatarget_t *mt;
+
+ *mtp = NULL;
+
+ mt = ch_calloc( sizeof( metatarget_t ), 1 );
+
+ if ( meta_rwi_init( &mt->mt_rwmap.rwm_rw )) {
+ ch_free( mt );
+ return -1;
+ }
ldap_pvt_thread_mutex_init( &mt->mt_uri_mutex );
@@ -78,27 +561,134 @@ meta_back_new_target(
return 0;
}
+/* Validation for suffixmassage_config */
static int
-check_true_false( char *str )
+meta_suffixm_config(
+ ConfigArgs *c,
+ int argc,
+ char **argv,
+ metatarget_t *mt
+)
{
- if ( strcasecmp( str, "true" ) == 0 || strcasecmp( str, "yes" ) == 0 ) {
+ BackendDB *tmp_bd;
+ struct berval dn, nvnc, pvnc, nrnc, prnc;
+ int j, rc;
+
+ /*
+ * syntax:
+ *
+ * suffixmassage
+ *
+ * the field must be defined as a valid suffix
+ * (or suffixAlias?) for the current database;
+ * the shouldn't have already been
+ * defined as a valid suffix or suffixAlias for the
+ * current server
+ */
+
+ ber_str2bv( argv[ 1 ], 0, 0, &dn );
+ if ( dnPrettyNormal( NULL, &dn, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "suffix \"%s\" is invalid",
+ argv[1] );
+ Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
+ return 1;
+ }
+
+ for ( j = 0; !BER_BVISNULL( &c->be->be_nsuffix[ j ] ); j++ ) {
+ if ( dnIsSuffix( &nvnc, &c->be->be_nsuffix[ 0 ] ) ) {
+ break;
+ }
+ }
+
+ if ( BER_BVISNULL( &c->be->be_nsuffix[ j ] ) ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "suffix \"%s\" must be within the database naming context",
+ argv[1] );
+ Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
+ free( pvnc.bv_val );
+ free( nvnc.bv_val );
return 1;
}
- if ( strcasecmp( str, "false" ) == 0 || strcasecmp( str, "no" ) == 0 ) {
- return 0;
+ ber_str2bv( argv[ 2 ], 0, 0, &dn );
+ if ( dnPrettyNormal( NULL, &dn, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "massaged suffix \"%s\" is invalid",
+ argv[2] );
+ Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
+ free( pvnc.bv_val );
+ free( nvnc.bv_val );
+ return 1;
+ }
+
+ tmp_bd = select_backend( &nrnc, 0 );
+ if ( tmp_bd != NULL && tmp_bd->be_private == c->be->be_private ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: warning: \"%s\" resolves to this database, in "
+ "\"suffixMassage \"\n",
+ c->log, prnc.bv_val, 0 );
}
- return -1;
+ /*
+ * The suffix massaging is emulated by means of the
+ * rewrite capabilities
+ */
+ rc = suffix_massage_config( mt->mt_rwmap.rwm_rw,
+ &pvnc, &nvnc, &prnc, &nrnc );
+
+ free( pvnc.bv_val );
+ free( nvnc.bv_val );
+ free( prnc.bv_val );
+ free( nrnc.bv_val );
+
+ return rc;
}
-int
-meta_subtree_destroy( metasubtree_t *ms )
+static int
+slap_bv_x_ordered_unparse( BerVarray in, BerVarray *out )
{
- if ( ms->ms_next ) {
- meta_subtree_destroy( ms->ms_next );
+ int i;
+ BerVarray bva = NULL;
+ char ibuf[32], *ptr;
+ struct berval idx;
+
+ assert( in != NULL );
+
+ for ( i = 0; !BER_BVISNULL( &in[i] ); i++ )
+ /* count'em */ ;
+
+ if ( i == 0 ) {
+ return 1;
+ }
+
+ idx.bv_val = ibuf;
+
+ bva = ch_malloc( ( i + 1 ) * sizeof(struct berval) );
+ BER_BVZERO( &bva[ 0 ] );
+
+ for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) {
+ idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i );
+ if ( idx.bv_len >= sizeof( ibuf ) ) {
+ ber_bvarray_free( bva );
+ return 1;
+ }
+
+ bva[i].bv_len = idx.bv_len + in[i].bv_len;
+ bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
+ ptr = lutil_strcopy( bva[i].bv_val, ibuf );
+ ptr = lutil_strcopy( ptr, in[i].bv_val );
+ *ptr = '\0';
+ BER_BVZERO( &bva[ i + 1 ] );
}
+ *out = bva;
+ return 0;
+}
+
+int
+meta_subtree_free( metasubtree_t *ms )
+{
switch ( ms->ms_type ) {
case META_ST_SUBTREE:
case META_ST_SUBORDINATE:
@@ -107,7 +697,7 @@ meta_subtree_destroy( metasubtree_t *ms )
case META_ST_REGEX:
regfree( &ms->ms_regex );
- ch_free( ms->ms_regex_pattern );
+ ber_memfree( ms->ms_regex_pattern.bv_val );
break;
default:
@@ -115,27 +705,72 @@ meta_subtree_destroy( metasubtree_t *ms )
}
ch_free( ms );
+ return 0;
+}
+
+int
+meta_subtree_destroy( metasubtree_t *ms )
+{
+ if ( ms->ms_next ) {
+ meta_subtree_destroy( ms->ms_next );
+ }
+
+ return meta_subtree_free( ms );
+}
+
+static struct berval st_styles[] = {
+ BER_BVC("subtree"),
+ BER_BVC("children"),
+ BER_BVC("regex")
+};
+
+static int
+meta_subtree_unparse(
+ ConfigArgs *c,
+ metatarget_t *mt )
+{
+ metasubtree_t *ms;
+ struct berval bv, *style;
+
+ if ( !mt->mt_subtree )
+ return 1;
+
+ /* can only be one of exclude or include */
+ if (( c->type == LDAP_BACK_CFG_SUBTREE_EX ) ^ mt->mt_subtree_exclude )
+ return 1;
+ bv.bv_val = c->cr_msg;
+ for ( ms=mt->mt_subtree; ms; ms=ms->ms_next ) {
+ if (ms->ms_type == META_ST_SUBTREE)
+ style = &st_styles[0];
+ else if ( ms->ms_type == META_ST_SUBORDINATE )
+ style = &st_styles[1];
+ else if ( ms->ms_type == META_ST_REGEX )
+ style = &st_styles[2];
+ else {
+ assert(0);
+ continue;
+ }
+ bv.bv_len = snprintf( c->cr_msg, sizeof(c->cr_msg),
+ "dn.%s:%s", style->bv_val, ms->ms_dn.bv_val );
+ value_add_one( &c->rvalue_vals, &bv );
+ }
return 0;
}
static int
meta_subtree_config(
metatarget_t *mt,
- int argc,
- char **argv,
- char *buf,
- ber_len_t buflen,
- char *log_prefix )
+ ConfigArgs *c )
{
meta_st_t type = META_ST_SUBTREE;
char *pattern;
struct berval ndn = BER_BVNULL;
metasubtree_t *ms = NULL;
- if ( strcasecmp( argv[0], "subtree-exclude" ) == 0 ) {
+ if ( c->type == LDAP_BACK_CFG_SUBTREE_EX ) {
if ( mt->mt_subtree && !mt->mt_subtree_exclude ) {
- snprintf( buf, buflen,
+ snprintf( c->cr_msg, sizeof(c->cr_msg),
"\"subtree-exclude\" incompatible with previous \"subtree-include\" directives" );
return 1;
}
@@ -144,26 +779,13 @@ meta_subtree_config(
} else {
if ( mt->mt_subtree && mt->mt_subtree_exclude ) {
- snprintf( buf, buflen,
+ snprintf( c->cr_msg, sizeof(c->cr_msg),
"\"subtree-include\" incompatible with previous \"subtree-exclude\" directives" );
return 1;
}
}
- switch ( argc ) {
- case 1:
- snprintf( buf, buflen, "missing pattern" );
- return 1;
-
- case 2:
- break;
-
- default:
- snprintf( buf, buflen, "too many args" );
- return 1;
- }
-
- pattern = argv[1];
+ pattern = c->argv[1];
if ( strncasecmp( pattern, "dn", STRLENOF( "dn" ) ) == 0 ) {
char *style;
@@ -189,13 +811,13 @@ meta_subtree_config(
pattern = &style[STRLENOF( "regex" )];
} else {
- snprintf( buf, buflen, "unknown style in \"dn.