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