1*cf1d77f7Schristos /* $NetBSD: cr.c,v 1.3 2021/08/14 16:14:58 christos Exp $ */
24e6df137Slukem
32de962bdSlukem /* cr.c - content rule routines */
433197c6aStron /* $OpenLDAP$ */
52de962bdSlukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
62de962bdSlukem *
7*cf1d77f7Schristos * Copyright 1998-2021 The OpenLDAP Foundation.
82de962bdSlukem * All rights reserved.
92de962bdSlukem *
102de962bdSlukem * Redistribution and use in source and binary forms, with or without
112de962bdSlukem * modification, are permitted only as authorized by the OpenLDAP
122de962bdSlukem * Public License.
132de962bdSlukem *
142de962bdSlukem * A copy of this license is available in the file LICENSE in the
152de962bdSlukem * top-level directory of the distribution or, alternatively, at
162de962bdSlukem * <http://www.OpenLDAP.org/license.html>.
172de962bdSlukem */
182de962bdSlukem
198bd9f7cdSchristos #include <sys/cdefs.h>
20*cf1d77f7Schristos __RCSID("$NetBSD: cr.c,v 1.3 2021/08/14 16:14:58 christos Exp $");
218bd9f7cdSchristos
222de962bdSlukem #include "portable.h"
232de962bdSlukem
242de962bdSlukem #include <stdio.h>
252de962bdSlukem
262de962bdSlukem #include <ac/ctype.h>
272de962bdSlukem #include <ac/string.h>
282de962bdSlukem #include <ac/socket.h>
292de962bdSlukem
302de962bdSlukem #include "slap.h"
312de962bdSlukem
322de962bdSlukem struct cindexrec {
332de962bdSlukem struct berval cir_name;
342de962bdSlukem ContentRule *cir_cr;
352de962bdSlukem };
362de962bdSlukem
372de962bdSlukem static Avlnode *cr_index = NULL;
382de962bdSlukem static LDAP_STAILQ_HEAD(CRList, ContentRule) cr_list
392de962bdSlukem = LDAP_STAILQ_HEAD_INITIALIZER(cr_list);
402de962bdSlukem
412de962bdSlukem static int
cr_index_cmp(const void * v_cir1,const void * v_cir2)422de962bdSlukem cr_index_cmp(
432de962bdSlukem const void *v_cir1,
442de962bdSlukem const void *v_cir2 )
452de962bdSlukem {
462de962bdSlukem const struct cindexrec *cir1 = v_cir1;
472de962bdSlukem const struct cindexrec *cir2 = v_cir2;
482de962bdSlukem int i = cir1->cir_name.bv_len - cir2->cir_name.bv_len;
492de962bdSlukem if (i) return i;
502de962bdSlukem return strcasecmp( cir1->cir_name.bv_val, cir2->cir_name.bv_val );
512de962bdSlukem }
522de962bdSlukem
532de962bdSlukem static int
cr_index_name_cmp(const void * v_name,const void * v_cir)542de962bdSlukem cr_index_name_cmp(
552de962bdSlukem const void *v_name,
562de962bdSlukem const void *v_cir )
572de962bdSlukem {
582de962bdSlukem const struct berval *name = v_name;
592de962bdSlukem const struct cindexrec *cir = v_cir;
602de962bdSlukem int i = name->bv_len - cir->cir_name.bv_len;
612de962bdSlukem if (i) return i;
622de962bdSlukem return strncasecmp( name->bv_val, cir->cir_name.bv_val, name->bv_len );
632de962bdSlukem }
642de962bdSlukem
652de962bdSlukem ContentRule *
cr_find(const char * crname)662de962bdSlukem cr_find( const char *crname )
672de962bdSlukem {
682de962bdSlukem struct berval bv;
692de962bdSlukem
702de962bdSlukem bv.bv_val = (char *)crname;
712de962bdSlukem bv.bv_len = strlen( crname );
722de962bdSlukem
732de962bdSlukem return( cr_bvfind( &bv ) );
742de962bdSlukem }
752de962bdSlukem
762de962bdSlukem ContentRule *
cr_bvfind(struct berval * crname)772de962bdSlukem cr_bvfind( struct berval *crname )
782de962bdSlukem {
792de962bdSlukem struct cindexrec *cir;
802de962bdSlukem
81*cf1d77f7Schristos cir = ldap_avl_find( cr_index, crname, cr_index_name_cmp );
822de962bdSlukem
832de962bdSlukem if ( cir != NULL ) {
842de962bdSlukem return( cir->cir_cr );
852de962bdSlukem }
862de962bdSlukem
872de962bdSlukem return( NULL );
882de962bdSlukem }
892de962bdSlukem
902de962bdSlukem static int
cr_destroy_one(ContentRule * c)912de962bdSlukem cr_destroy_one( ContentRule *c )
922de962bdSlukem {
932de962bdSlukem assert( c != NULL );
942de962bdSlukem
952de962bdSlukem if (c->scr_auxiliaries) ldap_memfree(c->scr_auxiliaries);
962de962bdSlukem if (c->scr_required) ldap_memfree(c->scr_required);
972de962bdSlukem if (c->scr_allowed) ldap_memfree(c->scr_allowed);
982de962bdSlukem if (c->scr_precluded) ldap_memfree(c->scr_precluded);
992de962bdSlukem ldap_contentrule_free((LDAPContentRule *)c);
1002de962bdSlukem
1012de962bdSlukem return 0;
1022de962bdSlukem }
1032de962bdSlukem
1042de962bdSlukem void
cr_destroy(void)1052de962bdSlukem cr_destroy( void )
1062de962bdSlukem {
1072de962bdSlukem ContentRule *c;
1082de962bdSlukem
109*cf1d77f7Schristos ldap_avl_free(cr_index, ldap_memfree);
1102de962bdSlukem
1112de962bdSlukem while( !LDAP_STAILQ_EMPTY(&cr_list) ) {
1122de962bdSlukem c = LDAP_STAILQ_FIRST(&cr_list);
1132de962bdSlukem LDAP_STAILQ_REMOVE_HEAD(&cr_list, scr_next);
1142de962bdSlukem
1152de962bdSlukem cr_destroy_one( c );
1162de962bdSlukem }
1172de962bdSlukem }
1182de962bdSlukem
1192de962bdSlukem static int
cr_insert(ContentRule * scr,const char ** err)1202de962bdSlukem cr_insert(
1212de962bdSlukem ContentRule *scr,
1222de962bdSlukem const char **err
1232de962bdSlukem )
1242de962bdSlukem {
1252de962bdSlukem struct cindexrec *cir;
1262de962bdSlukem char **names;
1272de962bdSlukem
12833197c6aStron assert( scr != NULL );
12933197c6aStron
1302de962bdSlukem if ( scr->scr_oid ) {
1312de962bdSlukem cir = (struct cindexrec *)
1322de962bdSlukem ch_calloc( 1, sizeof(struct cindexrec) );
1332de962bdSlukem cir->cir_name.bv_val = scr->scr_oid;
1342de962bdSlukem cir->cir_name.bv_len = strlen( scr->scr_oid );
1352de962bdSlukem cir->cir_cr = scr;
1362de962bdSlukem
137*cf1d77f7Schristos if ( ldap_avl_insert( &cr_index, (caddr_t) cir,
138*cf1d77f7Schristos cr_index_cmp, ldap_avl_dup_error ) )
1392de962bdSlukem {
1402de962bdSlukem *err = scr->scr_oid;
1412de962bdSlukem ldap_memfree(cir);
1422de962bdSlukem return SLAP_SCHERR_CR_DUP;
1432de962bdSlukem }
1442de962bdSlukem
1452de962bdSlukem /* FIX: temporal consistency check */
1462de962bdSlukem assert( cr_bvfind(&cir->cir_name) != NULL );
1472de962bdSlukem }
1482de962bdSlukem
1492de962bdSlukem if ( (names = scr->scr_names) ) {
1502de962bdSlukem while ( *names ) {
1512de962bdSlukem cir = (struct cindexrec *)
1522de962bdSlukem ch_calloc( 1, sizeof(struct cindexrec) );
1532de962bdSlukem cir->cir_name.bv_val = *names;
1542de962bdSlukem cir->cir_name.bv_len = strlen( *names );
1552de962bdSlukem cir->cir_cr = scr;
1562de962bdSlukem
157*cf1d77f7Schristos if ( ldap_avl_insert( &cr_index, (caddr_t) cir,
158*cf1d77f7Schristos cr_index_cmp, ldap_avl_dup_error ) )
1592de962bdSlukem {
1602de962bdSlukem *err = *names;
1612de962bdSlukem ldap_memfree(cir);
1622de962bdSlukem return SLAP_SCHERR_CR_DUP;
1632de962bdSlukem }
1642de962bdSlukem
1652de962bdSlukem /* FIX: temporal consistency check */
1662de962bdSlukem assert( cr_bvfind(&cir->cir_name) != NULL );
1672de962bdSlukem
1682de962bdSlukem names++;
1692de962bdSlukem }
1702de962bdSlukem }
1712de962bdSlukem
1722de962bdSlukem LDAP_STAILQ_INSERT_TAIL(&cr_list, scr, scr_next);
1732de962bdSlukem
1742de962bdSlukem return 0;
1752de962bdSlukem }
1762de962bdSlukem
1772de962bdSlukem static int
cr_add_auxiliaries(ContentRule * scr,int * op,const char ** err)1782de962bdSlukem cr_add_auxiliaries(
1792de962bdSlukem ContentRule *scr,
1802de962bdSlukem int *op,
1812de962bdSlukem const char **err )
1822de962bdSlukem {
1832de962bdSlukem int naux;
1842de962bdSlukem
1852de962bdSlukem if( scr->scr_oc_oids_aux == NULL ) return 0;
1862de962bdSlukem
1872de962bdSlukem for( naux=0; scr->scr_oc_oids_aux[naux]; naux++ ) {
1882de962bdSlukem /* count them */ ;
1892de962bdSlukem }
1902de962bdSlukem
1912de962bdSlukem scr->scr_auxiliaries = ch_calloc( naux+1, sizeof(ObjectClass *));
1922de962bdSlukem
1932de962bdSlukem for( naux=0; scr->scr_oc_oids_aux[naux]; naux++ ) {
1942de962bdSlukem ObjectClass *soc = scr->scr_auxiliaries[naux]
1952de962bdSlukem = oc_find(scr->scr_oc_oids_aux[naux]);
1962de962bdSlukem if ( !soc ) {
1972de962bdSlukem *err = scr->scr_oc_oids_aux[naux];
1982de962bdSlukem return SLAP_SCHERR_CLASS_NOT_FOUND;
1992de962bdSlukem }
2002de962bdSlukem
2012de962bdSlukem if( soc->soc_flags & SLAP_OC_OPERATIONAL &&
2022de962bdSlukem soc != slap_schema.si_oc_extensibleObject )
2032de962bdSlukem {
2042de962bdSlukem (*op)++;
2052de962bdSlukem }
2062de962bdSlukem
2072de962bdSlukem if( soc->soc_kind != LDAP_SCHEMA_AUXILIARY ) {
2082de962bdSlukem *err = scr->scr_oc_oids_aux[naux];
2092de962bdSlukem return SLAP_SCHERR_CR_BAD_AUX;
2102de962bdSlukem }
2112de962bdSlukem }
2122de962bdSlukem
2132de962bdSlukem scr->scr_auxiliaries[naux] = NULL;
2142de962bdSlukem return 0;
2152de962bdSlukem }
2162de962bdSlukem
2172de962bdSlukem static int
cr_create_required(ContentRule * scr,int * op,const char ** err)2182de962bdSlukem cr_create_required(
2192de962bdSlukem ContentRule *scr,
2202de962bdSlukem int *op,
2212de962bdSlukem const char **err )
2222de962bdSlukem {
2232de962bdSlukem char **attrs = scr->scr_at_oids_must;
2242de962bdSlukem char **attrs1;
2252de962bdSlukem AttributeType *sat;
2262de962bdSlukem
2272de962bdSlukem if ( attrs ) {
2282de962bdSlukem attrs1 = attrs;
2292de962bdSlukem while ( *attrs1 ) {
2302de962bdSlukem sat = at_find(*attrs1);
2312de962bdSlukem if ( !sat ) {
2322de962bdSlukem *err = *attrs1;
2332de962bdSlukem return SLAP_SCHERR_ATTR_NOT_FOUND;
2342de962bdSlukem }
2352de962bdSlukem
2362de962bdSlukem if( is_at_operational( sat )) (*op)++;
2372de962bdSlukem
2382de962bdSlukem if ( at_find_in_list(sat, scr->scr_required) < 0) {
2392de962bdSlukem if ( at_append_to_list(sat, &scr->scr_required) ) {
2402de962bdSlukem *err = *attrs1;
2412de962bdSlukem return SLAP_SCHERR_OUTOFMEM;
2422de962bdSlukem }
2432de962bdSlukem } else {
2442de962bdSlukem *err = *attrs1;
2452de962bdSlukem return SLAP_SCHERR_CR_BAD_AT;
2462de962bdSlukem }
2472de962bdSlukem attrs1++;
2482de962bdSlukem }
2492de962bdSlukem }
2502de962bdSlukem return 0;
2512de962bdSlukem }
2522de962bdSlukem
2532de962bdSlukem static int
cr_create_allowed(ContentRule * scr,int * op,const char ** err)2542de962bdSlukem cr_create_allowed(
2552de962bdSlukem ContentRule *scr,
2562de962bdSlukem int *op,
2572de962bdSlukem const char **err )
2582de962bdSlukem {
2592de962bdSlukem char **attrs = scr->scr_at_oids_may;
2602de962bdSlukem char **attrs1;
2612de962bdSlukem AttributeType *sat;
2622de962bdSlukem
2632de962bdSlukem if ( attrs ) {
2642de962bdSlukem attrs1 = attrs;
2652de962bdSlukem while ( *attrs1 ) {
2662de962bdSlukem sat = at_find(*attrs1);
2672de962bdSlukem if ( !sat ) {
2682de962bdSlukem *err = *attrs1;
2692de962bdSlukem return SLAP_SCHERR_ATTR_NOT_FOUND;
2702de962bdSlukem }
2712de962bdSlukem
2722de962bdSlukem if( is_at_operational( sat )) (*op)++;
2732de962bdSlukem
2742de962bdSlukem if ( at_find_in_list(sat, scr->scr_required) < 0 &&
2752de962bdSlukem at_find_in_list(sat, scr->scr_allowed) < 0 )
2762de962bdSlukem {
2772de962bdSlukem if ( at_append_to_list(sat, &scr->scr_allowed) ) {
2782de962bdSlukem *err = *attrs1;
2792de962bdSlukem return SLAP_SCHERR_OUTOFMEM;
2802de962bdSlukem }
2812de962bdSlukem } else {
2822de962bdSlukem *err = *attrs1;
2832de962bdSlukem return SLAP_SCHERR_CR_BAD_AT;
2842de962bdSlukem }
2852de962bdSlukem attrs1++;
2862de962bdSlukem }
2872de962bdSlukem }
2882de962bdSlukem return 0;
2892de962bdSlukem }
2902de962bdSlukem
2912de962bdSlukem static int
cr_create_precluded(ContentRule * scr,int * op,const char ** err)2922de962bdSlukem cr_create_precluded(
2932de962bdSlukem ContentRule *scr,
2942de962bdSlukem int *op,
2952de962bdSlukem const char **err )
2962de962bdSlukem {
2972de962bdSlukem char **attrs = scr->scr_at_oids_not;
2982de962bdSlukem char **attrs1;
2992de962bdSlukem AttributeType *sat;
3002de962bdSlukem
3012de962bdSlukem if ( attrs ) {
3022de962bdSlukem attrs1 = attrs;
3032de962bdSlukem while ( *attrs1 ) {
3042de962bdSlukem sat = at_find(*attrs1);
3052de962bdSlukem if ( !sat ) {
3062de962bdSlukem *err = *attrs1;
3072de962bdSlukem return SLAP_SCHERR_ATTR_NOT_FOUND;
3082de962bdSlukem }
3092de962bdSlukem
3102de962bdSlukem if( is_at_operational( sat )) (*op)++;
3112de962bdSlukem
3122de962bdSlukem /* FIXME: should also make sure attribute type is not
3132de962bdSlukem a required attribute of the structural class or
3142de962bdSlukem any auxiliary class */
3152de962bdSlukem if ( at_find_in_list(sat, scr->scr_required) < 0 &&
3162de962bdSlukem at_find_in_list(sat, scr->scr_allowed) < 0 &&
3172de962bdSlukem at_find_in_list(sat, scr->scr_precluded) < 0 )
3182de962bdSlukem {
3192de962bdSlukem if ( at_append_to_list(sat, &scr->scr_precluded) ) {
3202de962bdSlukem *err = *attrs1;
3212de962bdSlukem return SLAP_SCHERR_OUTOFMEM;
3222de962bdSlukem }
3232de962bdSlukem } else {
3242de962bdSlukem *err = *attrs1;
3252de962bdSlukem return SLAP_SCHERR_CR_BAD_AT;
3262de962bdSlukem }
3272de962bdSlukem attrs1++;
3282de962bdSlukem }
3292de962bdSlukem }
3302de962bdSlukem return 0;
3312de962bdSlukem }
3322de962bdSlukem
3332de962bdSlukem int
cr_add(LDAPContentRule * cr,int user,ContentRule ** rscr,const char ** err)3342de962bdSlukem cr_add(
3352de962bdSlukem LDAPContentRule *cr,
3362de962bdSlukem int user,
3372de962bdSlukem ContentRule **rscr,
3382de962bdSlukem const char **err
3392de962bdSlukem )
3402de962bdSlukem {
3412de962bdSlukem ContentRule *scr;
3422de962bdSlukem int code;
3432de962bdSlukem int op = 0;
3442de962bdSlukem char *oidm = NULL;
3452de962bdSlukem
3462de962bdSlukem if ( cr->cr_names != NULL ) {
3472de962bdSlukem int i;
3482de962bdSlukem
3492de962bdSlukem for( i=0; cr->cr_names[i]; i++ ) {
3502de962bdSlukem if( !slap_valid_descr( cr->cr_names[i] ) ) {
3512de962bdSlukem return SLAP_SCHERR_BAD_DESCR;
3522de962bdSlukem }
3532de962bdSlukem }
3542de962bdSlukem }
3552de962bdSlukem
3562de962bdSlukem if ( !OID_LEADCHAR( cr->cr_oid[0] )) {
3572de962bdSlukem /* Expand OID macros */
3582de962bdSlukem char *oid = oidm_find( cr->cr_oid );
3592de962bdSlukem if ( !oid ) {
3602de962bdSlukem *err = cr->cr_oid;
3612de962bdSlukem return SLAP_SCHERR_OIDM;
3622de962bdSlukem }
3632de962bdSlukem if ( oid != cr->cr_oid ) {
3642de962bdSlukem oidm = cr->cr_oid;
3652de962bdSlukem cr->cr_oid = oid;
3662de962bdSlukem }
3672de962bdSlukem }
3682de962bdSlukem
3692de962bdSlukem scr = (ContentRule *) ch_calloc( 1, sizeof(ContentRule) );
3702de962bdSlukem AC_MEMCPY( &scr->scr_crule, cr, sizeof(LDAPContentRule) );
3712de962bdSlukem
3722de962bdSlukem scr->scr_oidmacro = oidm;
3732de962bdSlukem scr->scr_sclass = oc_find(cr->cr_oid);
3742de962bdSlukem if ( !scr->scr_sclass ) {
3752de962bdSlukem *err = cr->cr_oid;
3762de962bdSlukem code = SLAP_SCHERR_CLASS_NOT_FOUND;
3772de962bdSlukem goto fail;
3782de962bdSlukem }
3792de962bdSlukem
3802de962bdSlukem /* check object class usage */
3812de962bdSlukem if( scr->scr_sclass->soc_kind != LDAP_SCHEMA_STRUCTURAL )
3822de962bdSlukem {
3832de962bdSlukem *err = cr->cr_oid;
3842de962bdSlukem code = SLAP_SCHERR_CR_BAD_STRUCT;
3852de962bdSlukem goto fail;
3862de962bdSlukem }
3872de962bdSlukem
3882de962bdSlukem if( scr->scr_sclass->soc_flags & SLAP_OC_OPERATIONAL ) op++;
3892de962bdSlukem
3902de962bdSlukem code = cr_add_auxiliaries( scr, &op, err );
3912de962bdSlukem if ( code != 0 ) goto fail;
3922de962bdSlukem
3932de962bdSlukem code = cr_create_required( scr, &op, err );
3942de962bdSlukem if ( code != 0 ) goto fail;
3952de962bdSlukem
3962de962bdSlukem code = cr_create_allowed( scr, &op, err );
3972de962bdSlukem if ( code != 0 ) goto fail;
3982de962bdSlukem
3992de962bdSlukem code = cr_create_precluded( scr, &op, err );
4002de962bdSlukem if ( code != 0 ) goto fail;
4012de962bdSlukem
4022de962bdSlukem if( user && op ) {
4032de962bdSlukem code = SLAP_SCHERR_CR_BAD_AUX;
4042de962bdSlukem goto fail;
4052de962bdSlukem }
4062de962bdSlukem
4072de962bdSlukem code = cr_insert(scr,err);
4082de962bdSlukem if ( code == 0 && rscr )
4092de962bdSlukem *rscr = scr;
4102de962bdSlukem return code;
4112de962bdSlukem fail:
4122de962bdSlukem ch_free( scr );
4132de962bdSlukem return code;
4142de962bdSlukem }
4152de962bdSlukem
4162de962bdSlukem void
cr_unparse(BerVarray * res,ContentRule * start,ContentRule * end,int sys)4172de962bdSlukem cr_unparse( BerVarray *res, ContentRule *start, ContentRule *end, int sys )
4182de962bdSlukem {
4192de962bdSlukem ContentRule *cr;
4202de962bdSlukem int i, num;
4212de962bdSlukem struct berval bv, *bva = NULL, idx;
4222de962bdSlukem char ibuf[32];
4232de962bdSlukem
4242de962bdSlukem if ( !start )
4252de962bdSlukem start = LDAP_STAILQ_FIRST( &cr_list );
4262de962bdSlukem
4272de962bdSlukem /* count the result size */
4282de962bdSlukem i = 0;
4292de962bdSlukem for ( cr=start; cr; cr=LDAP_STAILQ_NEXT(cr, scr_next)) {
4302de962bdSlukem if ( sys && !(cr->scr_flags & SLAP_CR_HARDCODE)) continue;
4312de962bdSlukem i++;
4322de962bdSlukem if ( cr == end ) break;
4332de962bdSlukem }
4342de962bdSlukem if (!i) return;
4352de962bdSlukem
4362de962bdSlukem num = i;
4372de962bdSlukem bva = ch_malloc( (num+1) * sizeof(struct berval) );
4382de962bdSlukem BER_BVZERO( bva );
4392de962bdSlukem idx.bv_val = ibuf;
4402de962bdSlukem if ( sys ) {
4412de962bdSlukem idx.bv_len = 0;
4422de962bdSlukem ibuf[0] = '\0';
4432de962bdSlukem }
4442de962bdSlukem i = 0;
4452de962bdSlukem for ( cr=start; cr; cr=LDAP_STAILQ_NEXT(cr, scr_next)) {
4462de962bdSlukem LDAPContentRule lcr, *lcrp;
4472de962bdSlukem if ( sys && !(cr->scr_flags & SLAP_CR_HARDCODE)) continue;
4482de962bdSlukem if ( cr->scr_oidmacro ) {
4492de962bdSlukem lcr = cr->scr_crule;
4502de962bdSlukem lcr.cr_oid = cr->scr_oidmacro;
4512de962bdSlukem lcrp = &lcr;
4522de962bdSlukem } else {
4532de962bdSlukem lcrp = &cr->scr_crule;
4542de962bdSlukem }
4552de962bdSlukem if ( ldap_contentrule2bv( lcrp, &bv ) == NULL ) {
4562de962bdSlukem ber_bvarray_free( bva );
4572de962bdSlukem }
4582de962bdSlukem if ( !sys ) {
4592de962bdSlukem idx.bv_len = sprintf(idx.bv_val, "{%d}", i);
4602de962bdSlukem }
4612de962bdSlukem bva[i].bv_len = idx.bv_len + bv.bv_len;
4622de962bdSlukem bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
4632de962bdSlukem strcpy( bva[i].bv_val, ibuf );
4642de962bdSlukem strcpy( bva[i].bv_val + idx.bv_len, bv.bv_val );
4652de962bdSlukem i++;
4662de962bdSlukem bva[i].bv_val = NULL;
4672de962bdSlukem ldap_memfree( bv.bv_val );
4682de962bdSlukem if ( cr == end ) break;
4692de962bdSlukem }
4702de962bdSlukem *res = bva;
4712de962bdSlukem }
4722de962bdSlukem
4732de962bdSlukem int
cr_schema_info(Entry * e)4742de962bdSlukem cr_schema_info( Entry *e )
4752de962bdSlukem {
4762de962bdSlukem AttributeDescription *ad_ditContentRules
4772de962bdSlukem = slap_schema.si_ad_ditContentRules;
4782de962bdSlukem ContentRule *cr;
4792de962bdSlukem
4802de962bdSlukem struct berval val;
4812de962bdSlukem struct berval nval;
4822de962bdSlukem
4832de962bdSlukem LDAP_STAILQ_FOREACH(cr, &cr_list, scr_next) {
4842de962bdSlukem if ( ldap_contentrule2bv( &cr->scr_crule, &val ) == NULL ) {
4852de962bdSlukem return -1;
4862de962bdSlukem }
4872de962bdSlukem
4882de962bdSlukem #if 0
4892de962bdSlukem if( cr->scr_flags & SLAP_CR_HIDE ) continue;
4902de962bdSlukem #endif
4912de962bdSlukem #if 0
4922de962bdSlukem Debug( LDAP_DEBUG_TRACE, "Merging cr [%ld] %s\n",
493*cf1d77f7Schristos (long) val.bv_len, val.bv_val );
4942de962bdSlukem #endif
4952de962bdSlukem
4962de962bdSlukem nval.bv_val = cr->scr_oid;
4972de962bdSlukem nval.bv_len = strlen(cr->scr_oid);
4982de962bdSlukem
4992de962bdSlukem if( attr_merge_one( e, ad_ditContentRules, &val, &nval ) )
5002de962bdSlukem {
5012de962bdSlukem return -1;
5022de962bdSlukem }
5032de962bdSlukem ldap_memfree( val.bv_val );
5042de962bdSlukem }
5052de962bdSlukem return 0;
5062de962bdSlukem }
507