1*2de962bdSlukem /* cr.c - content rule routines */ 2*2de962bdSlukem /* $OpenLDAP: pkg/ldap/servers/slapd/cr.c,v 1.22.2.3 2008/02/11 23:26:44 kurt Exp $ */ 3*2de962bdSlukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4*2de962bdSlukem * 5*2de962bdSlukem * Copyright 1998-2008 The OpenLDAP Foundation. 6*2de962bdSlukem * All rights reserved. 7*2de962bdSlukem * 8*2de962bdSlukem * Redistribution and use in source and binary forms, with or without 9*2de962bdSlukem * modification, are permitted only as authorized by the OpenLDAP 10*2de962bdSlukem * Public License. 11*2de962bdSlukem * 12*2de962bdSlukem * A copy of this license is available in the file LICENSE in the 13*2de962bdSlukem * top-level directory of the distribution or, alternatively, at 14*2de962bdSlukem * <http://www.OpenLDAP.org/license.html>. 15*2de962bdSlukem */ 16*2de962bdSlukem 17*2de962bdSlukem #include "portable.h" 18*2de962bdSlukem 19*2de962bdSlukem #include <stdio.h> 20*2de962bdSlukem 21*2de962bdSlukem #include <ac/ctype.h> 22*2de962bdSlukem #include <ac/string.h> 23*2de962bdSlukem #include <ac/socket.h> 24*2de962bdSlukem 25*2de962bdSlukem #include "slap.h" 26*2de962bdSlukem 27*2de962bdSlukem struct cindexrec { 28*2de962bdSlukem struct berval cir_name; 29*2de962bdSlukem ContentRule *cir_cr; 30*2de962bdSlukem }; 31*2de962bdSlukem 32*2de962bdSlukem static Avlnode *cr_index = NULL; 33*2de962bdSlukem static LDAP_STAILQ_HEAD(CRList, ContentRule) cr_list 34*2de962bdSlukem = LDAP_STAILQ_HEAD_INITIALIZER(cr_list); 35*2de962bdSlukem 36*2de962bdSlukem static int 37*2de962bdSlukem cr_index_cmp( 38*2de962bdSlukem const void *v_cir1, 39*2de962bdSlukem const void *v_cir2 ) 40*2de962bdSlukem { 41*2de962bdSlukem const struct cindexrec *cir1 = v_cir1; 42*2de962bdSlukem const struct cindexrec *cir2 = v_cir2; 43*2de962bdSlukem int i = cir1->cir_name.bv_len - cir2->cir_name.bv_len; 44*2de962bdSlukem if (i) return i; 45*2de962bdSlukem return strcasecmp( cir1->cir_name.bv_val, cir2->cir_name.bv_val ); 46*2de962bdSlukem } 47*2de962bdSlukem 48*2de962bdSlukem static int 49*2de962bdSlukem cr_index_name_cmp( 50*2de962bdSlukem const void *v_name, 51*2de962bdSlukem const void *v_cir ) 52*2de962bdSlukem { 53*2de962bdSlukem const struct berval *name = v_name; 54*2de962bdSlukem const struct cindexrec *cir = v_cir; 55*2de962bdSlukem int i = name->bv_len - cir->cir_name.bv_len; 56*2de962bdSlukem if (i) return i; 57*2de962bdSlukem return strncasecmp( name->bv_val, cir->cir_name.bv_val, name->bv_len ); 58*2de962bdSlukem } 59*2de962bdSlukem 60*2de962bdSlukem ContentRule * 61*2de962bdSlukem cr_find( const char *crname ) 62*2de962bdSlukem { 63*2de962bdSlukem struct berval bv; 64*2de962bdSlukem 65*2de962bdSlukem bv.bv_val = (char *)crname; 66*2de962bdSlukem bv.bv_len = strlen( crname ); 67*2de962bdSlukem 68*2de962bdSlukem return( cr_bvfind( &bv ) ); 69*2de962bdSlukem } 70*2de962bdSlukem 71*2de962bdSlukem ContentRule * 72*2de962bdSlukem cr_bvfind( struct berval *crname ) 73*2de962bdSlukem { 74*2de962bdSlukem struct cindexrec *cir; 75*2de962bdSlukem 76*2de962bdSlukem cir = avl_find( cr_index, crname, cr_index_name_cmp ); 77*2de962bdSlukem 78*2de962bdSlukem if ( cir != NULL ) { 79*2de962bdSlukem return( cir->cir_cr ); 80*2de962bdSlukem } 81*2de962bdSlukem 82*2de962bdSlukem return( NULL ); 83*2de962bdSlukem } 84*2de962bdSlukem 85*2de962bdSlukem static int 86*2de962bdSlukem cr_destroy_one( ContentRule *c ) 87*2de962bdSlukem { 88*2de962bdSlukem assert( c != NULL ); 89*2de962bdSlukem 90*2de962bdSlukem if (c->scr_auxiliaries) ldap_memfree(c->scr_auxiliaries); 91*2de962bdSlukem if (c->scr_required) ldap_memfree(c->scr_required); 92*2de962bdSlukem if (c->scr_allowed) ldap_memfree(c->scr_allowed); 93*2de962bdSlukem if (c->scr_precluded) ldap_memfree(c->scr_precluded); 94*2de962bdSlukem ldap_contentrule_free((LDAPContentRule *)c); 95*2de962bdSlukem 96*2de962bdSlukem return 0; 97*2de962bdSlukem } 98*2de962bdSlukem 99*2de962bdSlukem void 100*2de962bdSlukem cr_destroy( void ) 101*2de962bdSlukem { 102*2de962bdSlukem ContentRule *c; 103*2de962bdSlukem 104*2de962bdSlukem avl_free(cr_index, ldap_memfree); 105*2de962bdSlukem 106*2de962bdSlukem while( !LDAP_STAILQ_EMPTY(&cr_list) ) { 107*2de962bdSlukem c = LDAP_STAILQ_FIRST(&cr_list); 108*2de962bdSlukem LDAP_STAILQ_REMOVE_HEAD(&cr_list, scr_next); 109*2de962bdSlukem 110*2de962bdSlukem cr_destroy_one( c ); 111*2de962bdSlukem } 112*2de962bdSlukem } 113*2de962bdSlukem 114*2de962bdSlukem static int 115*2de962bdSlukem cr_insert( 116*2de962bdSlukem ContentRule *scr, 117*2de962bdSlukem const char **err 118*2de962bdSlukem ) 119*2de962bdSlukem { 120*2de962bdSlukem struct cindexrec *cir; 121*2de962bdSlukem char **names; 122*2de962bdSlukem 123*2de962bdSlukem if ( scr->scr_oid ) { 124*2de962bdSlukem cir = (struct cindexrec *) 125*2de962bdSlukem ch_calloc( 1, sizeof(struct cindexrec) ); 126*2de962bdSlukem cir->cir_name.bv_val = scr->scr_oid; 127*2de962bdSlukem cir->cir_name.bv_len = strlen( scr->scr_oid ); 128*2de962bdSlukem cir->cir_cr = scr; 129*2de962bdSlukem 130*2de962bdSlukem assert( cir->cir_name.bv_val != NULL ); 131*2de962bdSlukem assert( cir->cir_cr != NULL ); 132*2de962bdSlukem 133*2de962bdSlukem if ( avl_insert( &cr_index, (caddr_t) cir, 134*2de962bdSlukem cr_index_cmp, avl_dup_error ) ) 135*2de962bdSlukem { 136*2de962bdSlukem *err = scr->scr_oid; 137*2de962bdSlukem ldap_memfree(cir); 138*2de962bdSlukem return SLAP_SCHERR_CR_DUP; 139*2de962bdSlukem } 140*2de962bdSlukem 141*2de962bdSlukem /* FIX: temporal consistency check */ 142*2de962bdSlukem assert( cr_bvfind(&cir->cir_name) != NULL ); 143*2de962bdSlukem } 144*2de962bdSlukem 145*2de962bdSlukem if ( (names = scr->scr_names) ) { 146*2de962bdSlukem while ( *names ) { 147*2de962bdSlukem cir = (struct cindexrec *) 148*2de962bdSlukem ch_calloc( 1, sizeof(struct cindexrec) ); 149*2de962bdSlukem cir->cir_name.bv_val = *names; 150*2de962bdSlukem cir->cir_name.bv_len = strlen( *names ); 151*2de962bdSlukem cir->cir_cr = scr; 152*2de962bdSlukem 153*2de962bdSlukem assert( cir->cir_name.bv_val != NULL ); 154*2de962bdSlukem assert( cir->cir_cr != NULL ); 155*2de962bdSlukem 156*2de962bdSlukem if ( avl_insert( &cr_index, (caddr_t) cir, 157*2de962bdSlukem cr_index_cmp, avl_dup_error ) ) 158*2de962bdSlukem { 159*2de962bdSlukem *err = *names; 160*2de962bdSlukem ldap_memfree(cir); 161*2de962bdSlukem return SLAP_SCHERR_CR_DUP; 162*2de962bdSlukem } 163*2de962bdSlukem 164*2de962bdSlukem /* FIX: temporal consistency check */ 165*2de962bdSlukem assert( cr_bvfind(&cir->cir_name) != NULL ); 166*2de962bdSlukem 167*2de962bdSlukem names++; 168*2de962bdSlukem } 169*2de962bdSlukem } 170*2de962bdSlukem 171*2de962bdSlukem LDAP_STAILQ_INSERT_TAIL(&cr_list, scr, scr_next); 172*2de962bdSlukem 173*2de962bdSlukem return 0; 174*2de962bdSlukem } 175*2de962bdSlukem 176*2de962bdSlukem static int 177*2de962bdSlukem cr_add_auxiliaries( 178*2de962bdSlukem ContentRule *scr, 179*2de962bdSlukem int *op, 180*2de962bdSlukem const char **err ) 181*2de962bdSlukem { 182*2de962bdSlukem int naux; 183*2de962bdSlukem 184*2de962bdSlukem if( scr->scr_oc_oids_aux == NULL ) return 0; 185*2de962bdSlukem 186*2de962bdSlukem for( naux=0; scr->scr_oc_oids_aux[naux]; naux++ ) { 187*2de962bdSlukem /* count them */ ; 188*2de962bdSlukem } 189*2de962bdSlukem 190*2de962bdSlukem scr->scr_auxiliaries = ch_calloc( naux+1, sizeof(ObjectClass *)); 191*2de962bdSlukem 192*2de962bdSlukem for( naux=0; scr->scr_oc_oids_aux[naux]; naux++ ) { 193*2de962bdSlukem ObjectClass *soc = scr->scr_auxiliaries[naux] 194*2de962bdSlukem = oc_find(scr->scr_oc_oids_aux[naux]); 195*2de962bdSlukem if ( !soc ) { 196*2de962bdSlukem *err = scr->scr_oc_oids_aux[naux]; 197*2de962bdSlukem return SLAP_SCHERR_CLASS_NOT_FOUND; 198*2de962bdSlukem } 199*2de962bdSlukem 200*2de962bdSlukem if( soc->soc_flags & SLAP_OC_OPERATIONAL && 201*2de962bdSlukem soc != slap_schema.si_oc_extensibleObject ) 202*2de962bdSlukem { 203*2de962bdSlukem (*op)++; 204*2de962bdSlukem } 205*2de962bdSlukem 206*2de962bdSlukem if( soc->soc_kind != LDAP_SCHEMA_AUXILIARY ) { 207*2de962bdSlukem *err = scr->scr_oc_oids_aux[naux]; 208*2de962bdSlukem return SLAP_SCHERR_CR_BAD_AUX; 209*2de962bdSlukem } 210*2de962bdSlukem } 211*2de962bdSlukem 212*2de962bdSlukem scr->scr_auxiliaries[naux] = NULL; 213*2de962bdSlukem return 0; 214*2de962bdSlukem } 215*2de962bdSlukem 216*2de962bdSlukem static int 217*2de962bdSlukem cr_create_required( 218*2de962bdSlukem ContentRule *scr, 219*2de962bdSlukem int *op, 220*2de962bdSlukem const char **err ) 221*2de962bdSlukem { 222*2de962bdSlukem char **attrs = scr->scr_at_oids_must; 223*2de962bdSlukem char **attrs1; 224*2de962bdSlukem AttributeType *sat; 225*2de962bdSlukem 226*2de962bdSlukem if ( attrs ) { 227*2de962bdSlukem attrs1 = attrs; 228*2de962bdSlukem while ( *attrs1 ) { 229*2de962bdSlukem sat = at_find(*attrs1); 230*2de962bdSlukem if ( !sat ) { 231*2de962bdSlukem *err = *attrs1; 232*2de962bdSlukem return SLAP_SCHERR_ATTR_NOT_FOUND; 233*2de962bdSlukem } 234*2de962bdSlukem 235*2de962bdSlukem if( is_at_operational( sat )) (*op)++; 236*2de962bdSlukem 237*2de962bdSlukem if ( at_find_in_list(sat, scr->scr_required) < 0) { 238*2de962bdSlukem if ( at_append_to_list(sat, &scr->scr_required) ) { 239*2de962bdSlukem *err = *attrs1; 240*2de962bdSlukem return SLAP_SCHERR_OUTOFMEM; 241*2de962bdSlukem } 242*2de962bdSlukem } else { 243*2de962bdSlukem *err = *attrs1; 244*2de962bdSlukem return SLAP_SCHERR_CR_BAD_AT; 245*2de962bdSlukem } 246*2de962bdSlukem attrs1++; 247*2de962bdSlukem } 248*2de962bdSlukem } 249*2de962bdSlukem return 0; 250*2de962bdSlukem } 251*2de962bdSlukem 252*2de962bdSlukem static int 253*2de962bdSlukem cr_create_allowed( 254*2de962bdSlukem ContentRule *scr, 255*2de962bdSlukem int *op, 256*2de962bdSlukem const char **err ) 257*2de962bdSlukem { 258*2de962bdSlukem char **attrs = scr->scr_at_oids_may; 259*2de962bdSlukem char **attrs1; 260*2de962bdSlukem AttributeType *sat; 261*2de962bdSlukem 262*2de962bdSlukem if ( attrs ) { 263*2de962bdSlukem attrs1 = attrs; 264*2de962bdSlukem while ( *attrs1 ) { 265*2de962bdSlukem sat = at_find(*attrs1); 266*2de962bdSlukem if ( !sat ) { 267*2de962bdSlukem *err = *attrs1; 268*2de962bdSlukem return SLAP_SCHERR_ATTR_NOT_FOUND; 269*2de962bdSlukem } 270*2de962bdSlukem 271*2de962bdSlukem if( is_at_operational( sat )) (*op)++; 272*2de962bdSlukem 273*2de962bdSlukem if ( at_find_in_list(sat, scr->scr_required) < 0 && 274*2de962bdSlukem at_find_in_list(sat, scr->scr_allowed) < 0 ) 275*2de962bdSlukem { 276*2de962bdSlukem if ( at_append_to_list(sat, &scr->scr_allowed) ) { 277*2de962bdSlukem *err = *attrs1; 278*2de962bdSlukem return SLAP_SCHERR_OUTOFMEM; 279*2de962bdSlukem } 280*2de962bdSlukem } else { 281*2de962bdSlukem *err = *attrs1; 282*2de962bdSlukem return SLAP_SCHERR_CR_BAD_AT; 283*2de962bdSlukem } 284*2de962bdSlukem attrs1++; 285*2de962bdSlukem } 286*2de962bdSlukem } 287*2de962bdSlukem return 0; 288*2de962bdSlukem } 289*2de962bdSlukem 290*2de962bdSlukem static int 291*2de962bdSlukem cr_create_precluded( 292*2de962bdSlukem ContentRule *scr, 293*2de962bdSlukem int *op, 294*2de962bdSlukem const char **err ) 295*2de962bdSlukem { 296*2de962bdSlukem char **attrs = scr->scr_at_oids_not; 297*2de962bdSlukem char **attrs1; 298*2de962bdSlukem AttributeType *sat; 299*2de962bdSlukem 300*2de962bdSlukem if ( attrs ) { 301*2de962bdSlukem attrs1 = attrs; 302*2de962bdSlukem while ( *attrs1 ) { 303*2de962bdSlukem sat = at_find(*attrs1); 304*2de962bdSlukem if ( !sat ) { 305*2de962bdSlukem *err = *attrs1; 306*2de962bdSlukem return SLAP_SCHERR_ATTR_NOT_FOUND; 307*2de962bdSlukem } 308*2de962bdSlukem 309*2de962bdSlukem if( is_at_operational( sat )) (*op)++; 310*2de962bdSlukem 311*2de962bdSlukem /* FIXME: should also make sure attribute type is not 312*2de962bdSlukem a required attribute of the structural class or 313*2de962bdSlukem any auxiliary class */ 314*2de962bdSlukem if ( at_find_in_list(sat, scr->scr_required) < 0 && 315*2de962bdSlukem at_find_in_list(sat, scr->scr_allowed) < 0 && 316*2de962bdSlukem at_find_in_list(sat, scr->scr_precluded) < 0 ) 317*2de962bdSlukem { 318*2de962bdSlukem if ( at_append_to_list(sat, &scr->scr_precluded) ) { 319*2de962bdSlukem *err = *attrs1; 320*2de962bdSlukem return SLAP_SCHERR_OUTOFMEM; 321*2de962bdSlukem } 322*2de962bdSlukem } else { 323*2de962bdSlukem *err = *attrs1; 324*2de962bdSlukem return SLAP_SCHERR_CR_BAD_AT; 325*2de962bdSlukem } 326*2de962bdSlukem attrs1++; 327*2de962bdSlukem } 328*2de962bdSlukem } 329*2de962bdSlukem return 0; 330*2de962bdSlukem } 331*2de962bdSlukem 332*2de962bdSlukem int 333*2de962bdSlukem cr_add( 334*2de962bdSlukem LDAPContentRule *cr, 335*2de962bdSlukem int user, 336*2de962bdSlukem ContentRule **rscr, 337*2de962bdSlukem const char **err 338*2de962bdSlukem ) 339*2de962bdSlukem { 340*2de962bdSlukem ContentRule *scr; 341*2de962bdSlukem int code; 342*2de962bdSlukem int op = 0; 343*2de962bdSlukem char *oidm = NULL; 344*2de962bdSlukem 345*2de962bdSlukem if ( cr->cr_names != NULL ) { 346*2de962bdSlukem int i; 347*2de962bdSlukem 348*2de962bdSlukem for( i=0; cr->cr_names[i]; i++ ) { 349*2de962bdSlukem if( !slap_valid_descr( cr->cr_names[i] ) ) { 350*2de962bdSlukem return SLAP_SCHERR_BAD_DESCR; 351*2de962bdSlukem } 352*2de962bdSlukem } 353*2de962bdSlukem } 354*2de962bdSlukem 355*2de962bdSlukem if ( !OID_LEADCHAR( cr->cr_oid[0] )) { 356*2de962bdSlukem /* Expand OID macros */ 357*2de962bdSlukem char *oid = oidm_find( cr->cr_oid ); 358*2de962bdSlukem if ( !oid ) { 359*2de962bdSlukem *err = cr->cr_oid; 360*2de962bdSlukem return SLAP_SCHERR_OIDM; 361*2de962bdSlukem } 362*2de962bdSlukem if ( oid != cr->cr_oid ) { 363*2de962bdSlukem oidm = cr->cr_oid; 364*2de962bdSlukem cr->cr_oid = oid; 365*2de962bdSlukem } 366*2de962bdSlukem } 367*2de962bdSlukem 368*2de962bdSlukem scr = (ContentRule *) ch_calloc( 1, sizeof(ContentRule) ); 369*2de962bdSlukem AC_MEMCPY( &scr->scr_crule, cr, sizeof(LDAPContentRule) ); 370*2de962bdSlukem 371*2de962bdSlukem scr->scr_oidmacro = oidm; 372*2de962bdSlukem scr->scr_sclass = oc_find(cr->cr_oid); 373*2de962bdSlukem if ( !scr->scr_sclass ) { 374*2de962bdSlukem *err = cr->cr_oid; 375*2de962bdSlukem code = SLAP_SCHERR_CLASS_NOT_FOUND; 376*2de962bdSlukem goto fail; 377*2de962bdSlukem } 378*2de962bdSlukem 379*2de962bdSlukem /* check object class usage */ 380*2de962bdSlukem if( scr->scr_sclass->soc_kind != LDAP_SCHEMA_STRUCTURAL ) 381*2de962bdSlukem { 382*2de962bdSlukem *err = cr->cr_oid; 383*2de962bdSlukem code = SLAP_SCHERR_CR_BAD_STRUCT; 384*2de962bdSlukem goto fail; 385*2de962bdSlukem } 386*2de962bdSlukem 387*2de962bdSlukem if( scr->scr_sclass->soc_flags & SLAP_OC_OPERATIONAL ) op++; 388*2de962bdSlukem 389*2de962bdSlukem code = cr_add_auxiliaries( scr, &op, err ); 390*2de962bdSlukem if ( code != 0 ) goto fail; 391*2de962bdSlukem 392*2de962bdSlukem code = cr_create_required( scr, &op, err ); 393*2de962bdSlukem if ( code != 0 ) goto fail; 394*2de962bdSlukem 395*2de962bdSlukem code = cr_create_allowed( scr, &op, err ); 396*2de962bdSlukem if ( code != 0 ) goto fail; 397*2de962bdSlukem 398*2de962bdSlukem code = cr_create_precluded( scr, &op, err ); 399*2de962bdSlukem if ( code != 0 ) goto fail; 400*2de962bdSlukem 401*2de962bdSlukem if( user && op ) { 402*2de962bdSlukem code = SLAP_SCHERR_CR_BAD_AUX; 403*2de962bdSlukem goto fail; 404*2de962bdSlukem } 405*2de962bdSlukem 406*2de962bdSlukem code = cr_insert(scr,err); 407*2de962bdSlukem if ( code == 0 && rscr ) 408*2de962bdSlukem *rscr = scr; 409*2de962bdSlukem return code; 410*2de962bdSlukem fail: 411*2de962bdSlukem ch_free( scr ); 412*2de962bdSlukem return code; 413*2de962bdSlukem } 414*2de962bdSlukem 415*2de962bdSlukem void 416*2de962bdSlukem cr_unparse( BerVarray *res, ContentRule *start, ContentRule *end, int sys ) 417*2de962bdSlukem { 418*2de962bdSlukem ContentRule *cr; 419*2de962bdSlukem int i, num; 420*2de962bdSlukem struct berval bv, *bva = NULL, idx; 421*2de962bdSlukem char ibuf[32]; 422*2de962bdSlukem 423*2de962bdSlukem if ( !start ) 424*2de962bdSlukem start = LDAP_STAILQ_FIRST( &cr_list ); 425*2de962bdSlukem 426*2de962bdSlukem /* count the result size */ 427*2de962bdSlukem i = 0; 428*2de962bdSlukem for ( cr=start; cr; cr=LDAP_STAILQ_NEXT(cr, scr_next)) { 429*2de962bdSlukem if ( sys && !(cr->scr_flags & SLAP_CR_HARDCODE)) continue; 430*2de962bdSlukem i++; 431*2de962bdSlukem if ( cr == end ) break; 432*2de962bdSlukem } 433*2de962bdSlukem if (!i) return; 434*2de962bdSlukem 435*2de962bdSlukem num = i; 436*2de962bdSlukem bva = ch_malloc( (num+1) * sizeof(struct berval) ); 437*2de962bdSlukem BER_BVZERO( bva ); 438*2de962bdSlukem idx.bv_val = ibuf; 439*2de962bdSlukem if ( sys ) { 440*2de962bdSlukem idx.bv_len = 0; 441*2de962bdSlukem ibuf[0] = '\0'; 442*2de962bdSlukem } 443*2de962bdSlukem i = 0; 444*2de962bdSlukem for ( cr=start; cr; cr=LDAP_STAILQ_NEXT(cr, scr_next)) { 445*2de962bdSlukem LDAPContentRule lcr, *lcrp; 446*2de962bdSlukem if ( sys && !(cr->scr_flags & SLAP_CR_HARDCODE)) continue; 447*2de962bdSlukem if ( cr->scr_oidmacro ) { 448*2de962bdSlukem lcr = cr->scr_crule; 449*2de962bdSlukem lcr.cr_oid = cr->scr_oidmacro; 450*2de962bdSlukem lcrp = &lcr; 451*2de962bdSlukem } else { 452*2de962bdSlukem lcrp = &cr->scr_crule; 453*2de962bdSlukem } 454*2de962bdSlukem if ( ldap_contentrule2bv( lcrp, &bv ) == NULL ) { 455*2de962bdSlukem ber_bvarray_free( bva ); 456*2de962bdSlukem } 457*2de962bdSlukem if ( !sys ) { 458*2de962bdSlukem idx.bv_len = sprintf(idx.bv_val, "{%d}", i); 459*2de962bdSlukem } 460*2de962bdSlukem bva[i].bv_len = idx.bv_len + bv.bv_len; 461*2de962bdSlukem bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 ); 462*2de962bdSlukem strcpy( bva[i].bv_val, ibuf ); 463*2de962bdSlukem strcpy( bva[i].bv_val + idx.bv_len, bv.bv_val ); 464*2de962bdSlukem i++; 465*2de962bdSlukem bva[i].bv_val = NULL; 466*2de962bdSlukem ldap_memfree( bv.bv_val ); 467*2de962bdSlukem if ( cr == end ) break; 468*2de962bdSlukem } 469*2de962bdSlukem *res = bva; 470*2de962bdSlukem } 471*2de962bdSlukem 472*2de962bdSlukem int 473*2de962bdSlukem cr_schema_info( Entry *e ) 474*2de962bdSlukem { 475*2de962bdSlukem AttributeDescription *ad_ditContentRules 476*2de962bdSlukem = slap_schema.si_ad_ditContentRules; 477*2de962bdSlukem ContentRule *cr; 478*2de962bdSlukem 479*2de962bdSlukem struct berval val; 480*2de962bdSlukem struct berval nval; 481*2de962bdSlukem 482*2de962bdSlukem LDAP_STAILQ_FOREACH(cr, &cr_list, scr_next) { 483*2de962bdSlukem if ( ldap_contentrule2bv( &cr->scr_crule, &val ) == NULL ) { 484*2de962bdSlukem return -1; 485*2de962bdSlukem } 486*2de962bdSlukem 487*2de962bdSlukem #if 0 488*2de962bdSlukem if( cr->scr_flags & SLAP_CR_HIDE ) continue; 489*2de962bdSlukem #endif 490*2de962bdSlukem #if 0 491*2de962bdSlukem Debug( LDAP_DEBUG_TRACE, "Merging cr [%ld] %s\n", 492*2de962bdSlukem (long) val.bv_len, val.bv_val, 0 ); 493*2de962bdSlukem #endif 494*2de962bdSlukem 495*2de962bdSlukem nval.bv_val = cr->scr_oid; 496*2de962bdSlukem nval.bv_len = strlen(cr->scr_oid); 497*2de962bdSlukem 498*2de962bdSlukem if( attr_merge_one( e, ad_ditContentRules, &val, &nval ) ) 499*2de962bdSlukem { 500*2de962bdSlukem return -1; 501*2de962bdSlukem } 502*2de962bdSlukem ldap_memfree( val.bv_val ); 503*2de962bdSlukem } 504*2de962bdSlukem return 0; 505*2de962bdSlukem } 506