From: Howard Chu Date: Tue, 28 Aug 2007 09:19:07 +0000 (+0000) Subject: Convert collect to dynamic config. Even though it's only a demo... X-Git-Tag: OPENLDAP_REL_ENG_2_4_MP~54 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=4ccb430c8c6b309962a7b64cbfdc2e90a51120f6;p=openldap Convert collect to dynamic config. Even though it's only a demo... --- diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 3b651a680a..8891a32e58 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -248,6 +248,7 @@ static OidRec OidMacros[] = { * OLcfgOv{Oc|At}:16 -> rwm * OLcfgOv{Oc|At}:17 -> dyngroup * OLcfgOv{Oc|At}:18 -> memberof + * OLcfgOv{Oc|At}:19 -> collect */ /* alphabetical ordering */ diff --git a/servers/slapd/overlays/collect.c b/servers/slapd/overlays/collect.c index 5fd2cb8325..d78f32b54a 100644 --- a/servers/slapd/overlays/collect.c +++ b/servers/slapd/overlays/collect.c @@ -29,7 +29,7 @@ #include #include "slap.h" - +#include "config.h" /* This is a cheap hack to implement a collective attribute. * @@ -46,6 +46,124 @@ typedef struct collect_info { AttributeDescription *ci_ad; } collect_info; +static int +collect_cf( ConfigArgs *c ) +{ + slap_overinst *on = (slap_overinst *)c->bi; + int rc = 1; + + switch( c->op ) { + case SLAP_CONFIG_EMIT: + { + collect_info *ci; + for ( ci = on->on_bi.bi_private; ci; ci = ci->ci_next ) { + struct berval bv; + + bv.bv_len = ci->ci_dn.bv_len + 3 + + ci->ci_ad->ad_cname.bv_len; + bv.bv_val = ch_malloc( bv.bv_len + 1 ); + sprintf( bv.bv_val, "\"%s\" %s", ci->ci_dn.bv_val, + ci->ci_ad->ad_cname.bv_val ); + ber_bvarray_add( &c->rvalue_vals, &bv ); + rc = 0; + } + } + break; + case LDAP_MOD_DELETE: + if ( c->valx == -1 ) { + /* Delete entire attribute */ + collect_info *ci; + while (( ci = on->on_bi.bi_private )) { + on->on_bi.bi_private = ci->ci_next; + ch_free( ci->ci_dn.bv_val ); + ch_free( ci ); + } + } else { + /* Delete just one value */ + collect_info **cip, *ci; + int i; + cip = (collect_info **)&on->on_bi.bi_private; + for ( i=0; i <= c->valx; i++, cip = &ci->ci_next ) ci = *cip; + *cip = ci->ci_next; + ch_free( ci->ci_dn.bv_val ); + ch_free( ci ); + } + rc = 0; + break; + case SLAP_CONFIG_ADD: + case LDAP_MOD_ADD: + { + collect_info *ci; + struct berval bv, dn; + const char *text; + AttributeDescription *ad = NULL; + + ber_str2bv( c->argv[1], 0, 0, &bv ); + if ( dnNormalize( 0, NULL, NULL, &bv, &dn, NULL ) ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s invalid DN: \"%s\"", + c->argv[0], c->argv[1] ); + Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, + "%s: %s\n", c->log, c->cr_msg, 0 ); + return ARG_BAD_CONF; + } + if ( slap_str2ad( c->argv[2], &ad, &text ) ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"", + c->argv[0], c->argv[2] ); + Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, + "%s: %s\n", c->log, c->cr_msg, 0 ); + return ARG_BAD_CONF; + } + + /* The on->on_bi.bi_private pointer can be used for + * anything this instance of the overlay needs. + */ + ci = ch_malloc( sizeof( collect_info )); + ci->ci_ad = ad; + ci->ci_dn = dn; + ci->ci_next = on->on_bi.bi_private; + on->on_bi.bi_private = ci; + rc = 0; + } + } + return rc; +} + +static ConfigTable collectcfg[] = { + { "collectinfo", "dn> bd_info; + collect_info *ci; + + while (( ci = on->on_bi.bi_private )) { + on->on_bi.bi_private = ci->ci_next; + ch_free( ci->ci_dn.bv_val ); + ch_free( ci ); + } + return 0; +} + static int collect_response( Operation *op, SlapReply *rs ) { @@ -56,7 +174,6 @@ collect_response( Operation *op, SlapReply *rs ) * a search entry */ if ( ci && rs->sr_type == REP_SEARCH ) { - Entry *new = NULL; int rc; op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -65,9 +182,8 @@ collect_response( Operation *op, SlapReply *rs ) BerVarray vals = NULL; /* Is our configured entry an ancestor of this one? */ - rc = rs->sr_entry->e_nname.bv_len - ci->ci_dn.bv_len; - if ( rc < 1 || strcmp( rs->sr_entry->e_nname.bv_val + rc, - ci->ci_dn.bv_val )) continue; + if ( !dnIsSuffix( &rs->sr_entry->e_nname, &ci->ci_dn )) + continue; /* Extract the values of the desired attribute from * the ancestor entry @@ -82,82 +198,33 @@ collect_response( Operation *op, SlapReply *rs ) * don't modify it directly. Make a copy and * work with that instead. */ - if ( !new ) { - new = entry_dup( rs->sr_entry ); + if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE )) { + rs->sr_entry = entry_dup( rs->sr_entry ); + rs->sr_flags |= REP_ENTRY_MODIFIABLE | + REP_ENTRY_MUSTBEFREED; } - attr_merge( new, ci->ci_ad, vals, NULL ); + attr_merge( rs->sr_entry, ci->ci_ad, vals, NULL ); ber_bvarray_free_x( vals, op->o_tmpmemctx ); } } - - if ( new ) { - rs->sr_entry = new; - rs->sr_flags |= REP_ENTRY_MUSTBEFREED; - } } /* Default is to just fall through to the normal processing */ return SLAP_CB_CONTINUE; } -static int collect_config( - BackendDB *be, - const char *fname, - int lineno, - int argc, - char **argv -) -{ - slap_overinst *on = (slap_overinst *) be->bd_info; - AttributeDescription *ad = NULL; - - /* The config syntax is "collectinfo " - * and only one directive may be specified per overlay instance. - */ - - if ( strcasecmp( argv[0], "collectinfo" ) == 0 ) { - collect_info *ci; - struct berval bv, dn; - const char *text; - if ( argc != 3 ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: argument missing in \"collectinfo \" line.\n", - fname, lineno, 0 ); - return( 1 ); - } - ber_str2bv( argv[1], 0, 0, &bv ); - if ( dnNormalize( 0, NULL, NULL, &bv, &dn, NULL ) ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: invalid DN in \"collectinfo\" line: %s.\n", - fname, lineno, text ); - return( 1 ); - } - if ( slap_str2ad( argv[2], &ad, &text ) ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: attribute description unknown in \"collectinfo\" line: %s.\n", - fname, lineno, text ); - return( 1 ); - } - - /* The on->on_bi.bi_private pointer can be used for - * anything this instance of the overlay needs. - */ - ci = ch_malloc( sizeof( collect_info )); - ci->ci_ad = ad; - ci->ci_dn = dn; - ci->ci_next = on->on_bi.bi_private; - on->on_bi.bi_private = ci; - return 0; - } - return SLAP_CONF_UNKNOWN; -} - static slap_overinst collect; int collect_initialize() { + int code; + collect.on_bi.bi_type = "collect"; - collect.on_bi.bi_db_config = collect_config; + collect.on_bi.bi_db_destroy = collect_destroy; collect.on_response = collect_response; + collect.on_bi.bi_cf_ocs = collectocs; + code = config_register_schema( collectcfg, collectocs ); + if ( code ) return code; + return overlay_register( &collect ); }