1*549b59edSchristos /* $NetBSD: allowed.c,v 1.3 2021/08/14 16:14:50 christos Exp $ */
24e6df137Slukem
34e6df137Slukem /* allowed.c - add allowed attributes based on ACL */
4d11b170bStron /* $OpenLDAP$ */
54e6df137Slukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
64e6df137Slukem *
7*549b59edSchristos * Copyright 2006-2021 The OpenLDAP Foundation.
84e6df137Slukem * All rights reserved.
94e6df137Slukem *
104e6df137Slukem * Redistribution and use in source and binary forms, with or without
114e6df137Slukem * modification, are permitted only as authorized by the OpenLDAP
124e6df137Slukem * Public License.
134e6df137Slukem *
144e6df137Slukem * A copy of this license is available in the file LICENSE in the
154e6df137Slukem * top-level directory of the distribution or, alternatively, at
164e6df137Slukem * <http://www.OpenLDAP.org/license.html>.
174e6df137Slukem */
184e6df137Slukem /* ACKNOWLEDGEMENTS:
194e6df137Slukem * This work was initially developed by Pierangelo Masarati for inclusion in
204e6df137Slukem * OpenLDAP Software.
214e6df137Slukem */
224e6df137Slukem
234e6df137Slukem /*
244e6df137Slukem * Rationale: return in allowedAttributes the attributes required/allowed
254e6df137Slukem * by the objectClasses that are currently present in an object; return
264e6df137Slukem * in allowedAttributesEffective the subset of the above that can be written
274e6df137Slukem * by the identity that performs the search.
284e6df137Slukem *
294e6df137Slukem * Caveats:
304e6df137Slukem * - right now, the overlay assumes that all values of the objectClass
314e6df137Slukem * attribute will be returned in rs->sr_entry; this may not be true
32*549b59edSchristos * in general, but it usually is for back-mdb. To generalize,
334e6df137Slukem * the search request should be analyzed, and if allowedAttributes or
344e6df137Slukem * allowedAttributesEffective are requested, add objectClass to the
354e6df137Slukem * requested attributes
364e6df137Slukem * - it assumes that there is no difference between write-add and
374e6df137Slukem * write-delete
384e6df137Slukem * - it assumes that access rules do not depend on the values of the
394e6df137Slukem * attributes or on the contents of the entry (attr/val, filter, ...)
404e6df137Slukem * allowedAttributes and allowedAttributesEffective cannot be used
414e6df137Slukem * in filters or in compare
424e6df137Slukem */
434e6df137Slukem
44376af7d7Schristos #include <sys/cdefs.h>
45*549b59edSchristos __RCSID("$NetBSD: allowed.c,v 1.3 2021/08/14 16:14:50 christos Exp $");
46376af7d7Schristos
474e6df137Slukem #include "portable.h"
484e6df137Slukem
494e6df137Slukem /* define SLAPD_OVER_ALLOWED=2 to build as run-time loadable module */
504e6df137Slukem #ifdef SLAPD_OVER_ALLOWED
514e6df137Slukem
524e6df137Slukem #include "slap.h"
534e6df137Slukem
544e6df137Slukem /*
55d11b170bStron * NOTE: part of the schema definition reported below is taken
56d11b170bStron * from Microsoft schema definitions (OID, NAME, SYNTAX);
574e6df137Slukem *
58d11b170bStron * EQUALITY is taken from
594e6df137Slukem * <http://www.redhat.com/archives/fedora-directory-devel/2006-August/msg00007.html>
60d11b170bStron * (posted by Andrew Bartlett)
614e6df137Slukem *
62d11b170bStron * The rest is guessed. Specifically
63d11b170bStron *
64d11b170bStron * DESC briefly describes the purpose
65d11b170bStron *
66d11b170bStron * NO-USER-MODIFICATION is added to make attributes operational
67d11b170bStron *
68d11b170bStron * USAGE is set to "dSAOperation" as per ITS#7493,
69d11b170bStron * to prevent replication, since this information
70d11b170bStron * is generated (based on ACL and identity of request)
71d11b170bStron * and not stored.
724e6df137Slukem */
734e6df137Slukem
744e6df137Slukem #define AA_SCHEMA_AT "1.2.840.113556.1.4"
754e6df137Slukem
764e6df137Slukem static AttributeDescription
774e6df137Slukem *ad_allowedChildClasses,
784e6df137Slukem *ad_allowedChildClassesEffective,
794e6df137Slukem *ad_allowedAttributes,
804e6df137Slukem *ad_allowedAttributesEffective;
814e6df137Slukem
824e6df137Slukem static struct {
834e6df137Slukem char *at;
844e6df137Slukem AttributeDescription **ad;
854e6df137Slukem } aa_attrs[] = {
864e6df137Slukem { "( " AA_SCHEMA_AT ".911 "
874e6df137Slukem "NAME 'allowedChildClasses' "
884e6df137Slukem "EQUALITY objectIdentifierMatch "
894e6df137Slukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
904e6df137Slukem /* added by me :) */
914e6df137Slukem "DESC 'Child classes allowed for a given object' "
924e6df137Slukem "NO-USER-MODIFICATION "
93d11b170bStron "USAGE dSAOperation )", &ad_allowedChildClasses },
944e6df137Slukem { "( " AA_SCHEMA_AT ".912 "
954e6df137Slukem "NAME 'allowedChildClassesEffective' "
964e6df137Slukem "EQUALITY objectIdentifierMatch "
974e6df137Slukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
984e6df137Slukem /* added by me :) */
994e6df137Slukem "DESC 'Child classes allowed for a given object according to ACLs' "
1004e6df137Slukem "NO-USER-MODIFICATION "
101d11b170bStron "USAGE dSAOperation )", &ad_allowedChildClassesEffective },
1024e6df137Slukem { "( " AA_SCHEMA_AT ".913 "
1034e6df137Slukem "NAME 'allowedAttributes' "
1044e6df137Slukem "EQUALITY objectIdentifierMatch "
1054e6df137Slukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
1064e6df137Slukem /* added by me :) */
1074e6df137Slukem "DESC 'Attributes allowed for a given object' "
1084e6df137Slukem "NO-USER-MODIFICATION "
109d11b170bStron "USAGE dSAOperation )", &ad_allowedAttributes },
1104e6df137Slukem { "( " AA_SCHEMA_AT ".914 "
1114e6df137Slukem "NAME 'allowedAttributesEffective' "
1124e6df137Slukem "EQUALITY objectIdentifierMatch "
1134e6df137Slukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
1144e6df137Slukem /* added by me :) */
1154e6df137Slukem "DESC 'Attributes allowed for a given object according to ACLs' "
1164e6df137Slukem "NO-USER-MODIFICATION "
117d11b170bStron "USAGE dSAOperation )", &ad_allowedAttributesEffective },
1184e6df137Slukem
1194e6df137Slukem /* TODO: add objectClass stuff? */
1204e6df137Slukem
1214e6df137Slukem { NULL, NULL }
1224e6df137Slukem };
1234e6df137Slukem
1244e6df137Slukem static int
aa_add_at(AttributeType * at,AttributeType *** atpp)1254e6df137Slukem aa_add_at( AttributeType *at, AttributeType ***atpp )
1264e6df137Slukem {
1274e6df137Slukem int i = 0;
1284e6df137Slukem
1294e6df137Slukem if ( *atpp ) {
1304e6df137Slukem for ( i = 0; (*atpp)[ i ] != NULL; i++ ) {
1314e6df137Slukem if ( (*atpp)[ i ] == at ) {
1324e6df137Slukem break;
1334e6df137Slukem }
1344e6df137Slukem }
1354e6df137Slukem
1364e6df137Slukem if ( (*atpp)[ i ] != NULL ) {
1374e6df137Slukem return 0;
1384e6df137Slukem }
1394e6df137Slukem }
1404e6df137Slukem
1414e6df137Slukem *atpp = ch_realloc( *atpp, sizeof( AttributeType * ) * ( i + 2 ) );
1424e6df137Slukem (*atpp)[ i ] = at;
1434e6df137Slukem (*atpp)[ i + 1 ] = NULL;
1444e6df137Slukem
1454e6df137Slukem return 0;
1464e6df137Slukem }
1474e6df137Slukem
1484e6df137Slukem static int
aa_add_oc(ObjectClass * oc,ObjectClass *** ocpp,AttributeType *** atpp)1494e6df137Slukem aa_add_oc( ObjectClass *oc, ObjectClass ***ocpp, AttributeType ***atpp )
1504e6df137Slukem {
1514e6df137Slukem int i = 0;
1524e6df137Slukem
1534e6df137Slukem if ( *ocpp ) {
1544e6df137Slukem for ( ; (*ocpp)[ i ] != NULL; i++ ) {
1554e6df137Slukem if ( (*ocpp)[ i ] == oc ) {
1564e6df137Slukem break;
1574e6df137Slukem }
1584e6df137Slukem }
1594e6df137Slukem
1604e6df137Slukem if ( (*ocpp)[ i ] != NULL ) {
1614e6df137Slukem return 0;
1624e6df137Slukem }
1634e6df137Slukem }
1644e6df137Slukem
1654e6df137Slukem *ocpp = ch_realloc( *ocpp, sizeof( ObjectClass * ) * ( i + 2 ) );
1664e6df137Slukem (*ocpp)[ i ] = oc;
1674e6df137Slukem (*ocpp)[ i + 1 ] = NULL;
1684e6df137Slukem
1694e6df137Slukem if ( oc->soc_required ) {
1704e6df137Slukem int i;
1714e6df137Slukem
1724e6df137Slukem for ( i = 0; oc->soc_required[ i ] != NULL; i++ ) {
1734e6df137Slukem aa_add_at( oc->soc_required[ i ], atpp );
1744e6df137Slukem }
1754e6df137Slukem }
1764e6df137Slukem
1774e6df137Slukem if ( oc->soc_allowed ) {
1784e6df137Slukem int i;
1794e6df137Slukem
1804e6df137Slukem for ( i = 0; oc->soc_allowed[ i ] != NULL; i++ ) {
1814e6df137Slukem aa_add_at( oc->soc_allowed[ i ], atpp );
1824e6df137Slukem }
1834e6df137Slukem }
1844e6df137Slukem
1854e6df137Slukem return 0;
1864e6df137Slukem }
1874e6df137Slukem
1884e6df137Slukem static int
aa_operational(Operation * op,SlapReply * rs)1894e6df137Slukem aa_operational( Operation *op, SlapReply *rs )
1904e6df137Slukem {
1914e6df137Slukem Attribute *a, **ap;
1924e6df137Slukem AccessControlState acl_state = ACL_STATE_INIT;
1934e6df137Slukem struct berval *v;
1944e6df137Slukem AttributeType **atp = NULL;
1954e6df137Slukem ObjectClass **ocp = NULL;
1964e6df137Slukem
1974e6df137Slukem #define GOT_NONE (0x0U)
1984e6df137Slukem #define GOT_C (0x1U)
1994e6df137Slukem #define GOT_CE (0x2U)
2004e6df137Slukem #define GOT_A (0x4U)
2014e6df137Slukem #define GOT_AE (0x8U)
2024e6df137Slukem #define GOT_ALL (GOT_C|GOT_CE|GOT_A|GOT_AE)
2034e6df137Slukem int got = GOT_NONE;
2044e6df137Slukem
2054e6df137Slukem /* only add if requested */
2064e6df137Slukem if ( SLAP_OPATTRS( rs->sr_attr_flags ) ) {
2074e6df137Slukem got = GOT_ALL;
2084e6df137Slukem
2094e6df137Slukem } else {
2104e6df137Slukem if ( ad_inlist( ad_allowedChildClasses, rs->sr_attrs ) ) {
2114e6df137Slukem got |= GOT_C;
2124e6df137Slukem }
2134e6df137Slukem
2144e6df137Slukem if ( ad_inlist( ad_allowedChildClassesEffective, rs->sr_attrs ) ) {
2154e6df137Slukem got |= GOT_CE;
2164e6df137Slukem }
2174e6df137Slukem
2184e6df137Slukem if ( ad_inlist( ad_allowedAttributes, rs->sr_attrs ) ) {
2194e6df137Slukem got |= GOT_A;
2204e6df137Slukem }
2214e6df137Slukem
2224e6df137Slukem if ( ad_inlist( ad_allowedAttributesEffective, rs->sr_attrs ) ) {
2234e6df137Slukem got |= GOT_AE;
2244e6df137Slukem }
2254e6df137Slukem }
2264e6df137Slukem
2274e6df137Slukem if ( got == GOT_NONE ) {
2284e6df137Slukem return SLAP_CB_CONTINUE;
2294e6df137Slukem }
2304e6df137Slukem
2314e6df137Slukem /* shouldn't be called without an entry; please check */
2324e6df137Slukem assert( rs->sr_entry != NULL );
2334e6df137Slukem
234ef2f90d3Sadam for ( ap = &rs->sr_operational_attrs; *ap != NULL; ap = &(*ap)->a_next )
235ef2f90d3Sadam /* go to last */ ;
236ef2f90d3Sadam
2374e6df137Slukem /* see caveats; this is not guaranteed for all backends */
2384e6df137Slukem a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_objectClass );
2394e6df137Slukem if ( a == NULL ) {
240ef2f90d3Sadam goto do_oc;
2414e6df137Slukem }
2424e6df137Slukem
2434e6df137Slukem /* if client has no access to objectClass attribute; don't compute */
2444e6df137Slukem if ( !access_allowed( op, rs->sr_entry, slap_schema.si_ad_objectClass,
2454e6df137Slukem NULL, ACL_READ, &acl_state ) )
2464e6df137Slukem {
2474e6df137Slukem return SLAP_CB_CONTINUE;
2484e6df137Slukem }
2494e6df137Slukem
2504e6df137Slukem for ( v = a->a_nvals; !BER_BVISNULL( v ); v++ ) {
2514e6df137Slukem ObjectClass *oc = oc_bvfind( v );
2524e6df137Slukem
2534e6df137Slukem assert( oc != NULL );
2544e6df137Slukem
2554e6df137Slukem /* if client has no access to specific value, don't compute */
2564e6df137Slukem if ( !access_allowed( op, rs->sr_entry,
2574e6df137Slukem slap_schema.si_ad_objectClass,
2584e6df137Slukem &oc->soc_cname, ACL_READ, &acl_state ) )
2594e6df137Slukem {
2604e6df137Slukem continue;
2614e6df137Slukem }
2624e6df137Slukem
2634e6df137Slukem aa_add_oc( oc, &ocp, &atp );
2644e6df137Slukem
2654e6df137Slukem if ( oc->soc_sups ) {
266ef2f90d3Sadam int i;
267ef2f90d3Sadam
2684e6df137Slukem for ( i = 0; oc->soc_sups[ i ] != NULL; i++ ) {
2694e6df137Slukem aa_add_oc( oc->soc_sups[ i ], &ocp, &atp );
2704e6df137Slukem }
2714e6df137Slukem }
2724e6df137Slukem }
2734e6df137Slukem
274ef2f90d3Sadam ch_free( ocp );
275ef2f90d3Sadam
2764e6df137Slukem if ( atp != NULL ) {
277ef2f90d3Sadam BerVarray bv_allowed = NULL,
278ef2f90d3Sadam bv_effective = NULL;
279ef2f90d3Sadam int i, ja = 0, je = 0;
280ef2f90d3Sadam
2814e6df137Slukem for ( i = 0; atp[ i ] != NULL; i++ )
2824e6df137Slukem /* just count */ ;
2834e6df137Slukem
2844e6df137Slukem if ( got & GOT_A ) {
285*549b59edSchristos bv_allowed = ch_calloc( i + 1, sizeof( struct berval ) );
2864e6df137Slukem }
2874e6df137Slukem if ( got & GOT_AE ) {
288*549b59edSchristos bv_effective = ch_calloc( i + 1, sizeof( struct berval ) );
2894e6df137Slukem }
2904e6df137Slukem
2914e6df137Slukem for ( i = 0, ja = 0, je = 0; atp[ i ] != NULL; i++ ) {
2924e6df137Slukem if ( got & GOT_A ) {
2934e6df137Slukem ber_dupbv( &bv_allowed[ ja ], &atp[ i ]->sat_cname );
2944e6df137Slukem ja++;
2954e6df137Slukem }
2964e6df137Slukem
2974e6df137Slukem if ( got & GOT_AE ) {
2984e6df137Slukem AttributeDescription *ad = NULL;
2994e6df137Slukem const char *text = NULL;
3004e6df137Slukem
3014e6df137Slukem if ( slap_bv2ad( &atp[ i ]->sat_cname, &ad, &text ) ) {
3024e6df137Slukem /* log? */
3034e6df137Slukem continue;
3044e6df137Slukem }
3054e6df137Slukem
3064e6df137Slukem if ( access_allowed( op, rs->sr_entry,
3074e6df137Slukem ad, NULL, ACL_WRITE, NULL ) )
3084e6df137Slukem {
3094e6df137Slukem ber_dupbv( &bv_effective[ je ], &atp[ i ]->sat_cname );
3104e6df137Slukem je++;
3114e6df137Slukem }
3124e6df137Slukem }
3134e6df137Slukem }
3144e6df137Slukem
315ef2f90d3Sadam ch_free( atp );
3164e6df137Slukem
3174e6df137Slukem if ( ( got & GOT_A ) && ja > 0 ) {
3184e6df137Slukem *ap = attr_alloc( ad_allowedAttributes );
3194e6df137Slukem (*ap)->a_vals = bv_allowed;
3204e6df137Slukem (*ap)->a_nvals = bv_allowed;
3214e6df137Slukem (*ap)->a_numvals = ja;
3224e6df137Slukem ap = &(*ap)->a_next;
3234e6df137Slukem }
3244e6df137Slukem
3254e6df137Slukem if ( ( got & GOT_AE ) && je > 0 ) {
3264e6df137Slukem *ap = attr_alloc( ad_allowedAttributesEffective );
3274e6df137Slukem (*ap)->a_vals = bv_effective;
3284e6df137Slukem (*ap)->a_nvals = bv_effective;
3294e6df137Slukem (*ap)->a_numvals = je;
3304e6df137Slukem ap = &(*ap)->a_next;
3314e6df137Slukem }
3324e6df137Slukem
3334e6df137Slukem *ap = NULL;
3344e6df137Slukem }
3354e6df137Slukem
336ef2f90d3Sadam do_oc:;
337ef2f90d3Sadam if ( ( got & GOT_C ) || ( got & GOT_CE ) ) {
338ef2f90d3Sadam BerVarray bv_allowed = NULL,
339ef2f90d3Sadam bv_effective = NULL;
340ef2f90d3Sadam int i, ja = 0, je = 0;
341ef2f90d3Sadam
342ef2f90d3Sadam ObjectClass *oc;
343ef2f90d3Sadam
344*549b59edSchristos for ( i = 0, oc_start( &oc ); oc != NULL; oc_next( &oc ) ) {
345ef2f90d3Sadam /* we can only add AUXILIARY objectClasses */
346ef2f90d3Sadam if ( oc->soc_kind != LDAP_SCHEMA_AUXILIARY ) {
347ef2f90d3Sadam continue;
348ef2f90d3Sadam }
349ef2f90d3Sadam
350ef2f90d3Sadam i++;
351ef2f90d3Sadam }
352ef2f90d3Sadam
353ef2f90d3Sadam if ( got & GOT_C ) {
354*549b59edSchristos bv_allowed = ch_calloc( i + 1, sizeof( struct berval ) );
355ef2f90d3Sadam }
356ef2f90d3Sadam if ( got & GOT_CE ) {
357*549b59edSchristos bv_effective = ch_calloc( i + 1, sizeof( struct berval ) );
358ef2f90d3Sadam }
359ef2f90d3Sadam
360ef2f90d3Sadam for ( oc_start( &oc ); oc != NULL; oc_next( &oc ) ) {
361ef2f90d3Sadam /* we can only add AUXILIARY objectClasses */
362ef2f90d3Sadam if ( oc->soc_kind != LDAP_SCHEMA_AUXILIARY ) {
363ef2f90d3Sadam continue;
364ef2f90d3Sadam }
365ef2f90d3Sadam
366ef2f90d3Sadam if ( got & GOT_C ) {
367ef2f90d3Sadam ber_dupbv( &bv_allowed[ ja ], &oc->soc_cname );
368ef2f90d3Sadam ja++;
369ef2f90d3Sadam }
370ef2f90d3Sadam
371ef2f90d3Sadam if ( got & GOT_CE ) {
372ef2f90d3Sadam if ( !access_allowed( op, rs->sr_entry,
373ef2f90d3Sadam slap_schema.si_ad_objectClass,
374ef2f90d3Sadam &oc->soc_cname, ACL_WRITE, NULL ) )
375ef2f90d3Sadam {
376ef2f90d3Sadam goto done_ce;
377ef2f90d3Sadam }
378ef2f90d3Sadam
379ef2f90d3Sadam if ( oc->soc_required ) {
380ef2f90d3Sadam for ( i = 0; oc->soc_required[ i ] != NULL; i++ ) {
381ef2f90d3Sadam AttributeDescription *ad = NULL;
382ef2f90d3Sadam const char *text = NULL;
383ef2f90d3Sadam
384ef2f90d3Sadam if ( slap_bv2ad( &oc->soc_required[ i ]->sat_cname, &ad, &text ) ) {
385ef2f90d3Sadam /* log? */
386ef2f90d3Sadam continue;
387ef2f90d3Sadam }
388ef2f90d3Sadam
389ef2f90d3Sadam if ( !access_allowed( op, rs->sr_entry,
390ef2f90d3Sadam ad, NULL, ACL_WRITE, NULL ) )
391ef2f90d3Sadam {
392ef2f90d3Sadam goto done_ce;
393ef2f90d3Sadam }
394ef2f90d3Sadam }
395ef2f90d3Sadam }
396ef2f90d3Sadam
397ef2f90d3Sadam ber_dupbv( &bv_effective[ je ], &oc->soc_cname );
398ef2f90d3Sadam je++;
399ef2f90d3Sadam }
400ef2f90d3Sadam done_ce:;
401ef2f90d3Sadam }
402ef2f90d3Sadam
403ef2f90d3Sadam if ( ( got & GOT_C ) && ja > 0 ) {
404ef2f90d3Sadam *ap = attr_alloc( ad_allowedChildClasses );
405ef2f90d3Sadam (*ap)->a_vals = bv_allowed;
406ef2f90d3Sadam (*ap)->a_nvals = bv_allowed;
407ef2f90d3Sadam (*ap)->a_numvals = ja;
408ef2f90d3Sadam ap = &(*ap)->a_next;
409ef2f90d3Sadam }
410ef2f90d3Sadam
411ef2f90d3Sadam if ( ( got & GOT_CE ) && je > 0 ) {
412ef2f90d3Sadam *ap = attr_alloc( ad_allowedChildClassesEffective );
413ef2f90d3Sadam (*ap)->a_vals = bv_effective;
414ef2f90d3Sadam (*ap)->a_nvals = bv_effective;
415ef2f90d3Sadam (*ap)->a_numvals = je;
416ef2f90d3Sadam ap = &(*ap)->a_next;
417ef2f90d3Sadam }
418ef2f90d3Sadam
419ef2f90d3Sadam *ap = NULL;
420ef2f90d3Sadam }
4214e6df137Slukem
4224e6df137Slukem return SLAP_CB_CONTINUE;
4234e6df137Slukem }
4244e6df137Slukem
4254e6df137Slukem static slap_overinst aa;
4264e6df137Slukem
4274e6df137Slukem #if LDAP_VENDOR_VERSION_MINOR != X && LDAP_VENDOR_VERSION_MINOR <= 3
4284e6df137Slukem /* backport register_at() from HEAD, to allow building with OL <= 2.3 */
4294e6df137Slukem static int
register_at(char * def,AttributeDescription ** rad,int dupok)4304e6df137Slukem register_at( char *def, AttributeDescription **rad, int dupok )
4314e6df137Slukem {
4324e6df137Slukem LDAPAttributeType *at;
4334e6df137Slukem int code, freeit = 0;
4344e6df137Slukem const char *err;
4354e6df137Slukem AttributeDescription *ad = NULL;
4364e6df137Slukem
4374e6df137Slukem at = ldap_str2attributetype( def, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
4384e6df137Slukem if ( !at ) {
4394e6df137Slukem Debug( LDAP_DEBUG_ANY,
4404e6df137Slukem "register_at: AttributeType \"%s\": %s, %s\n",
4414e6df137Slukem def, ldap_scherr2str(code), err );
4424e6df137Slukem return code;
4434e6df137Slukem }
4444e6df137Slukem
4454e6df137Slukem code = at_add( at, 0, NULL, &err );
4464e6df137Slukem if ( code ) {
4474e6df137Slukem if ( code == SLAP_SCHERR_ATTR_DUP && dupok ) {
4484e6df137Slukem freeit = 1;
4494e6df137Slukem
4504e6df137Slukem } else {
4514e6df137Slukem ldap_attributetype_free( at );
4524e6df137Slukem Debug( LDAP_DEBUG_ANY,
4534e6df137Slukem "register_at: AttributeType \"%s\": %s, %s\n",
4544e6df137Slukem def, scherr2str(code), err );
4554e6df137Slukem return code;
4564e6df137Slukem }
4574e6df137Slukem }
4584e6df137Slukem code = slap_str2ad( at->at_names[0], &ad, &err );
4594e6df137Slukem if ( freeit || code ) {
4604e6df137Slukem ldap_attributetype_free( at );
4614e6df137Slukem } else {
4624e6df137Slukem ldap_memfree( at );
4634e6df137Slukem }
4644e6df137Slukem if ( code ) {
4654e6df137Slukem Debug( LDAP_DEBUG_ANY, "register_at: AttributeType \"%s\": %s\n",
466*549b59edSchristos def, err );
4674e6df137Slukem }
4684e6df137Slukem if ( rad ) *rad = ad;
4694e6df137Slukem return code;
4704e6df137Slukem }
4714e6df137Slukem #endif
4724e6df137Slukem
4734e6df137Slukem #if SLAPD_OVER_ALLOWED == SLAPD_MOD_DYNAMIC
4744e6df137Slukem static
4754e6df137Slukem #endif /* SLAPD_OVER_ALLOWED == SLAPD_MOD_DYNAMIC */
4764e6df137Slukem int
aa_initialize(void)4774e6df137Slukem aa_initialize( void )
4784e6df137Slukem {
4794e6df137Slukem int i;
4804e6df137Slukem
4814e6df137Slukem aa.on_bi.bi_type = "allowed";
4824e6df137Slukem
483*549b59edSchristos aa.on_bi.bi_flags = SLAPO_BFLAG_SINGLE;
4844e6df137Slukem aa.on_bi.bi_operational = aa_operational;
4854e6df137Slukem
4864e6df137Slukem /* aa schema integration */
4874e6df137Slukem for ( i = 0; aa_attrs[i].at; i++ ) {
4884e6df137Slukem int code;
4894e6df137Slukem
4904e6df137Slukem code = register_at( aa_attrs[i].at, aa_attrs[i].ad, 0 );
4914e6df137Slukem if ( code ) {
4924e6df137Slukem Debug( LDAP_DEBUG_ANY,
493*549b59edSchristos "aa_initialize: register_at failed\n" );
4944e6df137Slukem return -1;
4954e6df137Slukem }
4964e6df137Slukem }
4974e6df137Slukem
4984e6df137Slukem return overlay_register( &aa );
4994e6df137Slukem }
5004e6df137Slukem
5014e6df137Slukem #if SLAPD_OVER_ALLOWED == SLAPD_MOD_DYNAMIC
5024e6df137Slukem int
init_module(int argc,char * argv[])5034e6df137Slukem init_module( int argc, char *argv[] )
5044e6df137Slukem {
5054e6df137Slukem return aa_initialize();
5064e6df137Slukem }
5074e6df137Slukem #endif /* SLAPD_OVER_ALLOWED == SLAPD_MOD_DYNAMIC */
5084e6df137Slukem
5094e6df137Slukem #endif /* SLAPD_OVER_ALLOWED */
510