static int translucent_db_destroy( BackendDB *be, ConfigReply *cr ) { slap_overinst *on = (slap_overinst *) be->bd_info; translucent_info *ov = on->on_bi.bi_private; int rc = 0; Debug(LDAP_DEBUG_TRACE, "==> translucent_db_destroy\n", 0, 0, 0); if ( ov ) { if ( ov->remote ) anlist_free( ov->remote, 1, NULL ); if ( ov->local ) anlist_free( ov->local, 1, NULL ); if ( ov->db.be_private != NULL ) { backend_stopdown_one( &ov->db ); } ldap_pvt_thread_mutex_destroy( &ov->db.be_pcl_mutex ); ch_free(ov); on->on_bi.bi_private = NULL; } return(rc); }
static int translucent_cf_gen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; translucent_info *ov = on->on_bi.bi_private; AttributeName **an, *a2; int i; if ( c->type == TRANS_LOCAL ) an = &ov->local; else an = &ov->remote; if ( c->op == SLAP_CONFIG_EMIT ) { if ( !*an ) return 1; for ( i = 0; !BER_BVISNULL(&(*an)[i].an_name); i++ ) { value_add_one( &c->rvalue_vals, &(*an)[i].an_name ); } return ( i < 1 ); } else if ( c->op == LDAP_MOD_DELETE ) { if ( c->valx < 0 ) { anlist_free( *an, 1, NULL ); *an = NULL; } else { i = c->valx; ch_free( (*an)[i].an_name.bv_val ); do { (*an)[i] = (*an)[i+1]; i++; } while ( !BER_BVISNULL( &(*an)[i].an_name )); } return 0; } a2 = str2anlist( *an, c->argv[1], "," ); if ( !a2 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s unable to parse attribute %s", c->argv[0], c->argv[1] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); return ARG_BAD_CONF; } *an = a2; return 0; }
/* * Convert a delimited string into a list of AttributeNames; add * on to an existing list if it was given. If the string is not * a valid attribute name, if a '-' is prepended it is skipped * and the remaining name is tried again; if a '@' (or '+') is * prepended, an objectclass name is searched instead; if a '!' * is prepended, the objectclass name is negated. * * NOTE: currently, if a valid attribute name is not found, the * same string is also checked as valid objectclass name; however, * this behavior is deprecated. */ AttributeName * str2anlist( AttributeName *an, char *in, const char *brkstr ) { char *str; char *s; char *lasts; int i, j; const char *text; AttributeName *anew; /* find last element in list */ i = 0; if ( an != NULL ) { for ( i = 0; !BER_BVISNULL( &an[ i ].an_name ) ; i++) ; } /* protect the input string from strtok */ str = ch_strdup( in ); /* Count words in string */ j = 1; for ( s = str; *s; s++ ) { if ( strchr( brkstr, *s ) != NULL ) { j++; } } an = ch_realloc( an, ( i + j + 1 ) * sizeof( AttributeName ) ); anew = an + i; for ( s = ldap_pvt_strtok( str, brkstr, &lasts ); s != NULL; s = ldap_pvt_strtok( NULL, brkstr, &lasts ) ) { /* put a stop mark */ BER_BVZERO( &anew[1].an_name ); anew->an_desc = NULL; anew->an_oc = NULL; anew->an_flags = 0; ber_str2bv(s, 0, 1, &anew->an_name); slap_bv2ad(&anew->an_name, &anew->an_desc, &text); if ( !anew->an_desc ) { switch( anew->an_name.bv_val[0] ) { case '-': { struct berval adname; adname.bv_len = anew->an_name.bv_len - 1; adname.bv_val = &anew->an_name.bv_val[1]; slap_bv2ad(&adname, &anew->an_desc, &text); if ( !anew->an_desc ) { goto reterr; } } break; case '@': case '+': /* (deprecated) */ case '!': { struct berval ocname; ocname.bv_len = anew->an_name.bv_len - 1; ocname.bv_val = &anew->an_name.bv_val[1]; anew->an_oc = oc_bvfind( &ocname ); if ( !anew->an_oc ) { goto reterr; } if ( anew->an_name.bv_val[0] == '!' ) { anew->an_flags |= SLAP_AN_OCEXCLUDE; } } break; default: /* old (deprecated) way */ anew->an_oc = oc_bvfind( &anew->an_name ); if ( !anew->an_oc ) { goto reterr; } } } anew->an_flags |= SLAP_AN_OCINITED; anew++; } BER_BVZERO( &anew->an_name ); free( str ); return( an ); reterr: anlist_free( an, 1, NULL ); /* * overwrites input string * on error! */ strcpy( in, s ); free( str ); return NULL; }