1 /* bconfig.c - the config backend */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2005 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was originally developed by Howard Chu for inclusion
18 * in OpenLDAP Software.
24 #include <ac/string.h>
29 #define CONFIG_DN "cn=config"
31 typedef struct CfEntryInfo {
32 struct CfEntryInfo *ce_sibs;
33 struct CfEntryInfo *ce_kids;
35 ConfigTable *ce_table;
39 ConfigFile *cb_config;
44 config_back_bind( Operation *op, SlapReply *rs )
46 if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
47 ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
48 /* frontend sends result */
52 rs->sr_err = LDAP_INVALID_CREDENTIALS;
53 send_ldap_result( op, rs );
59 config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last )
64 if ( dn_match( &root->ce_entry->e_nname, dn ))
67 c = dn->bv_val+dn->bv_len;
72 for (--c;c>dn->bv_val && *c != ',';c--);
76 cdn.bv_len = dn->bv_len - (c-dn->bv_val);
80 for (;root;root=root->ce_sibs) {
81 if ( dn_match( &root->ce_entry->e_nname, &cdn )) {
82 if ( cdn.bv_val == dn->bv_val ) {
93 config_send( Operation *op, SlapReply *rs, CfEntryInfo *ce, int depth )
97 if ( test_filter( op, ce->ce_entry, op->ors_filter ) == LDAP_COMPARE_TRUE )
99 rs->sr_attrs = op->ors_attrs;
100 rs->sr_entry = ce->ce_entry;
101 rc = send_search_entry( op, rs );
103 if ( op->ors_scope == LDAP_SCOPE_SUBTREE ) {
105 rc = config_send( op, rs, ce->ce_kids, 1 );
109 for (ce=ce->ce_sibs; ce; ce=ce->ce_sibs) {
110 rc = config_send( op, rs, ce, 0 );
119 config_back_search( Operation *op, SlapReply *rs )
122 CfEntryInfo *ce, *last;
125 if ( !be_isroot( op ) ) {
126 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
127 send_ldap_result( op, rs );
130 cfb = (CfBackInfo *)op->o_bd->be_private;
132 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
135 rs->sr_matched = last->ce_entry->e_name.bv_val;
136 rs->sr_err = LDAP_NO_SUCH_OBJECT;
139 switch ( op->ors_scope ) {
140 case LDAP_SCOPE_BASE:
141 case LDAP_SCOPE_SUBTREE:
142 config_send( op, rs, ce, 0 );
145 case LDAP_SCOPE_ONELEVEL:
146 for (ce = ce->ce_kids; ce; ce=ce->ce_sibs) {
147 config_send( op, rs, ce, 1 );
152 rs->sr_err = LDAP_SUCCESS;
154 send_ldap_result( op, rs );
159 config_alloc_entry( struct berval *pdn, struct berval *rdn )
161 Entry *e = ch_calloc( 1, sizeof(Entry) );
162 CfEntryInfo *ce = ch_calloc( 1, sizeof(CfEntryInfo) );
165 build_new_dn( &e->e_name, pdn, rdn, NULL );
166 ber_dupbv( &e->e_nname, &e->e_name );
171 config_build_entry( Entry *e, void *private, char *oc, struct berval *rdn )
173 struct berval vals[2];
174 struct berval ad_name;
175 AttributeDescription *ad = NULL;
180 BER_BVZERO( &vals[1] );
182 ber_str2bv( oc, 0, 0, &vals[0] );
183 attr_merge(e, slap_schema.si_ad_objectClass, vals, NULL );
184 ptr = strchr(rdn->bv_val, '=');
185 ad_name.bv_val = rdn->bv_val;
186 ad_name.bv_len = ptr - rdn->bv_val;
187 rc = slap_bv2ad( &ad_name, &ad, &text );
191 vals[0].bv_val = ptr+1;
192 vals[0].bv_len = rdn->bv_len - (vals[0].bv_val - rdn->bv_val);
193 attr_merge(e, ad, vals, NULL );
198 config_back_db_open( BackendDB *be )
200 CfBackInfo *cfb = be->be_private;
203 CfEntryInfo *ce, *ceparent, *ceprev;
204 int i, rc, buflen = 0;
211 /* create root of tree */
212 ber_str2bv( CONFIG_DN, STRLENOF( CONFIG_DN ), 0, &rdn );
213 e = config_alloc_entry( NULL, &rdn );
215 ce->ce_table = be->bd_info->bi_cf_table;
218 config_build_entry( e, be->be_private, "olcGlobal", &rdn );
222 for (ct=ce->ce_table; ct->name; ct++) {
223 if (!ct->ad) continue;
224 if (ct->arg_type & ARG_DB) continue;
225 rc = config_get_vals(ct, &c);
226 if (rc == LDAP_SUCCESS) {
227 attr_merge(e, ct->ad, c.rvalue_vals, c.rvalue_nvals);
234 /* Create backend nodes. Skip if they don't provide a cf_table.
235 * There usually aren't any of these.
238 for (i=0; i<nBackendInfo; i++, bi++) {
239 if (!bi->bi_cf_table) continue;
240 if (!bi->bi_private) continue;
242 if ( buflen < STRLENOF("olcbackend=")+strlen(bi->bi_type)+1) {
243 buflen = STRLENOF("olcbackend=") + strlen(bi->bi_type)+1;
244 buf = realloc(buf, buflen);
247 rdn.bv_len = sprintf(buf, "olcBackend=%s", bi->bi_type);
248 e = config_alloc_entry( &parent->e_nname, &rdn );
250 ce->ce_table = bi->bi_cf_table;
251 config_build_entry( e, bi->bi_private, "olcBackendConfig",
253 if ( !ceparent->ce_kids ) {
254 ceparent->ce_kids = ce;
256 ceprev->ce_sibs = ce;
261 /* Create database nodes... */
262 for (i=0; i<nBackendDB; i++) {
266 bptr = &backendDB[i];
269 if ( buflen < STRLENOF("olcdatabase={xxxxxxxx}")+strlen(bi->bi_type)+1) {
270 buflen = STRLENOF("olcdatabase={xxxxxxxx}")+strlen(bi->bi_type)+1;
271 buf = realloc(buf, buflen);
274 rdn.bv_len = sprintf(buf, "olcDatabase={%0x}%s", i, bi->bi_type);
275 e = config_alloc_entry( &parent->e_nname, &rdn );
277 ce->ce_table = bptr->be_cf_table;
278 config_build_entry( e, bptr->be_private, "olcDatabaseConfig",
282 ct = be->bd_info->bi_cf_table;
283 for (; ct->name; ct++) {
284 if (!ct->ad) continue;
285 if (!(ct->arg_type & (ARG_DB|ARG_MAY_DB))) continue;
286 rc = config_get_vals(ct, &c);
287 if (rc == LDAP_SUCCESS) {
288 attr_merge(e, ct->ad, c.rvalue_vals, c.rvalue_nvals);
292 if ( !ceparent->ce_kids ) {
293 ceparent->ce_kids = ce;
295 ceprev->ce_sibs = ce;
298 /* Iterate through overlays */
301 /* Create includeFile nodes... */
307 config_back_db_destroy( Backend *be )
309 free( be->be_private );
314 config_back_initialize( BackendInfo *bi )
322 bi->bi_db_config = 0;
323 bi->bi_db_open = config_back_db_open;
325 bi->bi_db_destroy = config_back_db_destroy;
327 bi->bi_op_bind = config_back_bind;
328 bi->bi_op_unbind = 0;
329 bi->bi_op_search = config_back_search;
330 bi->bi_op_compare = 0;
331 bi->bi_op_modify = 0;
332 bi->bi_op_modrdn = 0;
334 bi->bi_op_delete = 0;
335 bi->bi_op_abandon = 0;
339 bi->bi_chk_referrals = 0;
341 bi->bi_connection_init = 0;
342 bi->bi_connection_destroy = 0;
347 void config_back_init( ConfigFile *cfp, ConfigTable *ct )
349 BackendInfo bi = {0};
354 bi.bi_type = "config";
355 bi.bi_init = config_back_initialize;
359 if ( slapMode & SLAP_TOOL_MODE ) {
362 be = backend_db_init( bi.bi_type );
363 ber_str2bv( CONFIG_DN, 0, 1, &be->be_rootdn );
364 ber_dupbv( &be->be_rootndn, &be->be_rootdn );
365 ber_dupbv( &dn, &be->be_rootdn );
366 ber_bvarray_add( &be->be_suffix, &dn );
367 ber_dupbv( &dn, &be->be_rootdn );
368 ber_bvarray_add( &be->be_nsuffix, &dn );
369 cfb = ch_calloc( 1, sizeof(CfBackInfo));
370 cfb->cb_config = cfp;
371 be->be_private = cfb;