/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2006-2009 The OpenLDAP Foundation.
+ * Copyright 2006-2014 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include "slap.h"
/*
- * Schema from
+ * NOTE: part of the schema definition reported below is taken
+ * from Microsoft schema definitions (OID, NAME, SYNTAX);
*
+ * EQUALITY is taken from
* <http://www.redhat.com/archives/fedora-directory-devel/2006-August/msg00007.html>
+ * (posted by Andrew Bartlett)
*
- * posted by Andrew Bartlett
+ * The rest is guessed. Specifically
+ *
+ * DESC briefly describes the purpose
+ *
+ * NO-USER-MODIFICATION is added to make attributes operational
+ *
+ * USAGE is set to "dSAOperation" as per ITS#7493,
+ * to prevent replication, since this information
+ * is generated (based on ACL and identity of request)
+ * and not stored.
*/
#define AA_SCHEMA_AT "1.2.840.113556.1.4"
/* added by me :) */
"DESC 'Child classes allowed for a given object' "
"NO-USER-MODIFICATION "
- "USAGE directoryOperation )", &ad_allowedChildClasses },
+ "USAGE dSAOperation )", &ad_allowedChildClasses },
{ "( " AA_SCHEMA_AT ".912 "
"NAME 'allowedChildClassesEffective' "
"EQUALITY objectIdentifierMatch "
/* added by me :) */
"DESC 'Child classes allowed for a given object according to ACLs' "
"NO-USER-MODIFICATION "
- "USAGE directoryOperation )", &ad_allowedChildClassesEffective },
+ "USAGE dSAOperation )", &ad_allowedChildClassesEffective },
{ "( " AA_SCHEMA_AT ".913 "
"NAME 'allowedAttributes' "
"EQUALITY objectIdentifierMatch "
/* added by me :) */
"DESC 'Attributes allowed for a given object' "
"NO-USER-MODIFICATION "
- "USAGE directoryOperation )", &ad_allowedAttributes },
+ "USAGE dSAOperation )", &ad_allowedAttributes },
{ "( " AA_SCHEMA_AT ".914 "
"NAME 'allowedAttributesEffective' "
"EQUALITY objectIdentifierMatch "
/* added by me :) */
"DESC 'Attributes allowed for a given object according to ACLs' "
"NO-USER-MODIFICATION "
- "USAGE directoryOperation )", &ad_allowedAttributesEffective },
+ "USAGE dSAOperation )", &ad_allowedAttributesEffective },
/* TODO: add objectClass stuff? */
struct berval *v;
AttributeType **atp = NULL;
ObjectClass **ocp = NULL;
- BerVarray bv_allowed = NULL,
- bv_effective = NULL;
- int i, ja, je;
#define GOT_NONE (0x0U)
#define GOT_C (0x1U)
/* shouldn't be called without an entry; please check */
assert( rs->sr_entry != NULL );
+ for ( ap = &rs->sr_operational_attrs; *ap != NULL; ap = &(*ap)->a_next )
+ /* go to last */ ;
+
/* see caveats; this is not guaranteed for all backends */
a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_objectClass );
if ( a == NULL ) {
- return SLAP_CB_CONTINUE;
+ goto do_oc;
}
/* if client has no access to objectClass attribute; don't compute */
aa_add_oc( oc, &ocp, &atp );
if ( oc->soc_sups ) {
+ int i;
+
for ( i = 0; oc->soc_sups[ i ] != NULL; i++ ) {
aa_add_oc( oc->soc_sups[ i ], &ocp, &atp );
}
}
}
+ ch_free( ocp );
+
if ( atp != NULL ) {
+ BerVarray bv_allowed = NULL,
+ bv_effective = NULL;
+ int i, ja = 0, je = 0;
+
for ( i = 0; atp[ i ] != NULL; i++ )
/* just count */ ;
}
}
- for ( ap = &rs->sr_operational_attrs; *ap != NULL; ap = &(*ap)->a_next )
- /* go to last */ ;
+ ch_free( atp );
- if ( got & GOT_A ) {
+ if ( ( got & GOT_A ) && ja > 0 ) {
BER_BVZERO( &bv_allowed[ ja ] );
*ap = attr_alloc( ad_allowedAttributes );
(*ap)->a_vals = bv_allowed;
(*ap)->a_nvals = bv_allowed;
+ (*ap)->a_numvals = ja;
ap = &(*ap)->a_next;
}
-
- if ( got & GOT_AE ) {
+
+ if ( ( got & GOT_AE ) && je > 0 ) {
BER_BVZERO( &bv_effective[ je ] );
*ap = attr_alloc( ad_allowedAttributesEffective );
(*ap)->a_vals = bv_effective;
(*ap)->a_nvals = bv_effective;
+ (*ap)->a_numvals = je;
ap = &(*ap)->a_next;
}
-
+
*ap = NULL;
}
- ch_free( atp );
- ch_free( ocp );
+do_oc:;
+ if ( ( got & GOT_C ) || ( got & GOT_CE ) ) {
+ BerVarray bv_allowed = NULL,
+ bv_effective = NULL;
+ int i, ja = 0, je = 0;
+
+ ObjectClass *oc;
+
+ for ( oc_start( &oc ); oc != NULL; oc_next( &oc ) ) {
+ /* we can only add AUXILIARY objectClasses */
+ if ( oc->soc_kind != LDAP_SCHEMA_AUXILIARY ) {
+ continue;
+ }
+
+ i++;
+ }
+
+ if ( got & GOT_C ) {
+ bv_allowed = ber_memalloc( sizeof( struct berval ) * ( i + 1 ) );
+ }
+ if ( got & GOT_CE ) {
+ bv_effective = ber_memalloc( sizeof( struct berval ) * ( i + 1 ) );
+ }
+
+ for ( oc_start( &oc ); oc != NULL; oc_next( &oc ) ) {
+ /* we can only add AUXILIARY objectClasses */
+ if ( oc->soc_kind != LDAP_SCHEMA_AUXILIARY ) {
+ continue;
+ }
+
+ if ( got & GOT_C ) {
+ ber_dupbv( &bv_allowed[ ja ], &oc->soc_cname );
+ ja++;
+ }
+
+ if ( got & GOT_CE ) {
+ if ( !access_allowed( op, rs->sr_entry,
+ slap_schema.si_ad_objectClass,
+ &oc->soc_cname, ACL_WRITE, NULL ) )
+ {
+ goto done_ce;
+ }
+
+ if ( oc->soc_required ) {
+ for ( i = 0; oc->soc_required[ i ] != NULL; i++ ) {
+ AttributeDescription *ad = NULL;
+ const char *text = NULL;
+
+ if ( slap_bv2ad( &oc->soc_required[ i ]->sat_cname, &ad, &text ) ) {
+ /* log? */
+ continue;
+ }
+
+ if ( !access_allowed( op, rs->sr_entry,
+ ad, NULL, ACL_WRITE, NULL ) )
+ {
+ goto done_ce;
+ }
+ }
+ }
+
+ ber_dupbv( &bv_effective[ je ], &oc->soc_cname );
+ je++;
+ }
+done_ce:;
+ }
+
+ if ( ( got & GOT_C ) && ja > 0 ) {
+ BER_BVZERO( &bv_allowed[ ja ] );
+ *ap = attr_alloc( ad_allowedChildClasses );
+ (*ap)->a_vals = bv_allowed;
+ (*ap)->a_nvals = bv_allowed;
+ (*ap)->a_numvals = ja;
+ ap = &(*ap)->a_next;
+ }
+
+ if ( ( got & GOT_CE ) && je > 0 ) {
+ BER_BVZERO( &bv_effective[ je ] );
+ *ap = attr_alloc( ad_allowedChildClassesEffective );
+ (*ap)->a_vals = bv_effective;
+ (*ap)->a_nvals = bv_effective;
+ (*ap)->a_numvals = je;
+ ap = &(*ap)->a_next;
+ }
+
+ *ap = NULL;
+ }
return SLAP_CB_CONTINUE;
}
{
int i;
- aa.on_bi.bi_type = "aa";
+ aa.on_bi.bi_type = "allowed";
aa.on_bi.bi_operational = aa_operational;