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