~ubuntu-branches/ubuntu/trusty/389-ds-base/trusty

1 by Timo Aaltonen
Import upstream version 1.2.10.2
1
/** BEGIN COPYRIGHT BLOCK
2
 * This Program is free software; you can redistribute it and/or modify it under
3
 * the terms of the GNU General Public License as published by the Free Software
4
 * Foundation; version 2 of the License.
5
 * 
6
 * This Program is distributed in the hope that it will be useful, but WITHOUT
7
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9
 * 
10
 * You should have received a copy of the GNU General Public License along with
11
 * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
12
 * Place, Suite 330, Boston, MA 02111-1307 USA.
13
 * 
14
 * In addition, as a special exception, Red Hat, Inc. gives You the additional
15
 * right to link the code of this Program with code not covered under the GNU
16
 * General Public License ("Non-GPL Code") and to distribute linked combinations
17
 * including the two, subject to the limitations in this paragraph. Non-GPL Code
18
 * permitted under this exception must only link to the code of this Program
19
 * through those well defined interfaces identified in the file named EXCEPTION
20
 * found in the source code files (the "Approved Interfaces"). The files of
21
 * Non-GPL Code may instantiate templates or use macros or inline functions from
22
 * the Approved Interfaces without causing the resulting work to be covered by
23
 * the GNU General Public License. Only Red Hat, Inc. may make changes or
24
 * additions to the list of Approved Interfaces. You must obey the GNU General
25
 * Public License in all respects for all of the Program code and other code used
26
 * in conjunction with the Program except the Non-GPL Code covered by this
27
 * exception. If you modify this file, you may extend this exception to your
28
 * version of the file, but you are not obligated to do so. If you do not wish to
29
 * provide this exception without modification, you must delete this exception
30
 * statement from your version and license this file solely under the GPL without
31
 * exception. 
32
 * 
33
 * 
34
 * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
35
 * Copyright (C) 2005 Red Hat, Inc.
36
 * All rights reserved.
37
 * END COPYRIGHT BLOCK **/
38
39
#ifdef HAVE_CONFIG_H
40
#  include <config.h>
41
#endif
42
43
#include "cb.h"
44
#include "plstr.h"
45
46
/*
47
** 1 set/get function for each parameter of a backend instance
48
** NOTE: Some parameters won't be taken into account until the server has restarted
49
** In such cases, the internal conf is not updated but the new value is stored in the 
50
** dse.ldif file.
51
**/
52
53
/* Get functions */
54
55
static void *cb_instance_hosturl_get(void *arg);
56
static void *cb_instance_starttls_get(void *arg);
57
static void *cb_instance_binduser_get(void *arg);
58
static void *cb_instance_bindmech_get(void *arg);
59
static void *cb_instance_userpassword_get(void *arg);
60
static void *cb_instance_maxbconn_get(void *arg);
61
static void *cb_instance_maxconn_get(void *arg);
62
static void *cb_instance_abandonto_get(void *arg);
63
static void *cb_instance_maxbconc_get(void *arg);
64
static void *cb_instance_maxconc_get(void *arg);
65
static void *cb_instance_imperson_get(void *arg);
66
static void *cb_instance_connlife_get(void *arg);
67
static void *cb_instance_bindto_get(void *arg);
68
static void *cb_instance_opto_get(void *arg);
69
static void *cb_instance_ref_get(void *arg);
70
static void *cb_instance_acl_get(void *arg);
71
static void *cb_instance_bindretry_get(void *arg);
72
static void *cb_instance_sizelimit_get(void *arg);
73
static void *cb_instance_timelimit_get(void *arg);
74
static void *cb_instance_hoplimit_get(void *arg);
75
static void *cb_instance_max_idle_get(void *arg);
76
static void *cb_instance_max_test_get(void *arg);
77
78
79
/* Set functions */
80
81
static int cb_instance_hosturl_set(void *arg, void *value, char *errorbuf, int phase, int apply);
82
static int cb_instance_starttls_set(void *arg, void *value, char *errorbuf, int phase, int apply);
83
static int cb_instance_binduser_set(void *arg, void *value, char *errorbuf, int phase, int apply);
84
static int cb_instance_bindmech_set(void *arg, void *value, char *errorbuf, int phase, int apply);
85
static int cb_instance_userpassword_set(void *arg, void *value, char *errorbuf, int phase, int apply);
86
static int cb_instance_maxbconn_set(void *arg, void *value, char *errorbuf, int phase, int apply);
87
static int cb_instance_maxconn_set(void *arg, void *value, char *errorbuf, int phase, int apply);
88
static int cb_instance_abandonto_set(void *arg, void *value, char *errorbuf, int phase, int apply);
89
static int cb_instance_maxbconc_set(void *arg, void *value, char *errorbuf, int phase, int apply);
90
static int cb_instance_maxconc_set(void *arg, void *value, char *errorbuf, int phase, int apply);
91
static int cb_instance_imperson_set(void *arg, void *value, char *errorbuf, int phase, int apply);
92
static int cb_instance_connlife_set(void *arg, void *value, char *errorbuf, int phase, int apply);
93
static int cb_instance_bindto_set(void *arg, void *value, char *errorbuf, int phase, int apply);
94
static int cb_instance_opto_set(void *arg, void *value, char *errorbuf, int phase, int apply);
95
static int cb_instance_ref_set(void *arg, void *value, char *errorbuf, int phase, int apply);
96
static int cb_instance_acl_set(void *arg, void *value, char *errorbuf, int phase, int apply);
97
static int cb_instance_bindretry_set(void *arg, void *value, char *errorbuf, int phase, int apply);
98
static int cb_instance_sizelimit_set(void *arg, void *value, char *errorbuf, int phase, int apply);
99
static int cb_instance_timelimit_set(void *arg, void *value, char *errorbuf, int phase, int apply);
100
static int cb_instance_hoplimit_set(void *arg, void *value, char *errorbuf, int phase, int apply);
101
static int cb_instance_max_idle_set(void *arg, void *value, char *errorbuf, int phase, int apply);
102
static int cb_instance_max_test_set(void *arg, void *value, char *errorbuf, int phase, int apply);
103
104
/* Default hardwired values */
105
106
cb_instance_config_info cb_the_instance_config[] = {
107
{CB_CONFIG_HOSTURL,CB_CONFIG_TYPE_STRING,"",&cb_instance_hosturl_get,&cb_instance_hosturl_set,CB_ALWAYS_SHOW},
108
{CB_CONFIG_BINDUSER, CB_CONFIG_TYPE_STRING, "", &cb_instance_binduser_get, &cb_instance_binduser_set,CB_ALWAYS_SHOW},
109
{CB_CONFIG_USERPASSWORD,CB_CONFIG_TYPE_STRING,"",&cb_instance_userpassword_get,&cb_instance_userpassword_set,CB_ALWAYS_SHOW},
110
{CB_CONFIG_MAXBINDCONNECTIONS,CB_CONFIG_TYPE_INT,CB_DEF_BIND_MAXCONNECTIONS,&cb_instance_maxbconn_get, &cb_instance_maxbconn_set,CB_ALWAYS_SHOW},
111
{CB_CONFIG_MAXCONNECTIONS,CB_CONFIG_TYPE_INT,CB_DEF_MAXCONNECTIONS,&cb_instance_maxconn_get, &cb_instance_maxconn_set,CB_ALWAYS_SHOW},
112
{CB_CONFIG_ABANDONTIMEOUT,CB_CONFIG_TYPE_INT,CB_DEF_ABANDON_TIMEOUT,&cb_instance_abandonto_get, &cb_instance_abandonto_set,CB_ALWAYS_SHOW},
113
{CB_CONFIG_MAXBINDCONCURRENCY,CB_CONFIG_TYPE_INT,CB_DEF_BIND_MAXCONCURRENCY,&cb_instance_maxbconc_get, &cb_instance_maxbconc_set,CB_ALWAYS_SHOW},
114
{CB_CONFIG_MAXCONCURRENCY,CB_CONFIG_TYPE_INT,CB_DEF_MAXCONCURRENCY,&cb_instance_maxconc_get, &cb_instance_maxconc_set,CB_ALWAYS_SHOW},
115
{CB_CONFIG_IMPERSONATION,CB_CONFIG_TYPE_ONOFF,CB_DEF_IMPERSONATION,&cb_instance_imperson_get, &cb_instance_imperson_set,CB_ALWAYS_SHOW},
116
{CB_CONFIG_CONNLIFETIME,CB_CONFIG_TYPE_INT,CB_DEF_CONNLIFETIME,&cb_instance_connlife_get, &cb_instance_connlife_set,CB_ALWAYS_SHOW},
117
{CB_CONFIG_BINDTIMEOUT,CB_CONFIG_TYPE_INT,CB_DEF_BINDTIMEOUT,&cb_instance_bindto_get, &cb_instance_bindto_set,CB_ALWAYS_SHOW},
118
{CB_CONFIG_TIMEOUT,CB_CONFIG_TYPE_INT,"0",&cb_instance_opto_get, &cb_instance_opto_set,0},
119
{CB_CONFIG_REFERRAL,CB_CONFIG_TYPE_ONOFF,CB_DEF_SEARCHREFERRAL,&cb_instance_ref_get, &cb_instance_ref_set,CB_ALWAYS_SHOW},
120
{CB_CONFIG_LOCALACL,CB_CONFIG_TYPE_ONOFF,CB_DEF_LOCALACL,&cb_instance_acl_get, &cb_instance_acl_set,CB_ALWAYS_SHOW},
121
{CB_CONFIG_BINDRETRY,CB_CONFIG_TYPE_INT,CB_DEF_BINDRETRY,&cb_instance_bindretry_get, &cb_instance_bindretry_set,CB_ALWAYS_SHOW},
122
{CB_CONFIG_SIZELIMIT,CB_CONFIG_TYPE_INT,CB_DEF_SIZELIMIT,&cb_instance_sizelimit_get, &cb_instance_sizelimit_set,CB_ALWAYS_SHOW},
123
{CB_CONFIG_TIMELIMIT,CB_CONFIG_TYPE_INT,CB_DEF_TIMELIMIT,&cb_instance_timelimit_get, &cb_instance_timelimit_set,CB_ALWAYS_SHOW},
124
{CB_CONFIG_HOPLIMIT,CB_CONFIG_TYPE_INT,CB_DEF_HOPLIMIT,&cb_instance_hoplimit_get, &cb_instance_hoplimit_set,CB_ALWAYS_SHOW},
125
{CB_CONFIG_MAX_IDLE_TIME,CB_CONFIG_TYPE_INT,CB_DEF_MAX_IDLE_TIME,&cb_instance_max_idle_get, &cb_instance_max_idle_set,CB_ALWAYS_SHOW},
126
{CB_CONFIG_MAX_TEST_TIME,CB_CONFIG_TYPE_INT,CB_DEF_MAX_TEST_TIME,&cb_instance_max_test_get, &cb_instance_max_test_set,CB_ALWAYS_SHOW},
127
{CB_CONFIG_STARTTLS,CB_CONFIG_TYPE_ONOFF,CB_DEF_STARTTLS,&cb_instance_starttls_get, &cb_instance_starttls_set,CB_ALWAYS_SHOW},
128
{CB_CONFIG_BINDMECH,CB_CONFIG_TYPE_STRING,CB_DEF_BINDMECH,&cb_instance_bindmech_get, &cb_instance_bindmech_set,CB_ALWAYS_SHOW},
129
{NULL, 0, NULL, NULL, NULL, 0}
130
};
131
132
/* Others forward declarations */
133
134
int cb_instance_delete_config_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* e2,
135
       int *returncode, char *returntext, void *arg);
136
int cb_instance_search_config_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
137
        int *returncode, char *returntext, void *arg);
138
int cb_instance_add_config_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* e2,
139
       int *returncode, char *returntext, void *arg);
140
static int
141
cb_instance_config_set(void *arg, char *attr_name, cb_instance_config_info *config_array,
142
struct berval *bval, char *err_buf, int phase, int apply_mod);
143
144
145
int
146
cb_dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
147
        int *returncode, char *returntext, void *arg)
148
{
149
    *returncode=LDAP_UNWILLING_TO_PERFORM;
150
    return SLAPI_DSE_CALLBACK_ERROR;
151
}
152
153
static char *cb_skeleton_entries[] =
154
{
155
156
    "dn: cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config\n"
157
    "objectclass: top\n"
158
    "objectclass: extensibleObject\n"
159
    "cn: monitor\n",
160
161
        ""
162
};
163
164
/*
165
** Initialize a backend instance with a default configuration
166
*/
167
168
static void cb_instance_config_set_default(cb_backend_instance *inst)
169
{
170
        cb_instance_config_info *config;
171
        char err_buf[SLAPI_DSE_RETURNTEXT_SIZE];
172
173
        for (config = cb_the_instance_config; config->config_name != NULL; config++) {
174
                cb_instance_config_set((void *)inst, 
175
		config->config_name, cb_the_instance_config, NULL /* use default */, err_buf, 
176
		CB_CONFIG_PHASE_INITIALIZATION, 1 /* apply */);
177
        }
178
179
	/* Set backend instance flags */
180
	if (inst->inst_be) 
181
		slapi_be_set_flag(inst->inst_be,SLAPI_BE_FLAG_REMOTE_DATA);
182
}
183
184
/*
185
** Allocate a new chaining backend instance. Internal structure
186
*/
187
188
static cb_backend_instance * cb_instance_alloc(cb_backend * cb, char * name, char * basedn) {
189
190
	int i;
191
192
	cb_backend_instance * inst =
193
		(cb_backend_instance *)slapi_ch_calloc(1, sizeof(cb_backend_instance));
194
195
	/* associated_be_is_disabled defaults to 0 - this may be a problem if the associated
196
	   be is disabled at instance creation time
197
	 */
198
        inst->inst_name = slapi_ch_strdup(name);
199
        inst->monitor.mutex = slapi_new_mutex();
200
	inst->monitor_availability.cpt_lock = slapi_new_mutex();
201
	inst->monitor_availability.lock_timeLimit = slapi_new_mutex();
202
        inst->pool= (cb_conn_pool *) slapi_ch_calloc(1,sizeof(cb_conn_pool));
203
        inst->pool->conn.conn_list_mutex = slapi_new_mutex();
204
        inst->pool->conn.conn_list_cv = slapi_new_condvar(inst->pool->conn.conn_list_mutex);
205
        inst->pool->bindit=1;
206
207
        inst->bind_pool= (cb_conn_pool *) slapi_ch_calloc(1,sizeof(cb_conn_pool));
208
        inst->bind_pool->conn.conn_list_mutex = slapi_new_mutex();
209
        inst->bind_pool->conn.conn_list_cv = slapi_new_condvar(inst->bind_pool->conn.conn_list_mutex);
210
	
211
	inst->backend_type=cb;
212
	/* initialize monitor_availability */
213
	inst->monitor_availability.farmserver_state = FARMSERVER_AVAILABLE ; /* we expect the farm to be available */
214
	inst->monitor_availability.cpt              = 0 ;					 /* set up the failed conn counter to 0 */
215
216
	/* create RW lock to protect the config */
217
	inst->rwl_config_lock = slapi_new_rwlock();
218
219
	/* quick hack 				    */
220
	/* put a ref to the config lock in the pool */
221
	/* so that the connection mgmt module can   */
222
	/* access the config safely		    */
223
224
	inst->pool->rwl_config_lock = inst->rwl_config_lock;
225
	inst->bind_pool->rwl_config_lock = inst->rwl_config_lock;
226
227
	for (i=0; i < MAX_CONN_ARRAY; i++) {
228
		inst->pool->connarray[i] = NULL;
229
		inst->bind_pool->connarray[i] = NULL;
230
	}
231
232
	/* Config is now merged with the backend entry */
233
	inst->configDn=slapi_ch_strdup(basedn);
234
235
	inst->monitorDn=slapi_ch_smprintf("cn=monitor,%s",basedn); 
236
237
	inst->eq_ctx = NULL;
238
239
	return inst;
240
}
241
242
void cb_instance_free(cb_backend_instance * inst) {
243
244
	if (inst) {
245
		slapi_rwlock_wrlock(inst->rwl_config_lock);
246
247
		if ( inst->eq_ctx != NULL )
248
		{
249
			slapi_eq_cancel(inst->eq_ctx);
250
			inst->eq_ctx = NULL;
251
		}
252
253
		if (inst->bind_pool)
254
		{
255
        		cb_close_conn_pool(inst->bind_pool);
256
			slapi_destroy_condvar(inst->bind_pool->conn.conn_list_cv);
257
			slapi_destroy_mutex(inst->bind_pool->conn.conn_list_mutex);
258
			slapi_ch_free((void **) &inst->bind_pool);
259
		}
260
261
		if (inst->pool)
262
		{
263
        		cb_close_conn_pool(inst->pool);
264
			slapi_destroy_condvar(inst->pool->conn.conn_list_cv);
265
			slapi_ch_free_string(&inst->pool->password);
266
			slapi_ch_free_string(&inst->pool->binddn);
267
			slapi_ch_free_string(&inst->pool->binddn2);
268
			slapi_ch_free_string(&inst->pool->url);
269
			slapi_destroy_mutex(inst->pool->conn.conn_list_mutex);
270
			slapi_ch_free((void **) &inst->pool);
271
		}
272
273
		slapi_destroy_mutex(inst->monitor.mutex);
274
		slapi_destroy_mutex(inst->monitor_availability.cpt_lock);
275
		slapi_destroy_mutex(inst->monitor_availability.lock_timeLimit);
276
		slapi_ch_free_string(&inst->configDn);
277
		slapi_ch_free_string(&inst->monitorDn);
278
		slapi_ch_free_string(&inst->inst_name);
279
		charray_free(inst->every_attribute);
280
281
		slapi_rwlock_unlock(inst->rwl_config_lock);
282
		slapi_destroy_rwlock(inst->rwl_config_lock);
283
284
		slapi_ch_free((void **) &inst);
285
	}
286
/* XXXSD */
287
}
288
289
/*
290
** Check the change the configuration of an existing chaining
291
** backend instance.
292
*/
293
294
int cb_instance_modify_config_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
295
        int *returncode, char *returntext, void *arg) {
296
297
	cb_backend_instance * inst = (cb_backend_instance *) arg;
298
        LDAPMod **mods;
299
        int rc = LDAP_SUCCESS;
300
	int i;
301
	char * attr_name;
302
        returntext[0] = '\0';
303
304
	CB_ASSERT(inst!=NULL);
305
        slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
306
307
	/* First pass to validate input */
308
        for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
309
                attr_name = mods[i]->mod_type;
310
311
		/* specific processing for multi-valued attributes */
312
		if ( !strcasecmp ( attr_name, CB_CONFIG_SUFFIX )) {
313
                        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "suffix modification not allowed\n");
314
                        rc = LDAP_UNWILLING_TO_PERFORM;
315
			continue;
316
		} else
317
                if ( !strcasecmp ( attr_name, CB_CONFIG_ILLEGAL_ATTRS )) {
318
			continue;
319
		} else
320
		if ( !strcasecmp ( attr_name, CB_CONFIG_CHAINING_COMPONENTS )) {
321
			continue;
322
		} else
323
324
		/* CB_CONFIG_BINDUSER & CB_CONFIG_USERPASSWORD may be added */
325
		/* or deleted						    */
326
327
		if ( !strcasecmp ( attr_name, CB_CONFIG_USERPASSWORD ))  {
328
			continue;
329
		} else
330
		if ( !strcasecmp ( attr_name, CB_CONFIG_BINDUSER ))  {
331
332
			/* Make sure value is not forbidden */
333
                	if (SLAPI_IS_MOD_REPLACE(mods[i]->mod_op) ||
334
                        	SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {
335
336
                        	rc = cb_instance_config_set((void *) inst, attr_name,
337
                  	      	cb_the_instance_config, mods[i]->mod_bvalues[0], returntext,
338
                              	CB_CONFIG_PHASE_RUNNING, 0);
339
				continue;
340
			}
341
		} 
342
		
343
                if (SLAPI_IS_MOD_DELETE(mods[i]->mod_op) ||
344
                        SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {
345
                        rc= LDAP_UNWILLING_TO_PERFORM;
346
                        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "%s attributes is not allowed",
347
                                (mods[i]->mod_op & LDAP_MOD_DELETE) ? "Deleting" : "Adding");
348
                } else if (mods[i]->mod_op & LDAP_MOD_REPLACE) {
349
                        /* This assumes there is only one bval for this mod. */
350
                        rc = cb_instance_config_set((void *) inst, attr_name,
351
                  	      cb_the_instance_config, mods[i]->mod_bvalues[0], returntext,
352
                              CB_CONFIG_PHASE_RUNNING, 0);
353
                }
354
	}
355
        *returncode= rc;
356
		return ((LDAP_SUCCESS == rc) ? 1:-1);
357
}
358
359
360
/*
361
** Change the configuration of an existing chaining
362
** backend instance.
363
*/
364
365
int cb_instance_modify_config_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
366
        int *returncode, char *returntext, void *arg) {
367
368
	cb_backend_instance * inst = (cb_backend_instance *) arg;
369
        LDAPMod **mods;
370
        int rc = LDAP_SUCCESS;
371
	int i;
372
	int reopen_conn=0;
373
	char * attr_name;
374
        returntext[0] = '\0';
375
376
	CB_ASSERT(inst!=NULL);
377
        slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
378
379
	/* input checked in the preop modify callback */
380
381
        for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
382
                attr_name = mods[i]->mod_type;
383
384
		/* specific processing for multi-valued attributes */
385
		if ( !strcasecmp ( attr_name, CB_CONFIG_ILLEGAL_ATTRS )) {
386
               		char * config_attr_value;
387
                       	int done=0;
388
			int j;
389
390
       			slapi_rwlock_wrlock(inst->rwl_config_lock);
391
                        for (j = 0; mods[i]->mod_bvalues && mods[i]->mod_bvalues[j]; j++) {
392
                               	config_attr_value = (char *) mods[i]->mod_bvalues[j]->bv_val;
393
                               	if (SLAPI_IS_MOD_REPLACE(mods[i]->mod_op)) {
394
                                       	if (!done) {
395
                                               	charray_free(inst->illegal_attributes);
396
                                               	inst->illegal_attributes=NULL;
397
                                               	done=1;
398
                                       	}
399
                                       	charray_add(&inst->illegal_attributes,
400
						slapi_ch_strdup(config_attr_value));
401
                               	} else
402
                               	if (SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {
403
                                       	charray_add(&inst->illegal_attributes,
404
                                               	slapi_ch_strdup(config_attr_value));
405
                               	} else
406
                               	if (SLAPI_IS_MOD_DELETE(mods[i]->mod_op)) {
407
                                       	charray_remove(inst->illegal_attributes,
408
                                               	slapi_ch_strdup(config_attr_value),
409
												0 /* freeit */);
410
                               	}
411
                        }
412
                        if (NULL == mods[i]->mod_bvalues) {
413
                               	charray_free(inst->illegal_attributes);
414
                               	inst->illegal_attributes=NULL;
415
                        }
416
        		slapi_rwlock_unlock(inst->rwl_config_lock);
417
                        continue;
418
		} 
419
		if ( !strcasecmp ( attr_name, CB_CONFIG_CHAINING_COMPONENTS )) {
420
               		char * config_attr_value;
421
                       	int done=0;
422
			int j;
423
424
        		slapi_rwlock_wrlock(inst->rwl_config_lock);
425
                       	for (j = 0; mods[i]->mod_bvalues && mods[i]->mod_bvalues[j]; j++) {
426
                               	config_attr_value = (char *) mods[i]->mod_bvalues[j]->bv_val;
427
                               	if (SLAPI_IS_MOD_REPLACE(mods[i]->mod_op)) {
428
                                       	if (!done) {
429
                                               	charray_free(inst->chaining_components);
430
                                               	inst->chaining_components=NULL;
431
                                               	done=1;
432
                                       	}
433
					/* XXXSD assume dns */
434
                                       	charray_add(&inst->chaining_components,
435
                                               	slapi_dn_normalize(slapi_ch_strdup(config_attr_value)));
436
                               	} else
437
                               	if (SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {
438
                                       	charray_add(&inst->chaining_components,
439
                                               	slapi_dn_normalize(slapi_ch_strdup(config_attr_value)));
440
                               	} else
441
                               	if (SLAPI_IS_MOD_DELETE(mods[i]->mod_op)) {
442
                                       	charray_remove(inst->chaining_components,
443
                                               	slapi_dn_normalize(slapi_ch_strdup(config_attr_value)),
444
												0 /* freeit */);
445
                               	}
446
                       	}
447
                       	if (NULL == mods[i]->mod_bvalues) {
448
                               	charray_free(inst->chaining_components);
449
                               	inst->chaining_components=NULL;
450
                       	}
451
        		slapi_rwlock_unlock(inst->rwl_config_lock);
452
                        continue;
453
		} 
454
455
456
457
		if (SLAPI_IS_MOD_DELETE(mods[i]->mod_op) || 
458
                        SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {
459
460
			/* Special processing for binddn & password */
461
			/* because they are optional		    */
462
463
			if (( !strcasecmp ( attr_name, CB_CONFIG_BINDUSER )) || 
464
			    ( !strcasecmp ( attr_name, CB_CONFIG_USERPASSWORD ))) {
465
466
				if (mods[i]->mod_op & LDAP_MOD_DELETE) {
467
                        		rc = cb_instance_config_set((void *) inst, attr_name, 
468
					cb_the_instance_config, NULL, returntext,
469
					CB_CONFIG_PHASE_RUNNING, 1); }
470
				else {
471
                        		rc = cb_instance_config_set((void *) inst, attr_name, 
472
					cb_the_instance_config, mods[i]->mod_bvalues[0], returntext,
473
					CB_CONFIG_PHASE_RUNNING, 1);
474
				}
475
				if (rc==CB_REOPEN_CONN) {
476
					reopen_conn=1;
477
					rc=LDAP_SUCCESS;
478
				}
479
				continue;
480
			}
481
			
482
                        rc= LDAP_UNWILLING_TO_PERFORM;
483
                        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "%s attributes is not allowed",
484
                              (mods[i]->mod_op & LDAP_MOD_DELETE) ? "Deleting" : "Adding");
485
                } else if (mods[i]->mod_op & LDAP_MOD_REPLACE) {
486
                        /* This assumes there is only one bval for this mod. */
487
                        rc = cb_instance_config_set((void *) inst, attr_name, 
488
			cb_the_instance_config, mods[i]->mod_bvalues[0], returntext,
489
				CB_CONFIG_PHASE_RUNNING, 1);
490
		
491
			/* Update requires to reopen connections  */
492
			/* Expensive operation so do it only once */
493
			if (rc==CB_REOPEN_CONN) {
494
				reopen_conn=1;
495
				rc=LDAP_SUCCESS;
496
			}
497
                }
498
	}
499
500
        *returncode= rc; 
501
502
	if (reopen_conn) {
503
		cb_stale_all_connections(inst);
504
	}
505
506
        return ((LDAP_SUCCESS == rc) ? SLAPI_DSE_CALLBACK_OK:SLAPI_DSE_CALLBACK_ERROR);
507
}
508
509
/*
510
** Parse and instantiate backend instances 
511
*/
512
513
int
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
514
cb_parse_instance_config_entry(cb_backend * cb, Slapi_Entry * e)
515
{
516
	cb_backend_instance *inst = NULL;
517
	Slapi_Attr *attr = NULL;
518
	Slapi_Value *sval;
519
	const struct berval *attrValue;
520
	char *instname;
521
	char retmsg[CB_BUFSIZE];
522
	int rc = LDAP_SUCCESS;
1 by Timo Aaltonen
Import upstream version 1.2.10.2
523
524
	CB_ASSERT(e!=NULL);
525
	
526
	/*
527
	** Retrieve the instance name and make sure it is not 
528
	** already declared.
529
	*/
530
	
531
	if ( 0 == slapi_entry_attr_find( e, CB_CONFIG_INSTNAME, &attr )) {
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
532
		slapi_attr_first_value(attr, &sval);
533
		attrValue = slapi_value_get_berval(sval);
534
		instname = attrValue->bv_val;
1 by Timo Aaltonen
Import upstream version 1.2.10.2
535
	} else {
536
		slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, 
537
			"Malformed backend instance (<%s> missing)>\n", CB_CONFIG_INSTNAME); 
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
538
		return -1;
1 by Timo Aaltonen
Import upstream version 1.2.10.2
539
	}
540
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
541
	/* Allocate a new backend internal data structure */
542
	inst = cb_instance_alloc(cb,instname,slapi_entry_get_dn(e));
1 by Timo Aaltonen
Import upstream version 1.2.10.2
543
544
	/* Emulate a add config entry to configure */
545
	/* this backend instance.		   */
546
547
	cb_instance_add_config_callback(NULL,e,NULL,&rc,retmsg,inst);
548
	if ( rc != LDAP_SUCCESS ) {
549
		cb_instance_free(inst);
550
	}
551
	return rc;
552
}
553
554
/*
555
** Update the instance configuration
556
*/
557
558
static int 
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
559
cb_instance_config_initialize(cb_backend_instance * inst, Slapi_Entry * e , int phase, int apply)
560
{
561
	Slapi_Attr *attr = NULL;
562
	Slapi_Value *sval;
563
	Slapi_DN *suffix;
564
	struct berval *bval;
565
	char err_buf[SLAPI_DSE_RETURNTEXT_SIZE];
566
	char *attr_name = NULL;
567
	char *rootdn;
568
	int using_def_connlifetime, i;
569
	int urlfound = 0;
570
	int rc = LDAP_SUCCESS;
1 by Timo Aaltonen
Import upstream version 1.2.10.2
571
572
	using_def_connlifetime=1;
573
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
574
	for (slapi_entry_first_attr(e, &attr); attr; slapi_entry_next_attr(e, attr, &attr)) {
575
		attr_name = NULL;
576
		slapi_attr_get_type(attr, &attr_name);
1 by Timo Aaltonen
Import upstream version 1.2.10.2
577
578
		if ( !strcasecmp ( attr_name, CB_CONFIG_SUFFIX )) {
579
			if (apply && ( inst->inst_be != NULL )) {
580
				suffix = slapi_sdn_new();
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
581
				i = slapi_attr_first_value(attr, &sval);
582
				while (i != -1 ) {
583
					bval = (struct berval *) slapi_value_get_berval(sval);
584
					slapi_sdn_set_dn_byref(suffix, bval->bv_val);
1 by Timo Aaltonen
Import upstream version 1.2.10.2
585
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
586
					if (!slapi_be_issuffix(inst->inst_be, suffix)) {
587
							slapi_be_addsuffix(inst->inst_be, suffix);
588
					}
589
					i = slapi_attr_next_value(attr, i, &sval);
590
				}
1 by Timo Aaltonen
Import upstream version 1.2.10.2
591
				slapi_sdn_free(&suffix);
592
			}
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
593
			continue;
594
		} else if ( !strcasecmp ( attr_name, CB_CONFIG_CHAINING_COMPONENTS )) {
595
			if (apply) {
596
				slapi_rwlock_wrlock(inst->rwl_config_lock);
597
				i = slapi_attr_first_value(attr, &sval);
1 by Timo Aaltonen
Import upstream version 1.2.10.2
598
				charray_free(inst->chaining_components);
599
				inst->chaining_components=NULL;
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
600
				while (i != -1 ) {
601
					bval = (struct berval *) slapi_value_get_berval(sval);
1 by Timo Aaltonen
Import upstream version 1.2.10.2
602
					charray_add(&inst->chaining_components,
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
603
					slapi_dn_normalize(slapi_ch_strdup(bval->bv_val)));
604
					i = slapi_attr_next_value(attr, i, &sval);
605
				}
606
				slapi_rwlock_unlock(inst->rwl_config_lock);
607
			}
608
			continue;
609
		} else if ( !strcasecmp ( attr_name, CB_CONFIG_ILLEGAL_ATTRS )) {
610
			if (apply) {
611
				slapi_rwlock_wrlock(inst->rwl_config_lock);
612
				i = slapi_attr_first_value(attr, &sval);
1 by Timo Aaltonen
Import upstream version 1.2.10.2
613
				charray_free(inst->illegal_attributes);
614
				inst->illegal_attributes=NULL;
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
615
				while (i != -1 ) {
616
					bval = (struct berval *) slapi_value_get_berval(sval);
1 by Timo Aaltonen
Import upstream version 1.2.10.2
617
					charray_add(&inst->illegal_attributes,
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
618
					slapi_ch_strdup(bval->bv_val));
619
					i = slapi_attr_next_value(attr, i, &sval);
620
				}
621
				slapi_rwlock_unlock(inst->rwl_config_lock);
622
			}
623
			continue;
1 by Timo Aaltonen
Import upstream version 1.2.10.2
624
		}
625
626
627
		if ( !strcasecmp ( attr_name, CB_CONFIG_HOSTURL )) {
628
			urlfound=1;
629
		}
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
630
631
		/*
632
		 * We are assuming that each of these attributes are to have
633
		 * only one value.  If they have more than one value, like
634
		 * the nsslapd-suffix attribute, then they need to be
635
		 * handled differently.
636
		 */
637
638
		slapi_attr_first_value(attr, &sval);
639
		bval = (struct berval *) slapi_value_get_berval(sval);
640
641
		if (cb_instance_config_set((void *) inst, attr_name,
1 by Timo Aaltonen
Import upstream version 1.2.10.2
642
			cb_the_instance_config, bval, err_buf, phase, apply ) != LDAP_SUCCESS) {
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
643
			slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,"Error with config attribute %s : %s\n",
1 by Timo Aaltonen
Import upstream version 1.2.10.2
644
				attr_name, err_buf);
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
645
			rc = -1;
646
			break;
647
		}
648
		if ( !strcasecmp ( attr_name, CB_CONFIG_CONNLIFETIME )) {
1 by Timo Aaltonen
Import upstream version 1.2.10.2
649
			using_def_connlifetime=0;
650
		}
651
	}
652
653
654
	/*
655
	** Check for mandatory attributes
656
	** Post-Processing
657
	*/
658
659
	if (LDAP_SUCCESS == rc) {
660
		if (!urlfound) {
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
661
			slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
662
				"Malformed backend instance entry. Mandatory attr <%s> missing\n",CB_CONFIG_HOSTURL);
663
			rc = -1;
1 by Timo Aaltonen
Import upstream version 1.2.10.2
664
		}
665
666
		if (apply ) {
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
667
    		if ( using_def_connlifetime && strchr( inst->pool->hostname, ' ' ) != NULL ) {
668
    			cb_instance_config_set((void *)inst, CB_CONFIG_CONNLIFETIME,
669
    			cb_the_instance_config, NULL /* use default */, err_buf,
1 by Timo Aaltonen
Import upstream version 1.2.10.2
670
					CB_CONFIG_PHASE_INITIALIZATION, 1 );
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
671
    		}
1 by Timo Aaltonen
Import upstream version 1.2.10.2
672
		}
673
	}
674
675
	/* 
676
	** Additional checks
677
	** It is forbidden to use directory manager as proxy user
678
	** due to a bug in the acl check
679
	*/
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
680
	rootdn = cb_get_rootdn();
1 by Timo Aaltonen
Import upstream version 1.2.10.2
681
682
	if (inst->impersonate && inst->pool && inst->pool->binddn && 
683
		!strcmp(inst->pool->binddn,rootdn)) {	/* UTF8 aware */
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
684
		slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
685
			"Error with config attribute %s (%s: forbidden value)\n", CB_CONFIG_BINDUSER, rootdn);
686
		rc= -1;
1 by Timo Aaltonen
Import upstream version 1.2.10.2
687
	}
688
	slapi_ch_free((void **)&rootdn);
689
690
	return rc;
691
}
692
693
/********************************************************
694
** Get and set functions for chaining backend instances *
695
*********************************************************
696
*/
697
698
static void *cb_instance_hosturl_get(void *arg)
699
{
700
	cb_backend_instance * inst=(cb_backend_instance *) arg;
701
	char * data;
702
703
        slapi_rwlock_rdlock(inst->rwl_config_lock);
704
	data = slapi_ch_strdup(inst->pool->url);
705
        slapi_rwlock_unlock(inst->rwl_config_lock);
706
	return data;
707
}
708
709
static int cb_instance_hosturl_set(void *arg, void *value, char *errorbuf, int phase, int apply)
710
{
711
	cb_backend_instance 	*inst=(cb_backend_instance *) arg;
712
	char 			*url = (char *) value;
713
        LDAPURLDesc         	*ludp=NULL;
714
	int 			rc=LDAP_SUCCESS;
715
	int			secure = 0;
716
717
	if (!inst) {
718
		PR_snprintf (errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "NULL instance");
719
		rc = LDAP_OPERATIONS_ERROR;
720
		goto done;
721
	}
722
723
 	if (( rc = slapi_ldap_url_parse( url, &ludp, 0, &secure )) != 0 || !ludp) {
724
		PL_strncpyz(errorbuf,slapi_urlparse_err2string( rc ), SLAPI_DSE_RETURNTEXT_SIZE);
725
		if (CB_CONFIG_PHASE_INITIALIZATION == phase)
726
			inst->pool->url=slapi_ch_strdup("");
727
		rc = LDAP_INVALID_SYNTAX;
728
		goto done;
729
	}
730
 
731
	if (secure && inst->rwl_config_lock) {
732
		int isgss = 0;
733
		slapi_rwlock_rdlock(inst->rwl_config_lock);
734
		isgss = inst->pool->mech && !PL_strcasecmp(inst->pool->mech, "GSSAPI");
735
		slapi_rwlock_unlock(inst->rwl_config_lock);
736
		if (isgss) {
737
			PR_snprintf (errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "Cannot use LDAPS if using GSSAPI - please change the %s to use something other than GSSAPI before changing connection to use LDAPS", CB_CONFIG_BINDMECH);
738
			rc = LDAP_UNWILLING_TO_PERFORM;
739
		}
740
	}
741
742
	if ((LDAP_SUCCESS == rc) && apply) {
743
744
               	slapi_rwlock_wrlock(inst->rwl_config_lock);
745
746
	        if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
747
       			( phase != CB_CONFIG_PHASE_STARTUP )) {
748
749
			/* Dynamic modification				*/
750
			/* Don't free char * pointer now		*/
751
			/* STore them in a waste basket 		*/
752
			/* Will be relesase when the backend stops 	*/
753
			
754
			if (inst->pool->hostname)
755
				charray_add(&inst->pool->waste_basket,inst->pool->hostname);
756
			if (inst->pool->url)
757
				charray_add(&inst->pool->waste_basket,inst->pool->url);
758
			
759
			if (inst->bind_pool->hostname)
760
				charray_add(&inst->bind_pool->waste_basket,inst->bind_pool->hostname);
761
			if (inst->bind_pool->url)
762
				charray_add(&inst->bind_pool->waste_basket,inst->bind_pool->url);
763
764
			/* Require connection cleanup */
765
			rc=CB_REOPEN_CONN;
766
		}
767
768
		/* Normal case. Extract useful data from */
769
		/* the url and update the configuration  */
770
771
		if ((ludp->lud_host==NULL) || (strlen(ludp->lud_host)==0)) {
772
                        inst->pool->hostname=(char *)slapi_ch_strdup((char *)get_localhost_DNS());
773
		} else {
774
               		inst->pool->hostname = slapi_ch_strdup( ludp->lud_host );
775
		}
776
               	inst->pool->url = slapi_ch_strdup( url);
777
               	inst->pool->secure = secure;
778
779
		if ((ludp->lud_port==0) && inst->pool->secure)
780
			inst->pool->port=CB_LDAP_SECURE_PORT;
781
		else
782
               		inst->pool->port = ludp->lud_port;
783
784
		/* Build a charray of <host>:<port> */
785
		/* hostname is of the form <host>[:port] <host>[:port] */
786
787
		{ char * aBufCopy, * aHostName;
788
			char * iter = NULL;
789
			aBufCopy=slapi_ch_strdup(inst->pool->hostname);
790
791
			aHostName=ldap_utf8strtok_r(aBufCopy," ", &iter);
792
			charray_free(inst->url_array);
793
			inst->url_array=NULL;
794
			while (aHostName) {
795
			
796
				char * aHostPort;
797
				if ( NULL == strstr(aHostName,":")) {
798
					aHostPort = slapi_ch_smprintf("%s://%s:%d/",
799
												  inst->pool->secure ? "ldaps" : "ldap", 
800
												  aHostName,inst->pool->port);
801
				} else {
802
					aHostPort = slapi_ch_smprintf("%s://%s/", 
803
												  inst->pool->secure ? "ldaps" : "ldap",
804
												  aHostName);
805
				}
806
807
				charray_add(&inst->url_array,aHostPort);
808
				aHostName=ldap_utf8strtok_r(NULL," ", &iter);
809
			}
810
811
			slapi_ch_free((void **) &aBufCopy);
812
		}
813
814
		inst->bind_pool->port=inst->pool->port;
815
		inst->bind_pool->secure=inst->pool->secure;
816
		inst->bind_pool->hostname=slapi_ch_strdup(inst->pool->hostname);
817
818
	        slapi_rwlock_unlock(inst->rwl_config_lock);
819
	}
820
done:
821
    	if ( ludp != NULL ) {
822
       		ldap_free_urldesc( ludp );
823
	}
824
        return rc;
825
}
826
827
static void *cb_instance_binduser_get(void *arg)
828
{
829
	cb_backend_instance * inst=(cb_backend_instance *) arg;
830
	char * data;
831
832
        slapi_rwlock_rdlock(inst->rwl_config_lock);
833
	data = slapi_ch_strdup(inst->pool->binddn2);	/* not normalized */	
834
        slapi_rwlock_unlock(inst->rwl_config_lock);
835
	return data;
836
}
837
838
static int cb_instance_binduser_set(void *arg, void *value, char *errorbuf, int phase, int apply)
839
{
840
	cb_backend_instance * inst=(cb_backend_instance *) arg;
841
	int rc=LDAP_SUCCESS;
842
843
	if (apply) {
844
845
		slapi_rwlock_wrlock(inst->rwl_config_lock);
846
		if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
847
		    ( phase != CB_CONFIG_PHASE_STARTUP )) {
848
849
			/* Dynamic modif   */
850
			/* Free user later */
851
852
			charray_add(&inst->pool->waste_basket,inst->pool->binddn);
853
			charray_add(&inst->pool->waste_basket,inst->pool->binddn2);
854
			rc=CB_REOPEN_CONN;
855
		}
856
857
		/* normalize and ignore the case */
858
		inst->pool->binddn = slapi_create_dn_string_case("%s", (char *)value);
859
		/* not normalized */
860
		inst->pool->binddn2=slapi_ch_strdup((char *) value);
861
		slapi_rwlock_unlock(inst->rwl_config_lock);
862
	} else {
863
864
		/* Security check */
865
		/* directory manager of the farm server should not be used as */
866
		/* proxing user. This is hard to check, so assume same directory */
867
		/* manager across servers.					   */
868
		
869
		char * rootdn = cb_get_rootdn();
870
		char * theValueCopy = NULL;
871
872
		if (value) {
873
			theValueCopy = slapi_create_dn_string_case("%s", (char *) value);
874
		}
875
876
		slapi_rwlock_rdlock(inst->rwl_config_lock);
877
		if (inst->impersonate && theValueCopy && 
878
		    !strcmp(theValueCopy,rootdn)) {	/* UTF8-aware. See cb_get_dn() */
879
			rc=LDAP_UNWILLING_TO_PERFORM; 
880
			if (errorbuf) {
881
				PR_snprintf(errorbuf,SLAPI_DSE_RETURNTEXT_SIZE, "value %s not allowed",rootdn);
882
			}
883
		}
884
		slapi_rwlock_unlock(inst->rwl_config_lock);
885
886
		slapi_ch_free((void **)&theValueCopy);
887
		slapi_ch_free((void **)&rootdn);
888
	}
889
890
	return rc;
891
}
892
893
894
static void *cb_instance_userpassword_get(void *arg)
895
{
896
	cb_backend_instance * inst=(cb_backend_instance *) arg;
897
	char * data;
898
899
        slapi_rwlock_rdlock(inst->rwl_config_lock);
900
	data = slapi_ch_strdup(inst->pool->password);
901
        slapi_rwlock_unlock(inst->rwl_config_lock);
902
	return data;
903
}
904
905
static int cb_instance_userpassword_set(void *arg, void *value, char *errorbuf, int phase, int apply)
906
{
907
	cb_backend_instance * inst=(cb_backend_instance *) arg;
908
	int rc=LDAP_SUCCESS;
909
910
	if (apply) {
911
               	slapi_rwlock_wrlock(inst->rwl_config_lock);
912
		if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
913
    			( phase != CB_CONFIG_PHASE_STARTUP )) {
914
915
			/* Dynamic modif */
916
			charray_add(&inst->pool->waste_basket,inst->pool->password);
917
			rc=CB_REOPEN_CONN;
918
		}
919
920
		inst->pool->password=slapi_ch_strdup((char *) value);
921
               	slapi_rwlock_unlock(inst->rwl_config_lock);
922
	}
923
	return rc;
924
}
925
926
static void *cb_instance_sizelimit_get(void *arg)
927
{
928
	cb_backend_instance * inst=(cb_backend_instance *) arg;
929
	uintptr_t data;
930
931
        slapi_rwlock_rdlock(inst->rwl_config_lock);
932
	data = inst->sizelimit;
933
        slapi_rwlock_unlock(inst->rwl_config_lock);
934
	return (void *) data;
935
}
936
937
static int cb_instance_sizelimit_set(void *arg, void *value, char *errorbuf, int phase, int apply)
938
{
939
	cb_backend_instance * inst=(cb_backend_instance *) arg;
940
	if (apply) {
941
        	slapi_rwlock_wrlock(inst->rwl_config_lock);
942
            inst->sizelimit=(int) ((uintptr_t)value);
943
        	slapi_rwlock_unlock(inst->rwl_config_lock);
944
		if (inst->inst_be) 
945
			be_set_sizelimit(inst->inst_be, (int) ((uintptr_t)value));
946
	}
947
	return LDAP_SUCCESS;
948
}
949
950
static void *cb_instance_timelimit_get(void *arg)
951
{
952
	cb_backend_instance * inst=(cb_backend_instance *) arg;
953
	uintptr_t data;
954
955
        slapi_rwlock_rdlock(inst->rwl_config_lock);
956
	data = inst->timelimit;
957
        slapi_rwlock_unlock(inst->rwl_config_lock);
958
	return (void *) data;
959
}
960
961
static int cb_instance_timelimit_set(void *arg, void *value, char *errorbuf, int phase, int apply)
962
{
963
	cb_backend_instance * inst=(cb_backend_instance *) arg;
964
	if (apply) {
965
        	slapi_rwlock_wrlock(inst->rwl_config_lock);
966
		inst->timelimit=(int) ((uintptr_t)value);
967
        	slapi_rwlock_unlock(inst->rwl_config_lock);
968
		if (inst->inst_be) 
969
			be_set_timelimit(inst->inst_be, (int) ((uintptr_t)value));
970
	}
971
	return LDAP_SUCCESS;
972
}
973
974
static void *cb_instance_max_test_get(void *arg)
975
{
976
	cb_backend_instance * inst=(cb_backend_instance *) arg;
977
	uintptr_t data;
978
979
        slapi_rwlock_rdlock(inst->rwl_config_lock);
980
	data = inst->max_test_time;
981
        slapi_rwlock_unlock(inst->rwl_config_lock);
982
	return (void *) data;
983
}
984
985
static int cb_instance_max_test_set(void *arg, void *value, char *errorbuf, int phase, int apply)
986
{
987
	cb_backend_instance * inst=(cb_backend_instance *) arg;
988
	if (apply) {
989
        	slapi_rwlock_wrlock(inst->rwl_config_lock);
990
		inst->max_test_time=(int) ((uintptr_t)value);
991
        	slapi_rwlock_unlock(inst->rwl_config_lock);
992
	}
993
	return LDAP_SUCCESS;
994
}
995
996
static void *cb_instance_max_idle_get(void *arg)
997
{
998
	cb_backend_instance * inst=(cb_backend_instance *) arg;
999
	uintptr_t data;
1000
1001
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1002
	data = inst->max_idle_time;
1003
        slapi_rwlock_unlock(inst->rwl_config_lock);
1004
	return (void *) data;
1005
}
1006
1007
static int cb_instance_max_idle_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1008
{
1009
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1010
	if (apply) {
1011
        	slapi_rwlock_wrlock(inst->rwl_config_lock);
1012
		inst->max_idle_time=(int) ((uintptr_t)value);
1013
        	slapi_rwlock_unlock(inst->rwl_config_lock);
1014
	}
1015
	return LDAP_SUCCESS;
1016
}
1017
1018
1019
static void *cb_instance_hoplimit_get(void *arg)
1020
{
1021
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1022
	uintptr_t data;
1023
1024
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1025
	data = inst->hoplimit;
1026
        slapi_rwlock_unlock(inst->rwl_config_lock);
1027
	return (void *) data;
1028
}
1029
1030
static int cb_instance_hoplimit_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1031
{
1032
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1033
	if (apply) {
1034
        	slapi_rwlock_wrlock(inst->rwl_config_lock);
1035
		inst->hoplimit=(int) ((uintptr_t)value);
1036
        	slapi_rwlock_unlock(inst->rwl_config_lock);
1037
	}
1038
	return LDAP_SUCCESS;
1039
}
1040
1041
static void *cb_instance_maxbconn_get(void *arg)
1042
{
1043
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1044
	uintptr_t data;
1045
1046
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1047
	data = inst->bind_pool->conn.maxconnections;
1048
        slapi_rwlock_unlock(inst->rwl_config_lock);
1049
	return (void *) data;
1050
}
1051
1052
static int cb_instance_maxbconn_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1053
{
1054
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1055
	if (apply) {
1056
        	slapi_rwlock_wrlock(inst->rwl_config_lock);
1057
		inst->bind_pool->conn.maxconnections=(int) ((uintptr_t)value);
1058
        	slapi_rwlock_unlock(inst->rwl_config_lock);
1059
	}
1060
	return LDAP_SUCCESS;
1061
}
1062
1063
static void *cb_instance_maxconn_get(void *arg)
1064
{
1065
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1066
	uintptr_t data;
1067
1068
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1069
	data = inst->pool->conn.maxconnections;
1070
        slapi_rwlock_unlock(inst->rwl_config_lock);
1071
	return (void *) data;
1072
}
1073
1074
static int cb_instance_maxconn_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1075
{
1076
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1077
	if (apply) {
1078
        	slapi_rwlock_wrlock(inst->rwl_config_lock);
1079
		inst->pool->conn.maxconnections=(int) ((uintptr_t)value);
1080
        	slapi_rwlock_unlock(inst->rwl_config_lock);
1081
	}
1082
	return LDAP_SUCCESS;
1083
}
1084
1085
static void *cb_instance_abandonto_get(void *arg)
1086
{
1087
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1088
	uintptr_t data;
1089
1090
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1091
	data = inst->abandon_timeout.tv_sec;
1092
        slapi_rwlock_unlock(inst->rwl_config_lock);
1093
	return (void *) data;
1094
}
1095
1096
static int cb_instance_abandonto_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1097
{
1098
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1099
1100
	if (apply) {
1101
		if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
1102
    			( phase != CB_CONFIG_PHASE_STARTUP )) {
1103
1104
			/* Dynamic modif not supported     */
1105
			/* Stored in ldif only		   */
1106
			return LDAP_SUCCESS;
1107
		}
1108
1109
               	slapi_rwlock_wrlock(inst->rwl_config_lock);
1110
		inst->abandon_timeout.tv_sec=(int) ((uintptr_t)value);
1111
		inst->abandon_timeout.tv_usec=0;
1112
               	slapi_rwlock_unlock(inst->rwl_config_lock);
1113
	}
1114
	return LDAP_SUCCESS;
1115
}
1116
1117
static void *cb_instance_maxbconc_get(void *arg)
1118
{
1119
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1120
	uintptr_t data;
1121
1122
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1123
	data = inst->bind_pool->conn.maxconcurrency;
1124
        slapi_rwlock_unlock(inst->rwl_config_lock);
1125
	return (void *) data;
1126
}
1127
1128
static int cb_instance_maxbconc_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1129
{
1130
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1131
	if (apply) {
1132
        	slapi_rwlock_wrlock(inst->rwl_config_lock);
1133
		inst->bind_pool->conn.maxconcurrency=(int) ((uintptr_t)value);
1134
        	slapi_rwlock_unlock(inst->rwl_config_lock);
1135
	}
1136
	return LDAP_SUCCESS;
1137
}
1138
1139
static void *cb_instance_maxconc_get(void *arg)
1140
{
1141
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1142
	uintptr_t data;
1143
1144
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1145
	data = inst->pool->conn.maxconcurrency;
1146
        slapi_rwlock_unlock(inst->rwl_config_lock);
1147
	return (void *) data;
1148
}
1149
1150
static int cb_instance_maxconc_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1151
{
1152
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1153
	if (apply) {
1154
                slapi_rwlock_wrlock(inst->rwl_config_lock);
1155
		inst->pool->conn.maxconcurrency=(int) ((uintptr_t)value);
1156
                slapi_rwlock_unlock(inst->rwl_config_lock);
1157
	}
1158
        return LDAP_SUCCESS;   
1159
}
1160
1161
static void *cb_instance_imperson_get(void *arg)
1162
{
1163
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1164
        uintptr_t data;
1165
1166
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1167
        data = inst->impersonate;
1168
        slapi_rwlock_unlock(inst->rwl_config_lock);
1169
        return (void *) data;
1170
}
1171
1172
static int cb_instance_imperson_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1173
{
1174
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1175
	int rc=LDAP_SUCCESS;
1176
1177
	if (apply) {
1178
                slapi_rwlock_wrlock(inst->rwl_config_lock); 
1179
		inst->impersonate=(int) ((uintptr_t)value);
1180
                slapi_rwlock_unlock(inst->rwl_config_lock); 
1181
	} else {
1182
		/* Security check: Make sure the proxing user is */
1183
		/* not the directory manager.			 */
1184
1185
		char * rootdn=cb_get_rootdn();
1186
1187
                slapi_rwlock_rdlock(inst->rwl_config_lock); 
1188
		if (((int) ((uintptr_t)value)) && inst->pool && inst->pool->binddn &&
1189
	                !strcmp(inst->pool->binddn,rootdn)) {	/* UTF-8 aware */
1190
		  	rc=LDAP_UNWILLING_TO_PERFORM;
1191
			if (errorbuf)
1192
				PR_snprintf(errorbuf,SLAPI_DSE_RETURNTEXT_SIZE, "Proxy mode incompatible with %s value (%s not allowed)",
1193
					CB_CONFIG_BINDUSER,rootdn);
1194
		}
1195
                slapi_rwlock_unlock(inst->rwl_config_lock); 
1196
		slapi_ch_free((void **)&rootdn);
1197
	}
1198
1199
        return rc;   
1200
}
1201
1202
static void *cb_instance_connlife_get(void *arg)
1203
{
1204
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1205
        uintptr_t data; 
1206
 
1207
        slapi_rwlock_rdlock(inst->rwl_config_lock); 
1208
        data=inst->pool->conn.connlifetime;
1209
        slapi_rwlock_unlock(inst->rwl_config_lock); 
1210
        return (void *) data; 
1211
}
1212
1213
static int cb_instance_connlife_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1214
{
1215
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1216
	if (apply) {
1217
                slapi_rwlock_wrlock(inst->rwl_config_lock);  
1218
		inst->pool->conn.connlifetime=(int) ((uintptr_t)value);
1219
                slapi_rwlock_unlock(inst->rwl_config_lock);  
1220
	}
1221
        return LDAP_SUCCESS;     
1222
}
1223
1224
static void *cb_instance_bindto_get(void *arg)
1225
{
1226
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1227
        uintptr_t data;  
1228
 
1229
        slapi_rwlock_rdlock(inst->rwl_config_lock);  
1230
        data=inst->bind_pool->conn.op_timeout.tv_sec;
1231
        slapi_rwlock_unlock(inst->rwl_config_lock);  
1232
        return (void *) data;   
1233
}
1234
1235
static int cb_instance_bindto_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1236
{
1237
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1238
	if (apply) {
1239
                slapi_rwlock_wrlock(inst->rwl_config_lock);   
1240
		inst->bind_pool->conn.op_timeout.tv_sec=(int) ((uintptr_t)value);
1241
		inst->bind_pool->conn.op_timeout.tv_usec=0;
1242
		inst->bind_pool->conn.bind_timeout.tv_sec=(int) ((uintptr_t)value);
1243
		inst->bind_pool->conn.bind_timeout.tv_usec=0;
1244
		/* Used to bind to the farm server */
1245
		inst->pool->conn.bind_timeout.tv_sec=(int) ((uintptr_t)value);
1246
		inst->pool->conn.bind_timeout.tv_usec=0;
1247
                slapi_rwlock_unlock(inst->rwl_config_lock);   
1248
	}
1249
	return LDAP_SUCCESS;
1250
}
1251
1252
static void *cb_instance_opto_get(void *arg)
1253
{
1254
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1255
        uintptr_t data;  
1256
 
1257
        slapi_rwlock_rdlock(inst->rwl_config_lock);  
1258
        data=inst->pool->conn.op_timeout.tv_sec;
1259
        slapi_rwlock_unlock(inst->rwl_config_lock);  
1260
        return (void *) data;   
1261
}
1262
1263
static int cb_instance_opto_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1264
{
1265
        cb_backend_instance * inst=(cb_backend_instance *) arg;
1266
        if (apply) {
1267
                slapi_rwlock_wrlock(inst->rwl_config_lock);
1268
                inst->pool->conn.op_timeout.tv_sec=(int) ((uintptr_t)value);
1269
                inst->pool->conn.op_timeout.tv_usec=0;
1270
                slapi_rwlock_unlock(inst->rwl_config_lock);
1271
        }
1272
        return LDAP_SUCCESS;
1273
}
1274
1275
static void *cb_instance_ref_get(void *arg)
1276
{
1277
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1278
        uintptr_t data;   
1279
  
1280
        slapi_rwlock_rdlock(inst->rwl_config_lock);   
1281
        data=inst->searchreferral;
1282
        slapi_rwlock_unlock(inst->rwl_config_lock);   
1283
        return (void *) data;    
1284
}
1285
1286
static int cb_instance_ref_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1287
{
1288
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1289
	if (apply) {
1290
                slapi_rwlock_wrlock(inst->rwl_config_lock);    
1291
		inst->searchreferral=(int) ((uintptr_t)value);
1292
                slapi_rwlock_unlock(inst->rwl_config_lock);    
1293
	}
1294
	return LDAP_SUCCESS;
1295
}
1296
1297
static void *cb_instance_acl_get(void *arg)
1298
{
1299
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1300
        uintptr_t data;
1301
1302
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1303
        data=inst->local_acl;
1304
        slapi_rwlock_unlock(inst->rwl_config_lock);
1305
        return (void *) data;
1306
}
1307
1308
static int cb_instance_acl_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1309
{
1310
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1311
1312
	if (apply) {
1313
    		if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
1314
                        ( phase != CB_CONFIG_PHASE_STARTUP )) {
1315
1316
                        /* Dynamic modif not supported     */
1317
                        /* Stored in ldif only             */
1318
                        return LDAP_SUCCESS;
1319
                }
1320
	        slapi_rwlock_wrlock(inst->rwl_config_lock);
1321
		inst->local_acl=(int) ((uintptr_t)value);
1322
	        slapi_rwlock_unlock(inst->rwl_config_lock);
1323
	}
1324
	return LDAP_SUCCESS;
1325
}
1326
1327
static void *cb_instance_bindretry_get(void *arg)
1328
{
1329
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1330
	uintptr_t data;
1331
1332
        slapi_rwlock_rdlock(inst->rwl_config_lock); 
1333
        data=inst->bind_retry;
1334
        slapi_rwlock_unlock(inst->rwl_config_lock); 
1335
        return (void *) data; 
1336
}
1337
1338
static int cb_instance_bindretry_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1339
{
1340
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1341
	if (apply) {
1342
                slapi_rwlock_wrlock(inst->rwl_config_lock);
1343
		inst->bind_retry=(int) ((uintptr_t)value);
1344
                slapi_rwlock_unlock(inst->rwl_config_lock);
1345
	}
1346
	return LDAP_SUCCESS;
1347
}
1348
1349
1350
static void *cb_instance_starttls_get(void *arg)
1351
{
1352
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1353
        uintptr_t data;
1354
1355
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1356
        data=inst->pool->starttls;
1357
        slapi_rwlock_unlock(inst->rwl_config_lock);
1358
        return (void *) data;
1359
}
1360
1361
static int cb_instance_starttls_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1362
{
1363
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1364
	int rc = LDAP_SUCCESS;
1365
1366
	if (!inst) {
1367
		PR_snprintf (errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "NULL instance");
1368
		rc = LDAP_OPERATIONS_ERROR;
1369
		goto done;
1370
	}
1371
1372
	if (value && inst->rwl_config_lock) {
1373
		int isgss = 0;
1374
		slapi_rwlock_rdlock(inst->rwl_config_lock);
1375
		isgss = inst->pool->mech && !PL_strcasecmp(inst->pool->mech, "GSSAPI");
1376
		slapi_rwlock_unlock(inst->rwl_config_lock);
1377
		if (isgss) {
1378
			PR_snprintf (errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "Cannot use startTLS if using GSSAPI - please change the %s to use something other than GSSAPI before changing connection to use startTLS", CB_CONFIG_BINDMECH);
1379
			rc = LDAP_UNWILLING_TO_PERFORM;
1380
		}
1381
	}
1382
1383
	if ((LDAP_SUCCESS == rc) && apply) {
1384
	        slapi_rwlock_wrlock(inst->rwl_config_lock);
1385
		inst->pool->starttls=(int) ((uintptr_t)value);
1386
		inst->bind_pool->starttls=inst->pool->starttls;
1387
	        slapi_rwlock_unlock(inst->rwl_config_lock);
1388
		if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
1389
    			( phase != CB_CONFIG_PHASE_STARTUP )) {
1390
		    rc=CB_REOPEN_CONN; /* reconnect with the new starttls setting */
1391
		}
1392
	}
1393
done:
1394
	return rc;
1395
}
1396
1397
static void *cb_instance_bindmech_get(void *arg)
1398
{
1399
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1400
	char * data;
1401
1402
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1403
	data = slapi_ch_strdup(inst->pool->mech);
1404
        slapi_rwlock_unlock(inst->rwl_config_lock);
1405
	return data;
1406
}
1407
1408
static int cb_instance_bindmech_set(void *arg, void *value, char *errorbuf, int phase, int apply)
1409
{
1410
	cb_backend_instance * inst=(cb_backend_instance *) arg;
1411
	int rc=LDAP_SUCCESS;
1412
1413
	if (!inst) {
1414
		PR_snprintf (errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "NULL instance");
1415
		rc = LDAP_OPERATIONS_ERROR;
1416
		goto done;
1417
	}
1418
1419
	if (value && !PL_strcasecmp((char *) value, "GSSAPI") && inst->rwl_config_lock) {
1420
		int secure = 0;
1421
		slapi_rwlock_rdlock(inst->rwl_config_lock);
1422
		secure = inst->pool->secure || inst->pool->starttls;
1423
		slapi_rwlock_unlock(inst->rwl_config_lock);
1424
		if (secure) {
1425
			PR_snprintf (errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "Cannot use SASL/GSSAPI if using SSL or TLS - please change the connection to use no security before changing %s to use GSSAPI", CB_CONFIG_BINDMECH);
1426
			rc = LDAP_UNWILLING_TO_PERFORM;
1427
		}
1428
	}
1429
1430
	if ((LDAP_SUCCESS == rc) && apply) {
1431
               	slapi_rwlock_wrlock(inst->rwl_config_lock);
1432
		if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
1433
    			( phase != CB_CONFIG_PHASE_STARTUP )) {
1434
1435
			/* Dynamic modif */
1436
			if (inst->pool->mech) {
1437
			    charray_add(&inst->pool->waste_basket,inst->pool->mech);
1438
			}
1439
			if (inst->bind_pool->mech) {
1.2.1 by Timo Aaltonen
Import upstream version 1.3.1.7
1440
			    charray_add(&inst->bind_pool->waste_basket,inst->bind_pool->mech);
1 by Timo Aaltonen
Import upstream version 1.2.10.2
1441
			}
1442
			rc=CB_REOPEN_CONN;
1443
		}
1444
1445
		if (value && !PL_strcasecmp((char *) value, CB_SIMPLE_BINDMECH)) {
1446
		    inst->pool->mech=slapi_ch_strdup(LDAP_SASL_SIMPLE);
1447
		} else {
1448
		    inst->pool->mech=slapi_ch_strdup((char *) value);
1449
		}
1450
		inst->bind_pool->mech = slapi_ch_strdup(inst->pool->mech);
1451
               	slapi_rwlock_unlock(inst->rwl_config_lock);
1452
	}
1453
done:
1454
	return rc;
1455
}
1456
1457
1458
1459
/* Finds an entry in a config_info array with the given name.  Returns
1460
 * the entry on success and NULL when not found.
1461
 */
1462
static cb_instance_config_info *cb_get_config_info(cb_instance_config_info *config_array, char *attr_name)
1463
{
1464
        int x;
1465
1466
        for(x = 0; config_array[x].config_name != NULL; x++) {
1467
                if (!strcasecmp(config_array[x].config_name, attr_name)) {
1468
                        return &(config_array[x]);
1469
                }
1470
        }
1471
        return NULL;
1472
}
1473
1474
/*
1475
** Update an attribute value
1476
** For now, unknown attributes are ignored
1477
** Return a LDAP error code OR CB_REOPEN_CONN when the
1478
** update requires to close open connections.
1479
** err_buf is size SLAPI_DSE_RETURNTEXT_SIZE
1480
*/
1481
static int 
1482
cb_instance_config_set(void *arg, char *attr_name, cb_instance_config_info *config_array, 
1483
struct berval *bval, char *err_buf, int phase, int apply_mod)
1484
{
1485
        cb_instance_config_info *config;
1486
        int use_default;
1487
        int int_val;
1488
        long long_val;
1.1.4 by Timo Aaltonen
Import upstream version 1.3.0.2
1489
        int retval = -1;
1 by Timo Aaltonen
Import upstream version 1.2.10.2
1490
1491
        config = cb_get_config_info(config_array, attr_name);
1492
        if (NULL == config) {
1493
		/* Ignore unknown attributes */
1494
                return LDAP_SUCCESS;
1495
        }
1496
1497
        /* If the config phase is initialization or if bval is NULL, we will use
1498
         * the default value for the attribute. */
1499
        if (CB_CONFIG_PHASE_INITIALIZATION == phase || NULL == bval) {
1500
                use_default = 1;
1501
        } else { 
1502
                use_default = 0;
1503
                /* Since we are setting the value for the config attribute, we
1504
                 * need to turn on the CB_PREVIOUSLY_SET flag to make
1505
                 * sure this attribute is shown. */
1506
                config->config_flags |= CB_PREVIOUSLY_SET;
1507
        }
1508
1509
        switch(config->config_type) {
1510
        case CB_CONFIG_TYPE_INT:
1511
                if (use_default) {
1512
                        int_val = cb_atoi(config->config_default_value);
1513
                } else {
1514
                        int_val = cb_atoi((char *)bval->bv_val);
1515
                }
1516
                retval = config->config_set_fn(arg, (void *) ((uintptr_t)int_val), err_buf, phase, apply_mod);
1517
                break;
1518
        case CB_CONFIG_TYPE_INT_OCTAL:
1519
                if (use_default) {
1520
                        int_val = (int) strtol(config->config_default_value, NULL, 8);
1521
                } else {
1522
                        int_val = (int) strtol((char *)bval->bv_val, NULL, 8);
1523
                }
1524
                retval = config->config_set_fn(arg, (void *) ((uintptr_t)int_val), err_buf, phase, apply_mod);
1525
                break;
1526
        case CB_CONFIG_TYPE_LONG:
1527
                if (use_default) {
1528
                        long_val = cb_atol(config->config_default_value);
1529
                } else {
1530
                        long_val = cb_atol((char *)bval->bv_val);
1531
                }
1532
                retval = config->config_set_fn(arg, (void *) long_val, err_buf, phase, apply_mod);
1533
                break;
1534
        case CB_CONFIG_TYPE_STRING:
1535
                if (use_default) {
1536
                        retval = config->config_set_fn(arg, config->config_default_value, err_buf, phase, apply_mod);
1537
                } else {
1538
                        retval = config->config_set_fn(arg, bval->bv_val, err_buf, phase, apply_mod);
1539
                }
1540
                break;
1541
        case CB_CONFIG_TYPE_ONOFF:
1542
                if (use_default) {
1543
                        int_val = !strcasecmp(config->config_default_value, "on");
1544
                } else {
1545
                        int_val = !strcasecmp((char *) bval->bv_val, "on");
1546
                }
1547
                retval = config->config_set_fn(arg, (void *) ((uintptr_t)int_val), err_buf, phase, apply_mod);
1548
                break;
1549
        }        
1550
        return retval;
1551
}
1552
1553
/* Utility function used in creating config entries.  Using the
1554
 * config_info, this function gets info and formats in the correct
1555
 * way.
1556
 * buf is CB_BUFSIZE size
1557
 */
1558
void cb_instance_config_get(void *arg, cb_instance_config_info *config, char *buf)
1559
{
1560
        char *tmp_string;
1561
1562
        if (config == NULL) {
1563
                buf[0] = '\0';
1564
		return;
1565
        }
1566
 
1567
        switch(config->config_type) {
1568
        case CB_CONFIG_TYPE_INT:
1569
                sprintf(buf, "%d", (int) ((uintptr_t)config->config_get_fn(arg)));
1570
                break;
1571
        case CB_CONFIG_TYPE_INT_OCTAL:
1572
                sprintf(buf, "%o", (int) ((uintptr_t)config->config_get_fn(arg)));
1573
                break;
1574
        case CB_CONFIG_TYPE_LONG:
1575
                sprintf(buf, "%ld", (long) ((uintptr_t)config->config_get_fn(arg)));
1576
                break;
1577
        case CB_CONFIG_TYPE_STRING:
1578
                /* Remember the get function for strings returns memory
1579
                 * that must be freed. */
1580
                tmp_string = (char *) config->config_get_fn(arg);
1581
                if (tmp_string) {
1582
                    PR_snprintf(buf, CB_BUFSIZE, "%s", (char *) tmp_string);
1583
                    slapi_ch_free_string(&tmp_string);
1584
                } else {
1585
                    buf[0] = '\0';
1586
                }
1587
                break;
1588
        case CB_CONFIG_TYPE_ONOFF:
1589
                if ((int) ((uintptr_t)config->config_get_fn(arg))) {
1590
                        sprintf(buf,"%s","on");
1591
                } else {
1592
                        sprintf(buf,"%s","off");
1593
                }
1594
                break;
1595
	default:
1596
                slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
1597
                        "Invalid attribute syntax.\n");
1598
	
1599
        }
1600
}
1601
1602
/*
1603
** Search for instance config entry
1604
** Always return 'active' values because some configuration changes
1605
** won't be taken into account until the server restarts
1606
*/
1607
1608
int cb_instance_search_config_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
1609
        int *returncode, char *returntext, void *arg) {
1610
1611
        char                    buf[CB_BUFSIZE];
1612
        struct berval           val;
1613
        struct berval           *vals[2];
1614
        int                     i = 0;
1615
        cb_backend_instance     *inst = (cb_backend_instance *)arg;
1616
        cb_instance_config_info * config;
1617
1618
        vals[0] = &val;
1619
        vals[1] = NULL;
1620
1621
        /* suffixes */
1622
1623
        slapi_rwlock_rdlock(inst->rwl_config_lock);
1624
1625
        {
1626
                const Slapi_DN *aSuffix;
1627
                i=0;
1628
		if (inst->inst_be) {
1629
                while ((aSuffix=slapi_be_getsuffix(inst->inst_be,i))) {
1630
                        val.bv_val = (char *)slapi_sdn_get_dn(aSuffix);
1631
                        val.bv_len = strlen( val.bv_val );
1632
			if (val.bv_len) {
1633
                        	if (i==0)
1634
                                	slapi_entry_attr_replace(e,CB_CONFIG_SUFFIX,(struct berval **)vals );
1635
                        	else
1636
                                	slapi_entry_attr_merge(e,CB_CONFIG_SUFFIX,(struct berval **)vals );
1637
			}
1638
                        i++;
1639
                }
1640
		}
1641
        }
1642
1643
	for (i=0; inst->chaining_components && inst->chaining_components[i]; i++) {
1644
                val.bv_val = inst->chaining_components[i];
1645
                val.bv_len = strlen( val.bv_val );
1646
		if (val.bv_len) {
1647
        		if (i==0)
1648
                		slapi_entry_attr_replace(e,CB_CONFIG_CHAINING_COMPONENTS,(struct berval **)vals );
1649
                	else
1650
                        	slapi_entry_attr_merge(e,CB_CONFIG_CHAINING_COMPONENTS,(struct berval **)vals );
1651
		}
1652
	}
1653
	
1654
	for (i=0; inst->illegal_attributes && inst->illegal_attributes[i]; i++) {
1655
                val.bv_val = inst->illegal_attributes[i];
1656
                val.bv_len = strlen( val.bv_val );
1657
		if (val.bv_len) {
1658
        		if (i==0)
1659
                		slapi_entry_attr_replace(e,CB_CONFIG_ILLEGAL_ATTRS,(struct berval **)vals );
1660
                	else
1661
                        	slapi_entry_attr_merge(e,CB_CONFIG_ILLEGAL_ATTRS,(struct berval **)vals );
1662
		}
1663
	}
1664
1665
        slapi_rwlock_unlock(inst->rwl_config_lock);
1666
1667
	/* standard attributes */
1668
        for(config = cb_the_instance_config; config->config_name != NULL; config++) {
1669
                if (!(config->config_flags & (CB_ALWAYS_SHOW | CB_PREVIOUSLY_SET))) {
1670
                        /* This config option shouldn't be shown */
1671
                        continue;
1672
                }
1673
1674
                cb_instance_config_get((void *) inst, config, buf);
1675
1676
                val.bv_val = buf;
1677
                val.bv_len = strlen(buf);
1678
                if (val.bv_len) {
1679
                    slapi_entry_attr_replace(e, config->config_name, vals);
1680
                } else {
1681
                    slapi_entry_attr_delete(e, config->config_name);
1682
                }
1683
        }
1684
1685
        *returncode = LDAP_SUCCESS;
1686
        return SLAPI_DSE_CALLBACK_OK;
1687
}
1688
1689
/*
1690
** Ooops!!! The backend instance is beeing deleted
1691
*/
1692
1693
int cb_instance_delete_config_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* e2,
1694
       int *returncode, char *returntext, void *arg) {
1695
1696
        cb_backend_instance * inst = (cb_backend_instance *) arg;
1697
	int rc;
1698
	Slapi_Entry * anEntry=NULL;
1699
	Slapi_DN * aDn;
1700
1701
	CB_ASSERT( inst!=NULL );
1702
1703
	/* notify the front-end */
1704
	slapi_mtn_be_stopping(inst->inst_be);
1705
1706
	/* Now it is safe to stop */
1707
	/* No pending op          */
1708
1709
1710
	/* unregister callbacks */
1711
        slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, inst->configDn, 
1712
		LDAP_SCOPE_BASE, "(objectclass=*)", cb_instance_search_config_callback);
1713
1714
        slapi_config_remove_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, inst->configDn,
1715
		 LDAP_SCOPE_BASE, "(objectclass=*)", cb_instance_delete_config_callback);
1716
1717
        slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, inst->configDn, 
1718
		LDAP_SCOPE_BASE, "(objectclass=*)", cb_instance_modify_config_check_callback);
1719
        slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP, inst->configDn, 
1720
		LDAP_SCOPE_BASE, "(objectclass=*)", cb_instance_modify_config_callback);
1721
1722
	/* At this point, the monitor entry should have been removed */
1723
	/* If not, manually call delete callback 		     */
1724
1725
        aDn = slapi_sdn_new_dn_byref(inst->monitorDn);
1726
       	if ( LDAP_SUCCESS==(slapi_search_internal_get_entry(aDn,NULL, &anEntry,inst->backend_type->identity))) {
1727
		cb_delete_monitor_callback( NULL, anEntry, NULL, &rc , NULL, inst );
1728
		if (anEntry) 
1729
	                slapi_entry_free(anEntry);
1730
	}
1731
        slapi_sdn_done(aDn);
1732
        slapi_sdn_free(&aDn);
1733
1734
	/* free resources */
1735
        cb_close_conn_pool(inst->bind_pool);
1736
        cb_close_conn_pool(inst->pool);
1737
	slapi_be_free(&(inst->inst_be));
1738
        cb_instance_free(inst);
1739
1740
	return SLAPI_DSE_CALLBACK_OK;
1741
}
1742
1743
static void cb_instance_add_monitor_later(time_t when, void *arg) {
1744
1745
	cb_backend_instance * inst = (cb_backend_instance *) arg;
1746
1747
	if ( inst != NULL )
1748
	{
1749
		slapi_rwlock_rdlock(inst->rwl_config_lock);
1750
1751
		/* create the monitor entry if it is not there yet */
1752
		if (LDAP_SUCCESS == cb_config_add_dse_entries(inst->backend_type, cb_skeleton_entries,
1753
			inst->inst_name,CB_PLUGIN_NAME, NULL)) 
1754
		{
1755
1756
			/* add monitor callbacks */
1757
			slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, inst->monitorDn, LDAP_SCOPE_BASE,
1758
					"(objectclass=*)", cb_search_monitor_callback, (void *) inst);
1759
1760
			slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, inst->monitorDn, LDAP_SCOPE_BASE,
1761
					"(objectclass=*)", cb_dont_allow_that, (void *) NULL);
1762
1763
			slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP , inst->monitorDn, LDAP_SCOPE_BASE,
1764
					"(objectclass=*)", cb_delete_monitor_callback, (void *) inst);
1765
		}
1766
		slapi_rwlock_unlock(inst->rwl_config_lock);
1767
	}
1768
}
1769
1770
1771
int cb_instance_add_config_check_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* e2,
1772
       int *returncode, char *returntext, void *arg) {
1773
1774
       	int 			rc=LDAP_SUCCESS;
1775
	cb_backend_instance 	*inst;
1776
	cb_backend 		*cb=(cb_backend *) arg;
1777
        Slapi_Attr              *attr = NULL;
1778
        Slapi_Value             *sval;
1779
        const struct berval     *attrValue;
1780
	char 			*instname=NULL;
1781
1782
	if (returntext)
1783
		returntext[0]='\0';
1784
1785
	/* Basic entry check */
1786
        if ( 0 == slapi_entry_attr_find( e, CB_CONFIG_INSTNAME, &attr )) {
1787
                slapi_attr_first_value(attr, &sval);
1788
                attrValue = slapi_value_get_berval(sval);
1789
                instname=attrValue->bv_val;
1790
        }
1791
	if ( instname == NULL ) {
1792
                slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
1793
                        "Malformed backend instance (<%s> missing)>\n", CB_CONFIG_INSTNAME);
1794
				*returncode = LDAP_LOCAL_ERROR;
1795
                return SLAPI_DSE_CALLBACK_ERROR;
1796
        }
1797
1798
        /* Allocate a new backend internal data structure */
1799
        inst = cb_instance_alloc(cb,instname,slapi_entry_get_dn(e));
1800
1801
	/* build the backend instance from the default hardcoded conf,  */
1802
	/* the default instance config and the specific entry specified */
1803
	if ((rc=cb_build_backend_instance_config(inst,e,0))
1804
		!= LDAP_SUCCESS) {
1805
                slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
1806
                	"Can't instantiate chaining backend instance %s.\n",inst->inst_name);
1807
		*returncode=rc;
1808
                cb_instance_free(inst);
1809
                return SLAPI_DSE_CALLBACK_ERROR;
1810
        }
1811
1812
	/* Free the dummy instance */
1813
	*returncode=rc;
1814
        cb_instance_free(inst);
1815
1816
        return SLAPI_DSE_CALLBACK_OK;
1817
}
1818
 
1819
1820
/* Create the default instance config from hard-coded values */
1821
/*
1822
** Initialize the backend instance with the config entry 
1823
** passed in arguments.
1824
** <arg> : (cb_backend *)
1825
*/
1826
1827
int cb_instance_add_config_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* e2,
1828
       int *returncode, char *returntext, void *arg) {
1829
1830
       	int 			rc=LDAP_SUCCESS;
1831
	cb_backend_instance 	*inst;
1832
	cb_backend 		*cb=(cb_backend *) arg;
1833
        Slapi_Attr              *attr = NULL;
1834
        Slapi_Value             *sval;
1835
        const struct berval     *attrValue;
1836
	char 			*instname=NULL;
1837
1838
	if (returntext)
1839
		returntext[0]='\0';
1840
1841
	/* Basic entry check */
1842
        if ( 0 == slapi_entry_attr_find( e, CB_CONFIG_INSTNAME, &attr )) {
1843
                slapi_attr_first_value(attr, &sval);
1844
                attrValue = slapi_value_get_berval(sval);
1845
                instname=attrValue->bv_val;
1846
        }
1847
	if ( instname == NULL ) {
1848
                slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
1849
                        "Malformed backend instance (<%s> missing)>\n", CB_CONFIG_INSTNAME);
1850
				*returncode = LDAP_LOCAL_ERROR;
1851
                return SLAPI_DSE_CALLBACK_ERROR;
1852
        }
1853
1854
        /* Allocate a new backend internal data structure */
1855
        inst = cb_instance_alloc(cb,instname,slapi_entry_get_dn(e));
1856
1857
	/* build the backend instance from the default hardcoded conf,  */
1858
	/* the default instance config and the specific entry specified */
1859
	if ((rc=cb_build_backend_instance_config(inst,e,0))
1860
		!= LDAP_SUCCESS) {
1861
                slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
1862
                	"Can't instantiate chaining backend instance %s.\n",inst->inst_name);
1863
		*returncode=rc;
1864
                cb_instance_free(inst);
1865
                return SLAPI_DSE_CALLBACK_ERROR;
1866
        }
1867
1868
	/* Instantiate a Slapi_Backend if necessary */
1869
	if (!inst->isconfigured) {
1870
1871
		Slapi_PBlock 		*aPb=NULL;
1872
1873
        	inst->inst_be = slapi_be_new(CB_CHAINING_BACKEND_TYPE,inst->inst_name,0,0);
1874
        	aPb=slapi_pblock_new();
1875
        	slapi_pblock_set(aPb, SLAPI_PLUGIN, inst->backend_type->plugin);
1876
        	slapi_be_setentrypoint(inst->inst_be,0,(void *)NULL,aPb);
1877
        	slapi_be_set_instance_info(inst->inst_be,inst);
1878
        	slapi_pblock_set(aPb, SLAPI_PLUGIN, NULL);
1879
        	slapi_pblock_destroy(aPb);
1880
	}
1881
1882
	cb_build_backend_instance_config(inst,e,1);
1883
	
1884
	/* kexcoff: the order of the following calls is very important to prevent the deletion of the
1885
		instance to happen before the creation of the monitor part of the config.
1886
		However, not sure it solves all the situations, but at least it is worth to maintain
1887
		this order. */
1888
1889
	if (!inst->isconfigured) 
1890
	{ 
1891
		/* Add monitor entry and callback on it 
1892
		 * called from an add...
1893
		 * we can't call recursively into the DSE to do more adds, they'll
1894
		 * silently fail.  instead, schedule the adds to happen in 1 second.
1895
		 */
1896
		inst->eq_ctx = slapi_eq_once(cb_instance_add_monitor_later, (void *)inst, time(NULL)+1);
1897
	}
1898
1899
	/* Get the list of operational attrs defined in the schema */
1900
	/* see cb_search file for a reason for that		   */
1901
1902
	inst->every_attribute=slapi_schema_list_attribute_names(SLAPI_ATTR_FLAG_OPATTR);
1903
	charray_add(&inst->every_attribute,slapi_ch_strdup(LDAP_ALL_USER_ATTRS));
1904
1905
	if (!inst->isconfigured) 
1906
	{ 
1907
		slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, inst->configDn,
1908
		 LDAP_SCOPE_BASE,"(objectclass=*)",cb_instance_modify_config_check_callback, (void *) inst);
1909
		slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP, inst->configDn,
1910
		 LDAP_SCOPE_BASE,"(objectclass=*)",cb_instance_modify_config_callback, (void *) inst);
1911
1912
		slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, inst->configDn, 
1913
		LDAP_SCOPE_BASE,"(objectclass=*)", cb_instance_search_config_callback, (void *) inst);
1914
1915
		/* allow deletion otherwise impossible to remote a backend instance */
1916
		/* dynamically...							  */
1917
		slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, inst->configDn, 
1918
		LDAP_SCOPE_BASE,"(objectclass=*)", cb_instance_delete_config_callback, (void *) inst);
1919
	}
1920
1921
	/* Notify the front-end */
1922
	/* After the call below, we can receive ops */
1923
	slapi_mtn_be_started(inst->inst_be);
1924
1925
	inst->isconfigured=1;
1926
	return SLAPI_DSE_CALLBACK_OK;
1927
}
1928
 
1929
1930
/* Create the default instance config from hard-coded values */
1931
1932
int cb_create_default_backend_instance_config(cb_backend * cb) {
1933
1934
1935
	int 			rc;
1936
	cb_backend_instance 	*dummy;
1937
	Slapi_Entry 		*e=slapi_entry_alloc();
1938
	char            	*defaultDn;
1939
	char 			*olddn;
1940
        struct berval           val;
1941
        struct berval           *vals[2];
1942
	Slapi_PBlock 		*pb;
1943
1944
	dummy = cb_instance_alloc(cb, "dummy", "o=dummy");
1945
        cb_instance_config_set_default(dummy);
1946
	cb_instance_search_config_callback(NULL,e,NULL, &rc, NULL,(void *) dummy);
1947
1948
1949
	/* set right dn	 and objectclass */
1950
1951
	defaultDn = PR_smprintf("cn=default instance config,%s",cb->pluginDN);
1952
	olddn = slapi_entry_get_dn(e);
1953
	slapi_ch_free((void **) &olddn);
1954
	
1955
	slapi_entry_set_dn(e,slapi_ch_strdup(defaultDn));
1956
1957
 	vals[0] = &val;
1958
        vals[1] = NULL;
1959
1960
 	val.bv_val = "top";
1961
        val.bv_len = strlen( val.bv_val );
1962
        slapi_entry_attr_replace( e, "objectclass", (struct berval **)vals );
1963
        val.bv_val = CB_CONFIG_EXTENSIBLEOCL;
1964
        val.bv_len = strlen( val.bv_val );
1965
        slapi_entry_attr_merge( e, "objectclass", (struct berval **)vals );
1966
 	val.bv_val = "default instance config";
1967
        val.bv_len = strlen( val.bv_val );
1968
        slapi_entry_attr_replace( e, "cn", (struct berval **)vals );
1969
1970
	/* create entry */
1971
 	pb = slapi_pblock_new();
1972
        slapi_add_entry_internal_set_pb(pb, e, NULL, cb->identity, 0);
1973
	slapi_add_internal_pb(pb);
1974
	slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
1975
	if ( LDAP_SUCCESS != rc ) {
1976
	  slapi_log_error(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
1977
			  "Add %s failed (%s)\n",defaultDn,ldap_err2string(rc));
1978
	}
1979
1980
        slapi_pblock_destroy(pb); 
1981
	/* cleanup */
1982
        cb_instance_free(dummy);
1983
	/* BEWARE: entry is consummed */
1984
		PR_smprintf_free(defaultDn);
1985
	return rc;
1986
}
1987
1988
/* Extract backend instance configuration from the LDAP entry */
1989
1990
int cb_build_backend_instance_config(cb_backend_instance *inst, Slapi_Entry * conf, int apply) {
1991
1992
	cb_backend 	*cb = inst->backend_type;
1993
        Slapi_PBlock    *default_pb;
1994
	Slapi_Entry     **default_entries = NULL;
1995
	Slapi_Entry 	*default_conf=NULL;
1996
	int 		default_res, rc;
1997
	char 		*defaultDn;
1998
	cb_backend_instance * current_inst;
1999
2000
	rc=LDAP_SUCCESS;
2001
2002
	if (apply)
2003
		current_inst=inst;
2004
	else
2005
		current_inst=cb_instance_alloc(cb,inst->inst_name,"cn=dummy");
2006
2007
	/* set default configuration */
2008
	cb_instance_config_set_default(current_inst);
2009
2010
        /* 2: Overwrite values present in the default instance config */
2011
 
2012
        defaultDn = PR_smprintf("cn=default instance config,%s",cb->pluginDN);
2013
 
2014
        default_pb = slapi_pblock_new();
2015
        slapi_search_internal_set_pb(default_pb, defaultDn, LDAP_SCOPE_BASE,
2016
                "objectclass=*", NULL, 0, NULL, NULL, cb->identity, 0);
2017
        slapi_search_internal_pb (default_pb);
2018
		PR_smprintf_free(defaultDn);
2019
        slapi_pblock_get(default_pb, SLAPI_PLUGIN_INTOP_RESULT, &default_res);
2020
        if ( LDAP_SUCCESS == default_res ) {
2021
                slapi_pblock_get(default_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &default_entries);
2022
                if (default_entries && default_entries[0] ) {
2023
                               
2024
                        struct berval           val;
2025
                        struct berval           *vals[2];
2026
                        vals[0] = &val;
2027
                        vals[1] = NULL;
2028
                        default_conf=default_entries[0];
2029
 
2030
                        /* hack: add a dummy url (mandatory) to avoid error */
2031
                        /* will be overwritten by the one in conf entry     */
2032
                        val.bv_val = "ldap://localhost/";
2033
                        val.bv_len = strlen( val.bv_val );
2034
                        slapi_entry_attr_replace( default_conf, CB_CONFIG_HOSTURL, (struct berval **)vals );
2035
                                
2036
                        rc=cb_instance_config_initialize(current_inst,default_conf,CB_CONFIG_PHASE_STARTUP,1);
2037
                }
2038
        }
2039
        slapi_free_search_results_internal(default_pb);
2040
        slapi_pblock_destroy(default_pb);  
2041
2042
	if (rc == LDAP_SUCCESS)
2043
		rc=cb_instance_config_initialize(current_inst,conf,CB_CONFIG_PHASE_STARTUP,1);
2044
	
2045
	if (!apply)
2046
		cb_instance_free(current_inst);
2047
2048
	return rc;
2049
}