xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/slapi/slapi_pblock.c (revision c2f76ff004a2cb67efe5b12d97bd3ef7fe89e18d)
1 /*	$NetBSD: slapi_pblock.c,v 1.1.1.3 2010/12/12 15:23:53 adam Exp $	*/
2 
3 /* OpenLDAP: pkg/ldap/servers/slapd/slapi/slapi_pblock.c,v 1.63.2.11 2010/04/13 20:23:51 kurt Exp */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 2002-2010 The OpenLDAP Foundation.
7  * Portions Copyright 1997,2002-2003 IBM Corporation.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
14  * A copy of this license is available in the file LICENSE in the
15  * top-level directory of the distribution or, alternatively, at
16  * <http://www.OpenLDAP.org/license.html>.
17  */
18 /* ACKNOWLEDGEMENTS:
19  * This work was initially developed by IBM Corporation for use in
20  * IBM products and subsequently ported to OpenLDAP Software by
21  * Steve Omrani.  Additional significant contributors include:
22  *   Luke Howard
23  */
24 
25 #include "portable.h"
26 #include <slap.h>
27 #include <slapi.h>
28 
29 #ifdef LDAP_SLAPI
30 
31 /* some parameters require a valid connection and operation */
32 #define PBLOCK_LOCK_CONN( _pb )		do { \
33 		ldap_pvt_thread_mutex_lock( &(_pb)->pb_conn->c_mutex ); \
34 	} while (0)
35 
36 #define PBLOCK_UNLOCK_CONN( _pb )	do { \
37 		ldap_pvt_thread_mutex_unlock( &(_pb)->pb_conn->c_mutex ); \
38 	} while (0)
39 
40 /* some parameters are only settable for internal operations */
41 #define PBLOCK_VALIDATE_IS_INTOP( _pb )	do { if ( (_pb)->pb_intop == 0 ) break; } while ( 0 )
42 
43 static slapi_pblock_class_t
44 pblock_get_param_class( int param )
45 {
46 	switch ( param ) {
47 	case SLAPI_PLUGIN_TYPE:
48 	case SLAPI_PLUGIN_ARGC:
49 	case SLAPI_PLUGIN_OPRETURN:
50 	case SLAPI_PLUGIN_INTOP_RESULT:
51 	case SLAPI_CONFIG_LINENO:
52 	case SLAPI_CONFIG_ARGC:
53 	case SLAPI_BIND_METHOD:
54 	case SLAPI_MODRDN_DELOLDRDN:
55 	case SLAPI_SEARCH_SCOPE:
56 	case SLAPI_SEARCH_DEREF:
57 	case SLAPI_SEARCH_SIZELIMIT:
58 	case SLAPI_SEARCH_TIMELIMIT:
59 	case SLAPI_SEARCH_ATTRSONLY:
60 	case SLAPI_NENTRIES:
61 	case SLAPI_CHANGENUMBER:
62 	case SLAPI_DBSIZE:
63 	case SLAPI_REQUESTOR_ISROOT:
64 	case SLAPI_BE_READONLY:
65 	case SLAPI_BE_LASTMOD:
66 	case SLAPI_DB2LDIF_PRINTKEY:
67 	case SLAPI_LDIF2DB_REMOVEDUPVALS:
68 	case SLAPI_MANAGEDSAIT:
69 	case SLAPI_X_RELAX:
70 	case SLAPI_X_OPERATION_NO_SCHEMA_CHECK:
71 	case SLAPI_IS_REPLICATED_OPERATION:
72 	case SLAPI_X_CONN_IS_UDP:
73 	case SLAPI_X_CONN_SSF:
74 	case SLAPI_RESULT_CODE:
75 	case SLAPI_LOG_OPERATION:
76 	case SLAPI_IS_INTERNAL_OPERATION:
77 		return PBLOCK_CLASS_INTEGER;
78 		break;
79 
80 	case SLAPI_CONN_ID:
81 	case SLAPI_OPERATION_ID:
82 	case SLAPI_OPINITIATED_TIME:
83 	case SLAPI_ABANDON_MSGID:
84 	case SLAPI_X_OPERATION_DELETE_GLUE_PARENT:
85 	case SLAPI_OPERATION_MSGID:
86 		return PBLOCK_CLASS_LONG_INTEGER;
87 		break;
88 
89 	case SLAPI_PLUGIN_DESTROY_FN:
90 	case SLAPI_PLUGIN_DB_BIND_FN:
91 	case SLAPI_PLUGIN_DB_UNBIND_FN:
92 	case SLAPI_PLUGIN_DB_SEARCH_FN:
93 	case SLAPI_PLUGIN_DB_COMPARE_FN:
94 	case SLAPI_PLUGIN_DB_MODIFY_FN:
95 	case SLAPI_PLUGIN_DB_MODRDN_FN:
96 	case SLAPI_PLUGIN_DB_ADD_FN:
97 	case SLAPI_PLUGIN_DB_DELETE_FN:
98 	case SLAPI_PLUGIN_DB_ABANDON_FN:
99 	case SLAPI_PLUGIN_DB_CONFIG_FN:
100 	case SLAPI_PLUGIN_CLOSE_FN:
101 	case SLAPI_PLUGIN_DB_FLUSH_FN:
102 	case SLAPI_PLUGIN_START_FN:
103 	case SLAPI_PLUGIN_DB_SEQ_FN:
104 	case SLAPI_PLUGIN_DB_ENTRY_FN:
105 	case SLAPI_PLUGIN_DB_REFERRAL_FN:
106 	case SLAPI_PLUGIN_DB_RESULT_FN:
107 	case SLAPI_PLUGIN_DB_LDIF2DB_FN:
108 	case SLAPI_PLUGIN_DB_DB2LDIF_FN:
109 	case SLAPI_PLUGIN_DB_BEGIN_FN:
110 	case SLAPI_PLUGIN_DB_COMMIT_FN:
111 	case SLAPI_PLUGIN_DB_ABORT_FN:
112 	case SLAPI_PLUGIN_DB_ARCHIVE2DB_FN:
113 	case SLAPI_PLUGIN_DB_DB2ARCHIVE_FN:
114 	case SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN:
115 	case SLAPI_PLUGIN_DB_FREE_RESULT_SET_FN:
116 	case SLAPI_PLUGIN_DB_SIZE_FN:
117 	case SLAPI_PLUGIN_DB_TEST_FN:
118 	case SLAPI_PLUGIN_DB_NO_ACL:
119 	case SLAPI_PLUGIN_EXT_OP_FN:
120 	case SLAPI_PLUGIN_EXT_OP_OIDLIST:
121 	case SLAPI_PLUGIN_PRE_BIND_FN:
122 	case SLAPI_PLUGIN_PRE_UNBIND_FN:
123 	case SLAPI_PLUGIN_PRE_SEARCH_FN:
124 	case SLAPI_PLUGIN_PRE_COMPARE_FN:
125 	case SLAPI_PLUGIN_PRE_MODIFY_FN:
126 	case SLAPI_PLUGIN_PRE_MODRDN_FN:
127 	case SLAPI_PLUGIN_PRE_ADD_FN:
128 	case SLAPI_PLUGIN_PRE_DELETE_FN:
129 	case SLAPI_PLUGIN_PRE_ABANDON_FN:
130 	case SLAPI_PLUGIN_PRE_ENTRY_FN:
131 	case SLAPI_PLUGIN_PRE_REFERRAL_FN:
132 	case SLAPI_PLUGIN_PRE_RESULT_FN:
133 	case SLAPI_PLUGIN_INTERNAL_PRE_ADD_FN:
134 	case SLAPI_PLUGIN_INTERNAL_PRE_MODIFY_FN:
135 	case SLAPI_PLUGIN_INTERNAL_PRE_MODRDN_FN:
136 	case SLAPI_PLUGIN_INTERNAL_PRE_DELETE_FN:
137 	case SLAPI_PLUGIN_BE_PRE_ADD_FN:
138 	case SLAPI_PLUGIN_BE_PRE_MODIFY_FN:
139 	case SLAPI_PLUGIN_BE_PRE_MODRDN_FN:
140 	case SLAPI_PLUGIN_BE_PRE_DELETE_FN:
141 	case SLAPI_PLUGIN_POST_BIND_FN:
142 	case SLAPI_PLUGIN_POST_UNBIND_FN:
143 	case SLAPI_PLUGIN_POST_SEARCH_FN:
144 	case SLAPI_PLUGIN_POST_COMPARE_FN:
145 	case SLAPI_PLUGIN_POST_MODIFY_FN:
146 	case SLAPI_PLUGIN_POST_MODRDN_FN:
147 	case SLAPI_PLUGIN_POST_ADD_FN:
148 	case SLAPI_PLUGIN_POST_DELETE_FN:
149 	case SLAPI_PLUGIN_POST_ABANDON_FN:
150 	case SLAPI_PLUGIN_POST_ENTRY_FN:
151 	case SLAPI_PLUGIN_POST_REFERRAL_FN:
152 	case SLAPI_PLUGIN_POST_RESULT_FN:
153 	case SLAPI_PLUGIN_INTERNAL_POST_ADD_FN:
154 	case SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN:
155 	case SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN:
156 	case SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN:
157 	case SLAPI_PLUGIN_BE_POST_ADD_FN:
158 	case SLAPI_PLUGIN_BE_POST_MODIFY_FN:
159 	case SLAPI_PLUGIN_BE_POST_MODRDN_FN:
160 	case SLAPI_PLUGIN_BE_POST_DELETE_FN:
161 	case SLAPI_PLUGIN_MR_FILTER_CREATE_FN:
162 	case SLAPI_PLUGIN_MR_INDEXER_CREATE_FN:
163 	case SLAPI_PLUGIN_MR_FILTER_MATCH_FN:
164 	case SLAPI_PLUGIN_MR_FILTER_INDEX_FN:
165 	case SLAPI_PLUGIN_MR_FILTER_RESET_FN:
166 	case SLAPI_PLUGIN_MR_INDEX_FN:
167 	case SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN:
168 	case SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN:
169 	case SLAPI_PLUGIN_ACL_ALLOW_ACCESS:
170 	case SLAPI_X_PLUGIN_PRE_GROUP_FN:
171 	case SLAPI_X_PLUGIN_POST_GROUP_FN:
172 	case SLAPI_PLUGIN_AUDIT_FN:
173 	case SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN:
174 	case SLAPI_PLUGIN_INTERNAL_PRE_UNBIND_FN:
175 	case SLAPI_PLUGIN_INTERNAL_PRE_SEARCH_FN:
176 	case SLAPI_PLUGIN_INTERNAL_PRE_COMPARE_FN:
177 	case SLAPI_PLUGIN_INTERNAL_PRE_ABANDON_FN:
178 	case SLAPI_PLUGIN_INTERNAL_POST_BIND_FN:
179 	case SLAPI_PLUGIN_INTERNAL_POST_UNBIND_FN:
180 	case SLAPI_PLUGIN_INTERNAL_POST_SEARCH_FN:
181 	case SLAPI_PLUGIN_INTERNAL_POST_COMPARE_FN:
182 	case SLAPI_PLUGIN_INTERNAL_POST_ABANDON_FN:
183 		return PBLOCK_CLASS_FUNCTION_POINTER;
184 		break;
185 
186 	case SLAPI_BACKEND:
187 	case SLAPI_CONNECTION:
188 	case SLAPI_OPERATION:
189 	case SLAPI_OPERATION_PARAMETERS:
190 	case SLAPI_OPERATION_TYPE:
191 	case SLAPI_OPERATION_AUTHTYPE:
192 	case SLAPI_BE_MONITORDN:
193 	case SLAPI_BE_TYPE:
194 	case SLAPI_REQUESTOR_DN:
195 	case SLAPI_CONN_DN:
196 	case SLAPI_CONN_CLIENTIP:
197 	case SLAPI_CONN_SERVERIP:
198 	case SLAPI_CONN_AUTHTYPE:
199 	case SLAPI_CONN_AUTHMETHOD:
200 	case SLAPI_CONN_CERT:
201 	case SLAPI_X_CONN_CLIENTPATH:
202 	case SLAPI_X_CONN_SERVERPATH:
203 	case SLAPI_X_CONN_SASL_CONTEXT:
204 	case SLAPI_X_CONFIG_ARGV:
205 	case SLAPI_X_INTOP_FLAGS:
206 	case SLAPI_X_INTOP_RESULT_CALLBACK:
207 	case SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK:
208 	case SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK:
209 	case SLAPI_X_INTOP_CALLBACK_DATA:
210 	case SLAPI_PLUGIN_MR_OID:
211 	case SLAPI_PLUGIN_MR_TYPE:
212 	case SLAPI_PLUGIN_MR_VALUE:
213 	case SLAPI_PLUGIN_MR_VALUES:
214 	case SLAPI_PLUGIN_MR_KEYS:
215 	case SLAPI_PLUGIN:
216 	case SLAPI_PLUGIN_PRIVATE:
217 	case SLAPI_PLUGIN_ARGV:
218 	case SLAPI_PLUGIN_OBJECT:
219 	case SLAPI_PLUGIN_DESCRIPTION:
220 	case SLAPI_PLUGIN_IDENTITY:
221 	case SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES:
222 	case SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS:
223 	case SLAPI_PLUGIN_MR_FILTER_REUSABLE:
224 	case SLAPI_PLUGIN_MR_QUERY_OPERATOR:
225 	case SLAPI_PLUGIN_MR_USAGE:
226 	case SLAPI_OP_LESS:
227 	case SLAPI_OP_LESS_OR_EQUAL:
228 	case SLAPI_PLUGIN_MR_USAGE_INDEX:
229 	case SLAPI_PLUGIN_SYNTAX_FILTER_AVA:
230 	case SLAPI_PLUGIN_SYNTAX_FILTER_SUB:
231 	case SLAPI_PLUGIN_SYNTAX_VALUES2KEYS:
232 	case SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA:
233 	case SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB:
234 	case SLAPI_PLUGIN_SYNTAX_NAMES:
235 	case SLAPI_PLUGIN_SYNTAX_OID:
236 	case SLAPI_PLUGIN_SYNTAX_FLAGS:
237 	case SLAPI_PLUGIN_SYNTAX_COMPARE:
238 	case SLAPI_CONFIG_FILENAME:
239 	case SLAPI_CONFIG_ARGV:
240 	case SLAPI_TARGET_ADDRESS:
241 	case SLAPI_TARGET_UNIQUEID:
242 	case SLAPI_TARGET_DN:
243 	case SLAPI_REQCONTROLS:
244 	case SLAPI_ENTRY_PRE_OP:
245 	case SLAPI_ENTRY_POST_OP:
246 	case SLAPI_RESCONTROLS:
247 	case SLAPI_X_OLD_RESCONTROLS:
248 	case SLAPI_ADD_RESCONTROL:
249 	case SLAPI_CONTROLS_ARG:
250 	case SLAPI_ADD_ENTRY:
251 	case SLAPI_ADD_EXISTING_DN_ENTRY:
252 	case SLAPI_ADD_PARENT_ENTRY:
253 	case SLAPI_ADD_PARENT_UNIQUEID:
254 	case SLAPI_ADD_EXISTING_UNIQUEID_ENTRY:
255 	case SLAPI_BIND_CREDENTIALS:
256 	case SLAPI_BIND_SASLMECHANISM:
257 	case SLAPI_BIND_RET_SASLCREDS:
258 	case SLAPI_COMPARE_TYPE:
259 	case SLAPI_COMPARE_VALUE:
260 	case SLAPI_MODIFY_MODS:
261 	case SLAPI_MODRDN_NEWRDN:
262 	case SLAPI_MODRDN_NEWSUPERIOR:
263 	case SLAPI_MODRDN_PARENT_ENTRY:
264 	case SLAPI_MODRDN_NEWPARENT_ENTRY:
265 	case SLAPI_MODRDN_TARGET_ENTRY:
266 	case SLAPI_MODRDN_NEWSUPERIOR_ADDRESS:
267 	case SLAPI_SEARCH_FILTER:
268 	case SLAPI_SEARCH_STRFILTER:
269 	case SLAPI_SEARCH_ATTRS:
270 	case SLAPI_SEQ_TYPE:
271 	case SLAPI_SEQ_ATTRNAME:
272 	case SLAPI_SEQ_VAL:
273 	case SLAPI_EXT_OP_REQ_OID:
274 	case SLAPI_EXT_OP_REQ_VALUE:
275 	case SLAPI_EXT_OP_RET_OID:
276 	case SLAPI_EXT_OP_RET_VALUE:
277 	case SLAPI_MR_FILTER_ENTRY:
278 	case SLAPI_MR_FILTER_TYPE:
279 	case SLAPI_MR_FILTER_VALUE:
280 	case SLAPI_MR_FILTER_OID:
281 	case SLAPI_MR_FILTER_DNATTRS:
282 	case SLAPI_LDIF2DB_FILE:
283 	case SLAPI_PARENT_TXN:
284 	case SLAPI_TXN:
285 	case SLAPI_SEARCH_RESULT_SET:
286 	case SLAPI_SEARCH_RESULT_ENTRY:
287 	case SLAPI_SEARCH_REFERRALS:
288 	case SLAPI_RESULT_TEXT:
289 	case SLAPI_RESULT_MATCHED:
290 	case SLAPI_X_GROUP_ENTRY:
291 	case SLAPI_X_GROUP_ATTRIBUTE:
292 	case SLAPI_X_GROUP_OPERATION_DN:
293 	case SLAPI_X_GROUP_TARGET_ENTRY:
294 	case SLAPI_X_ADD_STRUCTURAL_CLASS:
295 	case SLAPI_PLUGIN_AUDIT_DATA:
296 	case SLAPI_IBM_PBLOCK:
297 	case SLAPI_PLUGIN_VERSION:
298 		return PBLOCK_CLASS_POINTER;
299 		break;
300 	default:
301 		break;
302 	}
303 
304 	return PBLOCK_CLASS_INVALID;
305 }
306 
307 static void
308 pblock_lock( Slapi_PBlock *pb )
309 {
310 	ldap_pvt_thread_mutex_lock( &pb->pb_mutex );
311 }
312 
313 static void
314 pblock_unlock( Slapi_PBlock *pb )
315 {
316 	ldap_pvt_thread_mutex_unlock( &pb->pb_mutex );
317 }
318 
319 static int
320 pblock_get_default( Slapi_PBlock *pb, int param, void **value )
321 {
322 	int i;
323 	slapi_pblock_class_t pbClass;
324 
325 	pbClass = pblock_get_param_class( param );
326 	if ( pbClass == PBLOCK_CLASS_INVALID ) {
327 		return PBLOCK_ERROR;
328 	}
329 
330 	switch ( pbClass ) {
331 	case PBLOCK_CLASS_INTEGER:
332 		*((int *)value) = 0;
333 		break;
334 	case PBLOCK_CLASS_LONG_INTEGER:
335 		*((long *)value) = 0L;
336 		break;
337 	case PBLOCK_CLASS_POINTER:
338 	case PBLOCK_CLASS_FUNCTION_POINTER:
339 		*value = NULL;
340 		break;
341 	case PBLOCK_CLASS_INVALID:
342 		return PBLOCK_ERROR;
343 	}
344 
345 	for ( i = 0; i < pb->pb_nParams; i++ ) {
346 		if ( pb->pb_params[i] == param ) {
347 			switch ( pbClass ) {
348 			case PBLOCK_CLASS_INTEGER:
349 				*((int *)value) = pb->pb_values[i].pv_integer;
350 				break;
351 			case PBLOCK_CLASS_LONG_INTEGER:
352 				*((long *)value) = pb->pb_values[i].pv_long_integer;
353 				break;
354 			case PBLOCK_CLASS_POINTER:
355 				*value = pb->pb_values[i].pv_pointer;
356 				break;
357 			case PBLOCK_CLASS_FUNCTION_POINTER:
358 				*value = pb->pb_values[i].pv_function_pointer;
359 				break;
360 			default:
361 				break;
362 			}
363 			break;
364 	  	}
365 	}
366 
367 	return PBLOCK_SUCCESS;
368 }
369 
370 static char *
371 pblock_get_authtype( AuthorizationInformation *authz, int is_tls )
372 {
373 	char *authType;
374 
375 	switch ( authz->sai_method ) {
376 	case LDAP_AUTH_SASL:
377 		authType = SLAPD_AUTH_SASL;
378 		break;
379 	case LDAP_AUTH_SIMPLE:
380 		authType = SLAPD_AUTH_SIMPLE;
381 		break;
382 	case LDAP_AUTH_NONE:
383 		authType = SLAPD_AUTH_NONE;
384 		break;
385 	default:
386 		authType = NULL;
387 		break;
388 	}
389 
390 	if ( is_tls && authType == NULL ) {
391 		authType = SLAPD_AUTH_SSL;
392 	}
393 
394 	return authType;
395 }
396 
397 static int
398 pblock_set_default( Slapi_PBlock *pb, int param, void *value )
399 {
400 	slapi_pblock_class_t pbClass;
401 	int i;
402 
403 	pbClass = pblock_get_param_class( param );
404 	if ( pbClass == PBLOCK_CLASS_INVALID ) {
405 		return PBLOCK_ERROR;
406 	}
407 
408 	if ( pb->pb_nParams == PBLOCK_MAX_PARAMS ) {
409 		return PBLOCK_ERROR;
410 	}
411 
412 	for ( i = 0; i < pb->pb_nParams; i++ ) {
413 		if ( pb->pb_params[i] == param )
414 			break;
415 	}
416 	if ( i >= pb->pb_nParams ) {
417 		pb->pb_params[i] = param;
418 	  	pb->pb_nParams++;
419 	}
420 
421 	switch ( pbClass ) {
422 	case PBLOCK_CLASS_INTEGER:
423 		pb->pb_values[i].pv_integer = (*((int *)value));
424 		break;
425 	case PBLOCK_CLASS_LONG_INTEGER:
426 		pb->pb_values[i].pv_long_integer = (*((long *)value));
427 		break;
428 	case PBLOCK_CLASS_POINTER:
429 		pb->pb_values[i].pv_pointer = value;
430 		break;
431 	case PBLOCK_CLASS_FUNCTION_POINTER:
432 		pb->pb_values[i].pv_function_pointer = value;
433 		break;
434 	default:
435 		break;
436 	}
437 
438 	return PBLOCK_SUCCESS;
439 }
440 
441 static int
442 pblock_be_call( Slapi_PBlock *pb, int (*bep)(Operation *) )
443 {
444 	BackendDB *be_orig;
445 	Operation *op;
446 	int rc;
447 
448 	PBLOCK_ASSERT_OP( pb, 0 );
449 	op = pb->pb_op;
450 
451 	be_orig = op->o_bd;
452 	op->o_bd = select_backend( &op->o_req_ndn, 0 );
453 	rc = (*bep)( op );
454 	op->o_bd = be_orig;
455 
456 	return rc;
457 }
458 
459 static int
460 pblock_get( Slapi_PBlock *pb, int param, void **value )
461 {
462 	int rc = PBLOCK_SUCCESS;
463 
464 	pblock_lock( pb );
465 
466 	switch ( param ) {
467 	case SLAPI_OPERATION:
468 		*value = pb->pb_op;
469 		break;
470 	case SLAPI_OPINITIATED_TIME:
471 		PBLOCK_ASSERT_OP( pb, 0 );
472 		*((long *)value) = pb->pb_op->o_time;
473 		break;
474 	case SLAPI_OPERATION_ID:
475 		PBLOCK_ASSERT_OP( pb, 0 );
476 		*((long *)value) = pb->pb_op->o_opid;
477 		break;
478 	case SLAPI_OPERATION_TYPE:
479 		PBLOCK_ASSERT_OP( pb, 0 );
480 		*((ber_tag_t *)value) = pb->pb_op->o_tag;
481 		break;
482 	case SLAPI_OPERATION_MSGID:
483 		PBLOCK_ASSERT_OP( pb, 0 );
484 		*((long *)value) = pb->pb_op->o_msgid;
485 		break;
486 	case SLAPI_X_OPERATION_DELETE_GLUE_PARENT:
487 		PBLOCK_ASSERT_OP( pb, 0 );
488 		*((int *)value) = pb->pb_op->o_delete_glue_parent;
489 		break;
490 	case SLAPI_X_OPERATION_NO_SCHEMA_CHECK:
491 		PBLOCK_ASSERT_OP( pb, 0 );
492 		*((int *)value) = get_no_schema_check( pb->pb_op );
493 		break;
494 	case SLAPI_X_ADD_STRUCTURAL_CLASS:
495 		PBLOCK_ASSERT_OP( pb, 0 );
496 
497 		if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
498 			struct berval tmpval = BER_BVNULL;
499 
500 			rc = mods_structural_class( pb->pb_op->ora_modlist,
501 				&tmpval, &pb->pb_rs->sr_text,
502 				pb->pb_textbuf, sizeof( pb->pb_textbuf ),
503 				pb->pb_op->o_tmpmemctx );
504 			*((char **)value) = tmpval.bv_val;
505 		} else {
506 			rc = PBLOCK_ERROR;
507 		}
508 		break;
509 	case SLAPI_X_OPERATION_NO_SUBORDINATE_GLUE:
510 		PBLOCK_ASSERT_OP( pb, 0 );
511 		*((int *)value) = pb->pb_op->o_no_subordinate_glue;
512 		break;
513 	case SLAPI_REQCONTROLS:
514 		PBLOCK_ASSERT_OP( pb, 0 );
515 		*((LDAPControl ***)value) = pb->pb_op->o_ctrls;
516 		break;
517 	case SLAPI_REQUESTOR_DN:
518 		PBLOCK_ASSERT_OP( pb, 0 );
519 		*((char **)value) = pb->pb_op->o_dn.bv_val;
520 		break;
521 	case SLAPI_MANAGEDSAIT:
522 		PBLOCK_ASSERT_OP( pb, 0 );
523 		*((int *)value) = get_manageDSAit( pb->pb_op );
524 		break;
525 	case SLAPI_X_RELAX:
526 		PBLOCK_ASSERT_OP( pb, 0 );
527 		*((int *)value) = get_relax( pb->pb_op );
528 		break;
529 	case SLAPI_BACKEND:
530 		PBLOCK_ASSERT_OP( pb, 0 );
531 		*((BackendDB **)value) = select_backend( &pb->pb_op->o_req_ndn, 0 );
532 		break;
533 	case SLAPI_BE_TYPE:
534 		PBLOCK_ASSERT_OP( pb, 0 );
535 		if ( pb->pb_op->o_bd != NULL )
536 			*((char **)value) = pb->pb_op->o_bd->bd_info->bi_type;
537 		else
538 			*value = NULL;
539 		break;
540 	case SLAPI_CONNECTION:
541 		*value = pb->pb_conn;
542 		break;
543 	case SLAPI_X_CONN_SSF:
544 		PBLOCK_ASSERT_OP( pb, 0 );
545 		*((slap_ssf_t *)value) = pb->pb_conn->c_ssf;
546 		break;
547 	case SLAPI_X_CONN_SASL_CONTEXT:
548 		PBLOCK_ASSERT_CONN( pb );
549 		if ( pb->pb_conn->c_sasl_authctx != NULL )
550 			*value = pb->pb_conn->c_sasl_authctx;
551 		else
552 			*value = pb->pb_conn->c_sasl_sockctx;
553 		break;
554 	case SLAPI_TARGET_DN:
555 		PBLOCK_ASSERT_OP( pb, 0 );
556 		*((char **)value) = pb->pb_op->o_req_dn.bv_val;
557 		break;
558 	case SLAPI_REQUESTOR_ISROOT:
559 		*((int *)value) = pblock_be_call( pb, be_isroot );
560 		break;
561 	case SLAPI_IS_REPLICATED_OPERATION:
562 		*((int *)value) = pblock_be_call( pb, be_slurp_update );
563 		break;
564 	case SLAPI_CONN_AUTHTYPE:
565 	case SLAPI_CONN_AUTHMETHOD: /* XXX should return SASL mech */
566 		PBLOCK_ASSERT_CONN( pb );
567 		*((char **)value) = pblock_get_authtype( &pb->pb_conn->c_authz,
568 #ifdef HAVE_TLS
569 							 pb->pb_conn->c_is_tls
570 #else
571 							 0
572 #endif
573 							 );
574 		break;
575 	case SLAPI_IS_INTERNAL_OPERATION:
576 		*((int *)value) = pb->pb_intop;
577 		break;
578 	case SLAPI_X_CONN_IS_UDP:
579 		PBLOCK_ASSERT_CONN( pb );
580 #ifdef LDAP_CONNECTIONLESS
581 		*((int *)value) = pb->pb_conn->c_is_udp;
582 #else
583 		*((int *)value) = 0;
584 #endif
585 		break;
586 	case SLAPI_CONN_ID:
587 		PBLOCK_ASSERT_CONN( pb );
588 		*((long *)value) = pb->pb_conn->c_connid;
589 		break;
590 	case SLAPI_CONN_DN:
591 		PBLOCK_ASSERT_CONN( pb );
592 #if 0
593 		/* This would be necessary to keep plugin compat after the fix in ITS#4158 */
594 		if ( pb->pb_op->o_tag == LDAP_REQ_BIND && pb->pb_rs->sr_err == LDAP_SUCCESS )
595 			*((char **)value) = pb->pb_op->orb_edn.bv_val;
596 		else
597 #endif
598 		*((char **)value) = pb->pb_conn->c_dn.bv_val;
599 		break;
600 	case SLAPI_CONN_CLIENTIP:
601 		PBLOCK_ASSERT_CONN( pb );
602 		if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "IP=", 3 ) == 0 )
603 			*((char **)value) = &pb->pb_conn->c_peer_name.bv_val[3];
604 		else
605 			*value = NULL;
606 		break;
607 	case SLAPI_X_CONN_CLIENTPATH:
608 		PBLOCK_ASSERT_CONN( pb );
609 		if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "PATH=", 3 ) == 0 )
610 			*((char **)value) = &pb->pb_conn->c_peer_name.bv_val[5];
611 		else
612 			*value = NULL;
613 		break;
614 	case SLAPI_CONN_SERVERIP:
615 		PBLOCK_ASSERT_CONN( pb );
616 		if ( strncmp( pb->pb_conn->c_sock_name.bv_val, "IP=", 3 ) == 0 )
617 			*((char **)value) = &pb->pb_conn->c_sock_name.bv_val[3];
618 		else
619 			*value = NULL;
620 		break;
621 	case SLAPI_X_CONN_SERVERPATH:
622 		PBLOCK_ASSERT_CONN( pb );
623 		if ( strncmp( pb->pb_conn->c_sock_name.bv_val, "PATH=", 3 ) == 0 )
624 			*((char **)value) = &pb->pb_conn->c_sock_name.bv_val[5];
625 		else
626 			*value = NULL;
627 		break;
628 	case SLAPI_RESULT_CODE:
629 	case SLAPI_PLUGIN_INTOP_RESULT:
630 		PBLOCK_ASSERT_OP( pb, 0 );
631 		*((int *)value) = pb->pb_rs->sr_err;
632 		break;
633         case SLAPI_RESULT_TEXT:
634 		PBLOCK_ASSERT_OP( pb, 0 );
635 		*((const char **)value) = pb->pb_rs->sr_text;
636 		break;
637         case SLAPI_RESULT_MATCHED:
638 		PBLOCK_ASSERT_OP( pb, 0 );
639 		*((const char **)value) = pb->pb_rs->sr_matched;
640 		break;
641 	case SLAPI_ADD_ENTRY:
642 		PBLOCK_ASSERT_OP( pb, 0 );
643 		if ( pb->pb_op->o_tag == LDAP_REQ_ADD )
644 			*((Slapi_Entry **)value) = pb->pb_op->ora_e;
645 		else
646 			*value = NULL;
647 		break;
648 	case SLAPI_MODIFY_MODS: {
649 		LDAPMod **mods = NULL;
650 		Modifications *ml = NULL;
651 
652 		pblock_get_default( pb, param, (void **)&mods );
653 		if ( mods == NULL && pb->pb_intop == 0 ) {
654 			switch ( pb->pb_op->o_tag ) {
655 			case LDAP_REQ_MODIFY:
656 				ml = pb->pb_op->orm_modlist;
657 				break;
658 			case LDAP_REQ_MODRDN:
659 				ml = pb->pb_op->orr_modlist;
660 				break;
661 			default:
662 				rc = PBLOCK_ERROR;
663 				break;
664 			}
665 			if ( rc != PBLOCK_ERROR ) {
666 				mods = slapi_int_modifications2ldapmods( ml );
667 				pblock_set_default( pb, param, (void *)mods );
668 			}
669 		}
670 		*((LDAPMod ***)value) = mods;
671 		break;
672 	}
673 	case SLAPI_MODRDN_NEWRDN:
674 		PBLOCK_ASSERT_OP( pb, 0 );
675 		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
676 			*((char **)value) = pb->pb_op->orr_newrdn.bv_val;
677 		else
678 			*value = NULL;
679 		break;
680 	case SLAPI_MODRDN_NEWSUPERIOR:
681 		PBLOCK_ASSERT_OP( pb, 0 );
682 		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN && pb->pb_op->orr_newSup != NULL )
683 			*((char **)value) = pb->pb_op->orr_newSup->bv_val;
684 		else
685 			*value = NULL;
686 		break;
687 	case SLAPI_MODRDN_DELOLDRDN:
688 		PBLOCK_ASSERT_OP( pb, 0 );
689 		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
690 			*((int *)value) = pb->pb_op->orr_deleteoldrdn;
691 		else
692 			*((int *)value) = 0;
693 		break;
694 	case SLAPI_SEARCH_SCOPE:
695 		PBLOCK_ASSERT_OP( pb, 0 );
696 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
697 			*((int *)value) = pb->pb_op->ors_scope;
698 		else
699 			*((int *)value) = 0;
700 		break;
701 	case SLAPI_SEARCH_DEREF:
702 		PBLOCK_ASSERT_OP( pb, 0 );
703 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
704 			*((int *)value) = pb->pb_op->ors_deref;
705 		else
706 			*((int *)value) = 0;
707 		break;
708 	case SLAPI_SEARCH_SIZELIMIT:
709 		PBLOCK_ASSERT_OP( pb, 0 );
710 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
711 			*((int *)value) = pb->pb_op->ors_slimit;
712 		else
713 			*((int *)value) = 0;
714 		break;
715 	case SLAPI_SEARCH_TIMELIMIT:
716 		PBLOCK_ASSERT_OP( pb, 0 );
717 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
718 			*((int *)value) = pb->pb_op->ors_tlimit;
719 		else
720 			*((int *)value) = 0;
721 		break;
722 	case SLAPI_SEARCH_FILTER:
723 		PBLOCK_ASSERT_OP( pb, 0 );
724 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
725 			*((Slapi_Filter **)value) = pb->pb_op->ors_filter;
726 		else
727 			*((Slapi_Filter **)value) = NULL;
728 		break;
729 	case SLAPI_SEARCH_STRFILTER:
730 		PBLOCK_ASSERT_OP( pb, 0 );
731 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
732 			*((char **)value) = pb->pb_op->ors_filterstr.bv_val;
733 		else
734 			*((char **)value) = NULL;
735 		break;
736 	case SLAPI_SEARCH_ATTRS: {
737 		char **attrs = NULL;
738 
739 		PBLOCK_ASSERT_OP( pb, 0 );
740 		if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) {
741 			rc = PBLOCK_ERROR;
742 			break;
743 		}
744 		pblock_get_default( pb, param, (void **)&attrs );
745 		if ( attrs == NULL && pb->pb_intop == 0 ) {
746 			attrs = anlist2charray_x( pb->pb_op->ors_attrs, 0, pb->pb_op->o_tmpmemctx );
747 			pblock_set_default( pb, param, (void *)attrs );
748 		}
749 		*((char ***)value) = attrs;
750 		break;
751 	}
752 	case SLAPI_SEARCH_ATTRSONLY:
753 		PBLOCK_ASSERT_OP( pb, 0 );
754 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
755 			*((int *)value) = pb->pb_op->ors_attrsonly;
756 		else
757 			*((int *)value) = 0;
758 		break;
759 	case SLAPI_SEARCH_RESULT_ENTRY:
760 		PBLOCK_ASSERT_OP( pb, 0 );
761 		*((Slapi_Entry **)value) = pb->pb_rs->sr_entry;
762 		break;
763 	case SLAPI_BIND_RET_SASLCREDS:
764 		PBLOCK_ASSERT_OP( pb, 0 );
765 		*((struct berval **)value) = pb->pb_rs->sr_sasldata;
766 		break;
767 	case SLAPI_EXT_OP_REQ_OID:
768 		*((const char **)value) = pb->pb_op->ore_reqoid.bv_val;
769 		break;
770 	case SLAPI_EXT_OP_REQ_VALUE:
771 		*((struct berval **)value) = pb->pb_op->ore_reqdata;
772 		break;
773 	case SLAPI_EXT_OP_RET_OID:
774 		PBLOCK_ASSERT_OP( pb, 0 );
775 		*((const char **)value) = pb->pb_rs->sr_rspoid;
776 		break;
777 	case SLAPI_EXT_OP_RET_VALUE:
778 		PBLOCK_ASSERT_OP( pb, 0 );
779 		*((struct berval **)value) = pb->pb_rs->sr_rspdata;
780 		break;
781 	case SLAPI_BIND_METHOD:
782 		if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
783 			*((int *)value) = pb->pb_op->orb_method;
784 		else
785 			*((int *)value) = 0;
786 		break;
787 	case SLAPI_BIND_CREDENTIALS:
788 		if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
789 			*((struct berval **)value) = &pb->pb_op->orb_cred;
790 		else
791 			*value = NULL;
792 		break;
793 	case SLAPI_COMPARE_TYPE:
794 		if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
795 			*((char **)value) = pb->pb_op->orc_ava->aa_desc->ad_cname.bv_val;
796 		else
797 			*value = NULL;
798 		break;
799 	case SLAPI_COMPARE_VALUE:
800 		if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
801 			*((struct berval **)value) = &pb->pb_op->orc_ava->aa_value;
802 		else
803 			*value = NULL;
804 		break;
805 	case SLAPI_ABANDON_MSGID:
806 		if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON )
807 			*((int *)value) = pb->pb_op->orn_msgid;
808 		else
809 			*((int *)value) = 0;
810 		break;
811 	default:
812 		rc = pblock_get_default( pb, param, value );
813 		break;
814 	}
815 
816 	pblock_unlock( pb );
817 
818 	return rc;
819 }
820 
821 static int
822 pblock_add_control( Slapi_PBlock *pb, LDAPControl *control )
823 {
824 	LDAPControl **controls = NULL;
825 	size_t i;
826 
827 	pblock_get_default( pb, SLAPI_RESCONTROLS, (void **)&controls );
828 
829 	if ( controls != NULL ) {
830 		for ( i = 0; controls[i] != NULL; i++ )
831 			;
832 	} else {
833 		i = 0;
834 	}
835 
836 	controls = (LDAPControl **)slapi_ch_realloc( (char *)controls,
837 		( i + 2 ) * sizeof(LDAPControl *));
838 	controls[i++] = slapi_dup_control( control );
839 	controls[i] = NULL;
840 
841 	return pblock_set_default( pb, SLAPI_RESCONTROLS, (void *)controls );
842 }
843 
844 static int
845 pblock_set_dn( void *value, struct berval *dn, struct berval *ndn, void *memctx )
846 {
847 	struct berval bv;
848 
849 	if ( !BER_BVISNULL( dn )) {
850 		slap_sl_free( dn->bv_val, memctx );
851 		BER_BVZERO( dn );
852 	}
853 	if ( !BER_BVISNULL( ndn )) {
854 		slap_sl_free( ndn->bv_val, memctx );
855 		BER_BVZERO( ndn );
856 	}
857 
858 	bv.bv_val = (char *)value;
859 	bv.bv_len = ( value != NULL ) ? strlen( bv.bv_val ) : 0;
860 
861 	return dnPrettyNormal( NULL, &bv, dn, ndn, memctx );
862 }
863 
864 static int
865 pblock_set( Slapi_PBlock *pb, int param, void *value )
866 {
867 	int rc = PBLOCK_SUCCESS;
868 
869 	pblock_lock( pb );
870 
871 	switch ( param ) {
872 	case SLAPI_OPERATION:
873 		pb->pb_op = (Operation *)value;
874 		break;
875 	case SLAPI_OPINITIATED_TIME:
876 		PBLOCK_ASSERT_OP( pb, 0 );
877 		pb->pb_op->o_time = *((long *)value);
878 		break;
879 	case SLAPI_OPERATION_ID:
880 		PBLOCK_ASSERT_OP( pb, 0 );
881 		pb->pb_op->o_opid = *((long *)value);
882 		break;
883 	case SLAPI_OPERATION_TYPE:
884 		PBLOCK_ASSERT_OP( pb, 0 );
885 		pb->pb_op->o_tag = *((ber_tag_t *)value);
886 		break;
887 	case SLAPI_OPERATION_MSGID:
888 		PBLOCK_ASSERT_OP( pb, 0 );
889 		pb->pb_op->o_msgid = *((long *)value);
890 		break;
891 	case SLAPI_X_OPERATION_DELETE_GLUE_PARENT:
892 		PBLOCK_ASSERT_OP( pb, 0 );
893 		pb->pb_op->o_delete_glue_parent = *((int *)value);
894 		break;
895 	case SLAPI_X_OPERATION_NO_SCHEMA_CHECK:
896 		PBLOCK_ASSERT_OP( pb, 0 );
897 		pb->pb_op->o_no_schema_check = *((int *)value);
898 		break;
899 	case SLAPI_X_OPERATION_NO_SUBORDINATE_GLUE:
900 		PBLOCK_ASSERT_OP( pb, 0 );
901 		pb->pb_op->o_no_subordinate_glue = *((int *)value);
902 		break;
903 	case SLAPI_REQCONTROLS:
904 		PBLOCK_ASSERT_OP( pb, 0 );
905 		pb->pb_op->o_ctrls = (LDAPControl **)value;
906 		break;
907 	case SLAPI_RESCONTROLS: {
908 		LDAPControl **ctrls = NULL;
909 
910 		pblock_get_default( pb, param, (void **)&ctrls );
911 		if ( ctrls != NULL ) {
912 			/* free old ones first */
913 			ldap_controls_free( ctrls );
914 		}
915 		rc = pblock_set_default( pb, param, value );
916 		break;
917 	}
918 	case SLAPI_ADD_RESCONTROL:
919 		PBLOCK_ASSERT_OP( pb, 0 );
920 		rc = pblock_add_control( pb, (LDAPControl *)value );
921 		break;
922 	case SLAPI_REQUESTOR_DN:
923 		PBLOCK_ASSERT_OP( pb, 0 );
924 		rc = pblock_set_dn( value, &pb->pb_op->o_dn, &pb->pb_op->o_ndn, pb->pb_op->o_tmpmemctx );
925 		break;
926 	case SLAPI_MANAGEDSAIT:
927 		PBLOCK_ASSERT_OP( pb, 0 );
928 		pb->pb_op->o_managedsait = *((int *)value);
929 		break;
930 	case SLAPI_X_RELAX:
931 		PBLOCK_ASSERT_OP( pb, 0 );
932 		pb->pb_op->o_relax = *((int *)value);
933 		break;
934 	case SLAPI_BACKEND:
935 		PBLOCK_ASSERT_OP( pb, 0 );
936 		pb->pb_op->o_bd = (BackendDB *)value;
937 		break;
938 	case SLAPI_CONNECTION:
939 		pb->pb_conn = (Connection *)value;
940 		break;
941 	case SLAPI_X_CONN_SSF:
942 		PBLOCK_ASSERT_CONN( pb );
943 		PBLOCK_LOCK_CONN( pb );
944 		pb->pb_conn->c_ssf = (slap_ssf_t)(long)value;
945 		PBLOCK_UNLOCK_CONN( pb );
946 		break;
947 	case SLAPI_X_CONN_SASL_CONTEXT:
948 		PBLOCK_ASSERT_CONN( pb );
949 		PBLOCK_LOCK_CONN( pb );
950 		pb->pb_conn->c_sasl_authctx = value;
951 		PBLOCK_UNLOCK_CONN( pb );
952 		break;
953 	case SLAPI_TARGET_DN:
954 		PBLOCK_ASSERT_OP( pb, 0 );
955 		rc = pblock_set_dn( value, &pb->pb_op->o_req_dn, &pb->pb_op->o_req_ndn, pb->pb_op->o_tmpmemctx );
956 		break;
957 	case SLAPI_CONN_ID:
958 		PBLOCK_ASSERT_CONN( pb );
959 		PBLOCK_LOCK_CONN( pb );
960 		pb->pb_conn->c_connid = *((long *)value);
961 		PBLOCK_UNLOCK_CONN( pb );
962 		break;
963 	case SLAPI_CONN_DN:
964 		PBLOCK_ASSERT_CONN( pb );
965 		PBLOCK_LOCK_CONN( pb );
966 		rc = pblock_set_dn( value, &pb->pb_conn->c_dn, &pb->pb_conn->c_ndn, NULL );
967 		PBLOCK_UNLOCK_CONN( pb );
968 		break;
969 	case SLAPI_RESULT_CODE:
970 	case SLAPI_PLUGIN_INTOP_RESULT:
971 		PBLOCK_ASSERT_OP( pb, 0 );
972 		pb->pb_rs->sr_err = *((int *)value);
973 		break;
974 	case SLAPI_RESULT_TEXT:
975 		PBLOCK_ASSERT_OP( pb, 0 );
976 		snprintf( pb->pb_textbuf, sizeof( pb->pb_textbuf ), "%s", (char *)value );
977 		pb->pb_rs->sr_text = pb->pb_textbuf;
978 		break;
979 	case SLAPI_RESULT_MATCHED:
980 		PBLOCK_ASSERT_OP( pb, 0 );
981 		pb->pb_rs->sr_matched = (char *)value; /* XXX should dup? */
982 		break;
983 	case SLAPI_ADD_ENTRY:
984 		PBLOCK_ASSERT_OP( pb, 0 );
985 		if ( pb->pb_op->o_tag == LDAP_REQ_ADD )
986 			pb->pb_op->ora_e = (Slapi_Entry *)value;
987 		else
988 			rc = PBLOCK_ERROR;
989 		break;
990 	case SLAPI_MODIFY_MODS: {
991 		Modifications **mlp;
992 		Modifications *newmods;
993 
994 		PBLOCK_ASSERT_OP( pb, 0 );
995 		rc = pblock_set_default( pb, param, value );
996 		if ( rc != PBLOCK_SUCCESS ) {
997 			break;
998 		}
999 
1000 		if ( pb->pb_op->o_tag == LDAP_REQ_MODIFY ) {
1001 			mlp = &pb->pb_op->orm_modlist;
1002 		} else if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
1003 			mlp = &pb->pb_op->ora_modlist;
1004 		} else if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
1005 			mlp = &pb->pb_op->orr_modlist;
1006 		} else {
1007 			break;
1008 		}
1009 
1010 		newmods = slapi_int_ldapmods2modifications( pb->pb_op, (LDAPMod **)value );
1011 		if ( newmods != NULL ) {
1012 			slap_mods_free( *mlp, 1 );
1013 			*mlp = newmods;
1014 		}
1015 		break;
1016 	}
1017 	case SLAPI_MODRDN_NEWRDN:
1018 		PBLOCK_ASSERT_OP( pb, 0 );
1019 		PBLOCK_VALIDATE_IS_INTOP( pb );
1020 		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
1021 			rc = pblock_set_dn( value, &pb->pb_op->orr_newrdn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx );
1022 			if ( rc == LDAP_SUCCESS )
1023 				rc = rdn_validate( &pb->pb_op->orr_nnewrdn );
1024 		} else {
1025 			rc = PBLOCK_ERROR;
1026 		}
1027 		break;
1028 	case SLAPI_MODRDN_NEWSUPERIOR:
1029 		PBLOCK_ASSERT_OP( pb, 0 );
1030 		PBLOCK_VALIDATE_IS_INTOP( pb );
1031 		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
1032 			if ( value == NULL ) {
1033 				if ( pb->pb_op->orr_newSup != NULL ) {
1034 					pb->pb_op->o_tmpfree( pb->pb_op->orr_newSup, pb->pb_op->o_tmpmemctx );
1035 					BER_BVZERO( pb->pb_op->orr_newSup );
1036 					pb->pb_op->orr_newSup = NULL;
1037 				}
1038 				if ( pb->pb_op->orr_newSup != NULL ) {
1039 					pb->pb_op->o_tmpfree( pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
1040 					BER_BVZERO( pb->pb_op->orr_nnewSup );
1041 					pb->pb_op->orr_nnewSup = NULL;
1042 				}
1043 			} else {
1044 				if ( pb->pb_op->orr_newSup == NULL ) {
1045 					pb->pb_op->orr_newSup = (struct berval *)pb->pb_op->o_tmpalloc(
1046 						sizeof(struct berval), pb->pb_op->o_tmpmemctx );
1047 					BER_BVZERO( pb->pb_op->orr_newSup );
1048 				}
1049 				if ( pb->pb_op->orr_nnewSup == NULL ) {
1050 					pb->pb_op->orr_nnewSup = (struct berval *)pb->pb_op->o_tmpalloc(
1051 						sizeof(struct berval), pb->pb_op->o_tmpmemctx );
1052 					BER_BVZERO( pb->pb_op->orr_nnewSup );
1053 				}
1054 				rc = pblock_set_dn( value, pb->pb_op->orr_newSup, pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
1055 			}
1056 		} else {
1057 			rc = PBLOCK_ERROR;
1058 		}
1059 		break;
1060 	case SLAPI_MODRDN_DELOLDRDN:
1061 		PBLOCK_ASSERT_OP( pb, 0 );
1062 		PBLOCK_VALIDATE_IS_INTOP( pb );
1063 		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
1064 			pb->pb_op->orr_deleteoldrdn = *((int *)value);
1065 		else
1066 			rc = PBLOCK_ERROR;
1067 		break;
1068 	case SLAPI_SEARCH_SCOPE: {
1069 		int scope = *((int *)value);
1070 
1071 		PBLOCK_ASSERT_OP( pb, 0 );
1072 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
1073 			switch ( *((int *)value) ) {
1074 			case LDAP_SCOPE_BASE:
1075 			case LDAP_SCOPE_ONELEVEL:
1076 			case LDAP_SCOPE_SUBTREE:
1077 			case LDAP_SCOPE_SUBORDINATE:
1078 				pb->pb_op->ors_scope = scope;
1079 				break;
1080 			default:
1081 				rc = PBLOCK_ERROR;
1082 				break;
1083 			}
1084 		} else {
1085 			rc = PBLOCK_ERROR;
1086 		}
1087 		break;
1088 	}
1089 	case SLAPI_SEARCH_DEREF:
1090 		PBLOCK_ASSERT_OP( pb, 0 );
1091 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1092 			pb->pb_op->ors_deref = *((int *)value);
1093 		else
1094 			rc = PBLOCK_ERROR;
1095 		break;
1096 	case SLAPI_SEARCH_SIZELIMIT:
1097 		PBLOCK_ASSERT_OP( pb, 0 );
1098 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1099 			pb->pb_op->ors_slimit = *((int *)value);
1100 		else
1101 			rc = PBLOCK_ERROR;
1102 		break;
1103 	case SLAPI_SEARCH_TIMELIMIT:
1104 		PBLOCK_ASSERT_OP( pb, 0 );
1105 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1106 			pb->pb_op->ors_tlimit = *((int *)value);
1107 		else
1108 			rc = PBLOCK_ERROR;
1109 		break;
1110 	case SLAPI_SEARCH_FILTER:
1111 		PBLOCK_ASSERT_OP( pb, 0 );
1112 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1113 			pb->pb_op->ors_filter = (Slapi_Filter *)value;
1114 		else
1115 			rc = PBLOCK_ERROR;
1116 		break;
1117 	case SLAPI_SEARCH_STRFILTER:
1118 		PBLOCK_ASSERT_OP( pb, 0 );
1119 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
1120 			pb->pb_op->ors_filterstr.bv_val = (char *)value;
1121 			pb->pb_op->ors_filterstr.bv_len = strlen((char *)value);
1122 		} else {
1123 			rc = PBLOCK_ERROR;
1124 		}
1125 		break;
1126 	case SLAPI_SEARCH_ATTRS: {
1127 		AttributeName *an = NULL;
1128 		size_t i = 0, j = 0;
1129 		char **attrs = (char **)value;
1130 
1131 		PBLOCK_ASSERT_OP( pb, 0 );
1132 		PBLOCK_VALIDATE_IS_INTOP( pb );
1133 
1134 		if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) {
1135 			rc = PBLOCK_ERROR;
1136 			break;
1137 		}
1138 		/* also set mapped attrs */
1139 		rc = pblock_set_default( pb, param, value );
1140 		if ( rc != PBLOCK_SUCCESS ) {
1141 			break;
1142 		}
1143 		if ( pb->pb_op->ors_attrs != NULL ) {
1144 			pb->pb_op->o_tmpfree( pb->pb_op->ors_attrs, pb->pb_op->o_tmpmemctx );
1145 			pb->pb_op->ors_attrs = NULL;
1146 		}
1147 		if ( attrs != NULL ) {
1148 			for ( i = 0; attrs[i] != NULL; i++ )
1149 				;
1150 		}
1151 		if ( i ) {
1152 			an = (AttributeName *)pb->pb_op->o_tmpcalloc( i + 1,
1153 				sizeof(AttributeName), pb->pb_op->o_tmpmemctx );
1154 			for ( i = 0; attrs[i] != NULL; i++ ) {
1155 				an[j].an_desc = NULL;
1156 				an[j].an_oc = NULL;
1157 				an[j].an_flags = 0;
1158 				an[j].an_name.bv_val = attrs[i];
1159 				an[j].an_name.bv_len = strlen( attrs[i] );
1160 				if ( slap_bv2ad( &an[j].an_name, &an[j].an_desc, &pb->pb_rs->sr_text ) == LDAP_SUCCESS ) {
1161 					j++;
1162 				}
1163 			}
1164 			an[j].an_name.bv_val = NULL;
1165 			an[j].an_name.bv_len = 0;
1166 		}
1167 		pb->pb_op->ors_attrs = an;
1168 		break;
1169 	}
1170 	case SLAPI_SEARCH_ATTRSONLY:
1171 		PBLOCK_ASSERT_OP( pb, 0 );
1172 		PBLOCK_VALIDATE_IS_INTOP( pb );
1173 
1174 		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1175 			pb->pb_op->ors_attrsonly = *((int *)value);
1176 		else
1177 			rc = PBLOCK_ERROR;
1178 		break;
1179 	case SLAPI_SEARCH_RESULT_ENTRY:
1180 		PBLOCK_ASSERT_OP( pb, 0 );
1181 		if ( pb->pb_rs->sr_flags & REP_ENTRY_MUSTBEFREED ) {
1182 			entry_free( pb->pb_rs->sr_entry );
1183 		} else if ( pb->pb_rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
1184 			be_entry_release_r( pb->pb_op, pb->pb_rs->sr_entry );
1185 			pb->pb_rs->sr_flags ^= REP_ENTRY_MUSTRELEASE;
1186 		}
1187 		pb->pb_rs->sr_entry = (Slapi_Entry *)value;
1188 		pb->pb_rs->sr_flags |= REP_ENTRY_MUSTBEFREED;
1189 		break;
1190 	case SLAPI_BIND_RET_SASLCREDS:
1191 		PBLOCK_ASSERT_OP( pb, 0 );
1192 		pb->pb_rs->sr_sasldata = (struct berval *)value;
1193 		break;
1194 	case SLAPI_EXT_OP_REQ_OID:
1195 		PBLOCK_ASSERT_OP( pb, 0 );
1196 		PBLOCK_VALIDATE_IS_INTOP( pb );
1197 
1198 		if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED ) {
1199 			pb->pb_op->ore_reqoid.bv_val = (char *)value;
1200 			pb->pb_op->ore_reqoid.bv_len = strlen((char *)value);
1201 		} else {
1202 			rc = PBLOCK_ERROR;
1203 		}
1204 		break;
1205 	case SLAPI_EXT_OP_REQ_VALUE:
1206 		PBLOCK_ASSERT_OP( pb, 0 );
1207 		PBLOCK_VALIDATE_IS_INTOP( pb );
1208 
1209 		if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED )
1210 			pb->pb_op->ore_reqdata = (struct berval *)value;
1211 		else
1212 			rc = PBLOCK_ERROR;
1213 		break;
1214 	case SLAPI_EXT_OP_RET_OID:
1215 		PBLOCK_ASSERT_OP( pb, 0 );
1216 		pb->pb_rs->sr_rspoid = (char *)value;
1217 		break;
1218 	case SLAPI_EXT_OP_RET_VALUE:
1219 		PBLOCK_ASSERT_OP( pb, 0 );
1220 		pb->pb_rs->sr_rspdata = (struct berval *)value;
1221 		break;
1222 	case SLAPI_BIND_METHOD:
1223 		PBLOCK_ASSERT_OP( pb, 0 );
1224 		PBLOCK_VALIDATE_IS_INTOP( pb );
1225 
1226 		if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
1227 			pb->pb_op->orb_method = *((int *)value);
1228 		else
1229 			rc = PBLOCK_ERROR;
1230 		break;
1231 	case SLAPI_BIND_CREDENTIALS:
1232 		PBLOCK_ASSERT_OP( pb, 0 );
1233 		PBLOCK_VALIDATE_IS_INTOP( pb );
1234 
1235 		if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
1236 			pb->pb_op->orb_cred = *((struct berval *)value);
1237 		else
1238 			rc = PBLOCK_ERROR;
1239 		break;
1240 	case SLAPI_COMPARE_TYPE:
1241 		PBLOCK_ASSERT_OP( pb, 0 );
1242 		PBLOCK_VALIDATE_IS_INTOP( pb );
1243 
1244 		if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) {
1245 			const char *text;
1246 
1247 			pb->pb_op->orc_ava->aa_desc = NULL;
1248 			rc = slap_str2ad( (char *)value, &pb->pb_op->orc_ava->aa_desc, &text );
1249 		} else {
1250 			rc = PBLOCK_ERROR;
1251 		}
1252 		break;
1253 	case SLAPI_COMPARE_VALUE:
1254 		PBLOCK_ASSERT_OP( pb, 0 );
1255 		PBLOCK_VALIDATE_IS_INTOP( pb );
1256 
1257 		if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
1258 			pb->pb_op->orc_ava->aa_value = *((struct berval *)value);
1259 		else
1260 			rc = PBLOCK_ERROR;
1261 		break;
1262 	case SLAPI_ABANDON_MSGID:
1263 		PBLOCK_ASSERT_OP( pb, 0 );
1264 		PBLOCK_VALIDATE_IS_INTOP( pb );
1265 
1266 		if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON)
1267 			pb->pb_op->orn_msgid = *((int *)value);
1268 		else
1269 			rc = PBLOCK_ERROR;
1270 		break;
1271 	case SLAPI_REQUESTOR_ISROOT:
1272 	case SLAPI_IS_REPLICATED_OPERATION:
1273 	case SLAPI_CONN_AUTHTYPE:
1274 	case SLAPI_CONN_AUTHMETHOD:
1275 	case SLAPI_IS_INTERNAL_OPERATION:
1276 	case SLAPI_X_CONN_IS_UDP:
1277 	case SLAPI_CONN_CLIENTIP:
1278 	case SLAPI_X_CONN_CLIENTPATH:
1279 	case SLAPI_CONN_SERVERIP:
1280 	case SLAPI_X_CONN_SERVERPATH:
1281 	case SLAPI_X_ADD_STRUCTURAL_CLASS:
1282 		/* These parameters cannot be set */
1283 		rc = PBLOCK_ERROR;
1284 		break;
1285 	default:
1286 		rc = pblock_set_default( pb, param, value );
1287 		break;
1288 	}
1289 
1290 	pblock_unlock( pb );
1291 
1292 	return rc;
1293 }
1294 
1295 static void
1296 pblock_clear( Slapi_PBlock *pb )
1297 {
1298 	pb->pb_nParams = 1;
1299 }
1300 
1301 static int
1302 pblock_delete_param( Slapi_PBlock *p, int param )
1303 {
1304 	int i;
1305 
1306 	pblock_lock(p);
1307 
1308 	for ( i = 0; i < p->pb_nParams; i++ ) {
1309 		if ( p->pb_params[i] == param ) {
1310 			break;
1311 		}
1312 	}
1313 
1314 	if (i >= p->pb_nParams ) {
1315 		pblock_unlock( p );
1316 		return PBLOCK_ERROR;
1317 	}
1318 
1319 	/* move last parameter to index of deleted parameter */
1320 	if ( p->pb_nParams > 1 ) {
1321 		p->pb_params[i] = p->pb_params[p->pb_nParams - 1];
1322 		p->pb_values[i] = p->pb_values[p->pb_nParams - 1];
1323 	}
1324 	p->pb_nParams--;
1325 
1326 	pblock_unlock( p );
1327 
1328 	return PBLOCK_SUCCESS;
1329 }
1330 
1331 Slapi_PBlock *
1332 slapi_pblock_new(void)
1333 {
1334 	Slapi_PBlock *pb;
1335 
1336 	pb = (Slapi_PBlock *) ch_calloc( 1, sizeof(Slapi_PBlock) );
1337 	if ( pb != NULL ) {
1338 		ldap_pvt_thread_mutex_init( &pb->pb_mutex );
1339 
1340 		pb->pb_params[0] = SLAPI_IBM_PBLOCK;
1341 		pb->pb_values[0].pv_pointer = NULL;
1342 		pb->pb_nParams = 1;
1343 		pb->pb_conn = NULL;
1344 		pb->pb_op = NULL;
1345 		pb->pb_rs = NULL;
1346 		pb->pb_intop = 0;
1347 	}
1348 	return pb;
1349 }
1350 
1351 static void
1352 pblock_destroy( Slapi_PBlock *pb )
1353 {
1354 	LDAPControl **controls = NULL;
1355 	LDAPMod **mods = NULL;
1356 	char **attrs = NULL;
1357 
1358 	assert( pb != NULL );
1359 
1360 	pblock_get_default( pb, SLAPI_RESCONTROLS, (void **)&controls );
1361 	if ( controls != NULL ) {
1362 		ldap_controls_free( controls );
1363 	}
1364 
1365 	if ( pb->pb_intop ) {
1366 		slapi_int_connection_done_pb( pb );
1367 	} else {
1368 		pblock_get_default( pb, SLAPI_MODIFY_MODS, (void **)&mods );
1369 		ldap_mods_free( mods, 1 );
1370 
1371 		pblock_get_default( pb, SLAPI_SEARCH_ATTRS, (void **)&attrs );
1372 		if ( attrs != NULL )
1373 			pb->pb_op->o_tmpfree( attrs, pb->pb_op->o_tmpmemctx );
1374 	}
1375 
1376 	ldap_pvt_thread_mutex_destroy( &pb->pb_mutex );
1377 	slapi_ch_free( (void **)&pb );
1378 }
1379 
1380 void
1381 slapi_pblock_destroy( Slapi_PBlock *pb )
1382 {
1383 	if ( pb != NULL ) {
1384 		pblock_destroy( pb );
1385 	}
1386 }
1387 
1388 int
1389 slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value )
1390 {
1391 	return pblock_get( pb, arg, (void **)value );
1392 }
1393 
1394 int
1395 slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value )
1396 {
1397 	return pblock_set( pb, arg, value );
1398 }
1399 
1400 void
1401 slapi_pblock_clear( Slapi_PBlock *pb )
1402 {
1403 	pblock_clear( pb );
1404 }
1405 
1406 int
1407 slapi_pblock_delete_param( Slapi_PBlock *p, int param )
1408 {
1409 	return pblock_delete_param( p, param );
1410 }
1411 
1412 /*
1413  * OpenLDAP extension
1414  */
1415 int
1416 slapi_int_pblock_get_first( Backend *be, Slapi_PBlock **pb )
1417 {
1418 	assert( pb != NULL );
1419 	*pb = SLAPI_BACKEND_PBLOCK( be );
1420 	return (*pb == NULL ? LDAP_OTHER : LDAP_SUCCESS);
1421 }
1422 
1423 /*
1424  * OpenLDAP extension
1425  */
1426 int
1427 slapi_int_pblock_get_next( Slapi_PBlock **pb )
1428 {
1429 	assert( pb != NULL );
1430 	return slapi_pblock_get( *pb, SLAPI_IBM_PBLOCK, pb );
1431 }
1432 
1433 #endif /* LDAP_SLAPI */
1434 
1435