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 |
}
|