[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: parent DN and deref control
On 09/30/2015 09:19 PM, Michael Ströder wrote:
I have a use-case where it would be handy to use the deref control to request
attributes from an entry's parent entry. But this would require kind of a
pseudo-attribute 'parentDN' (similar to 'entryDN').
Anybody aware whether such a thing is already available?
I've attached my implementation -- hope it helps. The patch is against
REL_ENG_2_4.
(More details: the parentDN part is fairly straightforward, given the
entryDN implementation as a model. However, the deref overlay can't use
dynamic attributes [you can try the unmodified slapd with deref and
entryDN], so I wrote a nasty hack to make it work with parentDN. Not
extensively tested, e.g., I'm not sure it would work "" as the parent.)
--
Ivan Nejgebauer +381 21 485 2025
Glavni sistem inženjer ian@uns.ac.rs
CIT-UNS/ARMUNS http://www.uns.ac.rs
Univerzitet u Novom Sadu $ Dr Zorana Đinđića 1 $ 21000 Novi Sad $ Srbija
--- openldap-c7384f9/servers/slapd/backend.c.orig 2015-09-29 23:05:48.000000000 +0200
+++ openldap-c7384f9/servers/slapd/backend.c 2015-10-01 14:50:06.325742572 +0200
@@ -1933,6 +1933,14 @@
ap = &(*ap)->a_next;
}
+ if ( !( rs->sr_flags & REP_NO_PARENTDN )
+ && ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( rs->sr_attrs &&
+ ad_inlist( slap_schema.si_ad_parentDN, rs->sr_attrs ) ) ) )
+ {
+ *ap = slap_operational_parentDN( rs->sr_entry );
+ ap = &(*ap)->a_next;
+ }
+
/* Let the overlays have a chance at this */
if ( oex && ((OpExtraDB *)oex)->oe_db )
op->o_bd = ((OpExtraDB *)oex)->oe_db;
--- openldap-c7384f9/servers/slapd/overlays/deref.c.orig 2015-09-29 23:05:48.000000000 +0200
+++ openldap-c7384f9/servers/slapd/overlays/deref.c 2015-10-01 21:12:47.233432326 +0200
@@ -304,7 +304,15 @@
}
for ( ds = dc->dc_ds; ds; ds = ds->ds_next ) {
- Attribute *a = attr_find( ebase->e_attrs, ds->ds_derefAttr );
+ Attribute *a;
+ struct berval pdn;
+
+ pdn.bv_val = "parentDN";
+ pdn.bv_len = strlen( pdn.bv_val );
+ if ( !ber_bvcmp( &pdn, &ds->ds_derefAttr->ad_cname ) )
+ a = slap_operational_parentDN( rs->sr_entry );
+ else
+ a = attr_find( ebase->e_attrs, ds->ds_derefAttr );
if ( a != NULL ) {
DerefVal *dv;
--- openldap-c7384f9/servers/slapd/slap.h.orig 2015-09-29 23:05:48.000000000 +0200
+++ openldap-c7384f9/servers/slapd/slap.h 2015-10-01 14:48:15.114192420 +0200
@@ -909,6 +909,7 @@
AttributeDescription *si_ad_collectiveSubentries;
AttributeDescription *si_ad_collectiveExclusions;
AttributeDescription *si_ad_entryDN;
+ AttributeDescription *si_ad_parentDN;
AttributeDescription *si_ad_entryUUID;
AttributeDescription *si_ad_entryCSN;
AttributeDescription *si_ad_namingCSN;
@@ -2137,7 +2138,8 @@
#define REP_NO_ENTRYDN ((slap_mask_t) 0x1000U)
#define REP_NO_SUBSCHEMA ((slap_mask_t) 0x2000U)
-#define REP_NO_OPERATIONALS (REP_NO_ENTRYDN|REP_NO_SUBSCHEMA)
+#define REP_NO_PARENTDN ((slap_mask_t) 0x4000U)
+#define REP_NO_OPERATIONALS (REP_NO_ENTRYDN|REP_NO_SUBSCHEMA|REP_NO_PARENTDN)
};
/* short hands for response members */
--- openldap-c7384f9/servers/slapd/schema_prep.c.orig 2015-09-29 23:05:48.000000000 +0200
+++ openldap-c7384f9/servers/slapd/schema_prep.c 2015-10-01 14:43:03.382675474 +0200
@@ -541,6 +541,15 @@
NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
offsetof(struct slap_internal_schema, si_ad_entryDN) },
+ { "parentDN", "( 1.3.6.1.4.1.10094.1.2.6 NAME 'parentDN' "
+ "DESC 'parent DN of the entry' "
+ "EQUALITY distinguishedNameMatch "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
+ "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
+ NULL, SLAP_AT_DYNAMIC,
+ NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ offsetof(struct slap_internal_schema, si_ad_parentDN) },
{ "entryUUID", "( 1.3.6.1.1.16.4 NAME 'entryUUID' "
"DESC 'UUID of the entry' "
"EQUALITY UUIDMatch "
--- openldap-c7384f9/servers/slapd/operational.c.orig 2015-09-29 23:05:48.000000000 +0200
+++ openldap-c7384f9/servers/slapd/operational.c 2015-10-01 21:17:55.824859972 +0200
@@ -88,3 +88,42 @@
return a;
}
+Attribute *
+slap_operational_parentDN( Entry *e )
+{
+ Attribute *a;
+ struct berval val;
+
+ assert( e != NULL );
+ assert( !BER_BVISNULL( &e->e_name ) );
+ assert( !BER_BVISNULL( &e->e_nname ) );
+
+ if ( e->e_name.bv_len == 0 )
+ return NULL;
+
+ a = attr_alloc( slap_schema.si_ad_parentDN );
+ a->a_numvals = 1;
+
+ ber_bvchr_post( &val, &e->e_name, ',' );
+ if ( val.bv_len > 0 ) {
+ val.bv_len--;
+ val.bv_val++;
+ } else
+ val.bv_val = &e->e_name.bv_val;
+ a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
+ ber_dupbv( &a->a_vals[ 0 ], &val );
+ BER_BVZERO( &a->a_vals[ 1 ] );
+
+ ber_bvchr_post( &val, &e->e_nname, ',' );
+ if ( val.bv_len > 0 ) {
+ val.bv_len--;
+ val.bv_val++;
+ } else
+ val.bv_val = &e->e_nname.bv_val;
+ a->a_nvals = ch_malloc( 2 * sizeof( struct berval ) );
+ ber_dupbv( &a->a_nvals[ 0 ], &val );
+ BER_BVZERO( &a->a_nvals[ 1 ] );
+
+ return a;
+}
+