]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_pblock.c
05ad0c23ef3002b9ba5cfc9500276db00db33a74
[openldap] / servers / slapd / slapi / slapi_pblock.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2002-2017 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 
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
306 pblock_lock( Slapi_PBlock *pb )
307 {
308         ldap_pvt_thread_mutex_lock( &pb->pb_mutex );
309 }
310
311 static void
312 pblock_unlock( Slapi_PBlock *pb )
313 {
314         ldap_pvt_thread_mutex_unlock( &pb->pb_mutex );
315 }
316
317 static int 
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 *
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 
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
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 
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
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
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 
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
1289 pblock_clear( Slapi_PBlock *pb ) 
1290 {
1291         pb->pb_nParams = 1;
1292 }
1293
1294 static int
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 *
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
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 
1374 slapi_pblock_destroy( Slapi_PBlock *pb ) 
1375 {
1376         if ( pb != NULL ) {
1377                 pblock_destroy( pb );
1378         }
1379 }
1380
1381 int 
1382 slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value ) 
1383 {
1384         return pblock_get( pb, arg, (void **)value );
1385 }
1386
1387 int 
1388 slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value ) 
1389 {
1390         return pblock_set( pb, arg, value );
1391 }
1392
1393 void
1394 slapi_pblock_clear( Slapi_PBlock *pb ) 
1395 {
1396         pblock_clear( pb );
1397 }
1398
1399 int 
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
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
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 */