diff --git a/CHANGES b/CHANGES index 141c263b5e4fb2508848f6eec150599bb2a1673c..f624771a9c136f1c5e7cac56dd8b3f732a2dee41 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,7 @@ OpenLDAP 2.4.17 Engineering Fixed slapd-ldap deadlock with non-responsive TLS URIs (ITS#6167) Fixed slapd-relay to return failure on failure (ITS#5328) Fixed slapd-sql with BACKSQL_ARBITRARY_KEY defined (ITS#6100) + Fixed slapo-collect collectinfo ordering (ITS#6076) Fixed slapo-collect missing equality match rule (ITS#6075) Fixed slapo-dds entry expiration (ITS#6169) Fixed slapo-refint refint_repair handling (ITS#6056) diff --git a/servers/slapd/overlays/collect.c b/servers/slapd/overlays/collect.c index 29d94dc7d3aa5980ecf7449f880fffc708f469ff..3e5ee67db38928b17481e8864f3b8cf53c45249c 100644 --- a/servers/slapd/overlays/collect.c +++ b/servers/slapd/overlays/collect.c @@ -49,6 +49,28 @@ typedef struct collect_info { AttributeDescription *ci_ad[1]; } collect_info; +static int collect_cf( ConfigArgs *c ); + +static ConfigTable collectcfg[] = { + { "collectinfo", "dn> <attribute", 3, 3, 0, + ARG_MAGIC, collect_cf, + "( OLcfgOvAt:19.1 NAME 'olcCollectInfo' " + "DESC 'DN of entry and attribute to distribute' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString )", NULL, NULL }, + { NULL, NULL, 0, 0, 0, ARG_IGNORED } +}; + +static ConfigOCs collectocs[] = { + { "( OLcfgOvOc:19.1 " + "NAME 'olcCollectConfig' " + "DESC 'Collective Attribute configuration' " + "SUP olcOverlayConfig " + "MAY olcCollectInfo )", + Cft_Overlay, collectcfg }, + { NULL, 0, NULL } +}; + /* * inserts a collect_info into on->on_bi.bi_private taking into account * order. this means longer dn's (i.e. more specific dn's) will be found @@ -188,6 +210,26 @@ collect_cf( ConfigArgs *c ) return ARG_BAD_CONF; } + /* check for duplicate DNs */ + for ( ci = (collect_info *)on->on_bi.bi_private; ci; + ci = ci->ci_next ) { + /* If new DN is longest, there are no possible matches */ + if ( dn.bv_len > ci->ci_dn.bv_len ) { + ci = NULL; + break; + } + if ( bvmatch( &dn, &ci->ci_dn )) { + break; + } + } + if ( ci ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s DN already configured: \"%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; + } + /* allocate config info with room for attribute array */ ci = ch_malloc( sizeof( collect_info ) + sizeof( AttributeDescription * ) * count ); @@ -224,32 +266,34 @@ collect_cf( ConfigArgs *c ) /* creates list of ci's ordered by dn length */ insert_ordered ( on, ci ); + /* New ci wasn't simply appended to end, adjust its + * position in the config entry's a_vals + */ + if ( c->ca_entry && ci->ci_next ) { + Attribute *a = attr_find( c->ca_entry->e_attrs, + collectcfg[0].ad ); + if ( a ) { + struct berval bv, nbv; + collect_info *c2 = (collect_info *)on->on_bi.bi_private; + int i, j; + for ( i=0; c2 != ci; i++, c2 = c2->ci_next ); + bv = a->a_vals[a->a_numvals-1]; + nbv = a->a_nvals[a->a_numvals-1]; + for ( j=a->a_numvals-1; j>i; j-- ) { + a->a_vals[j] = a->a_vals[j-1]; + a->a_nvals[j] = a->a_nvals[j-1]; + } + a->a_vals[j] = bv; + a->a_nvals[j] = nbv; + } + } + rc = 0; } } return rc; } -static ConfigTable collectcfg[] = { - { "collectinfo", "dn> <attribute", 3, 3, 0, - ARG_MAGIC, collect_cf, - "( OLcfgOvAt:19.1 NAME 'olcCollectInfo' " - "DESC 'DN of entry and attribute to distribute' " - "EQUALITY caseIgnoreMatch " - "SYNTAX OMsDirectoryString )", NULL, NULL }, - { NULL, NULL, 0, 0, 0, ARG_IGNORED } -}; - -static ConfigOCs collectocs[] = { - { "( OLcfgOvOc:19.1 " - "NAME 'olcCollectConfig' " - "DESC 'Collective Attribute configuration' " - "SUP olcOverlayConfig " - "MAY olcCollectInfo )", - Cft_Overlay, collectcfg }, - { NULL, 0, NULL } -}; - static int collect_destroy( BackendDB *be,