]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_pblock.c
- setup framework for monitoring of back-bdb/back-hdb stuff in their
[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-2006 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         size_t 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, 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                         *((char **)value) = tmpval.bv_val;
502                 } else {
503                         rc = PBLOCK_ERROR;
504                 }
505                 break;
506         case SLAPI_X_OPERATION_NO_SUBORDINATE_GLUE:
507                 PBLOCK_ASSERT_OP( pb, 0 );
508                 *((int *)value) = pb->pb_op->o_no_subordinate_glue;
509                 break;
510         case SLAPI_REQCONTROLS:
511                 PBLOCK_ASSERT_OP( pb, 0 );
512                 *((LDAPControl ***)value) = pb->pb_op->o_ctrls;
513                 break;
514         case SLAPI_REQUESTOR_DN:
515                 PBLOCK_ASSERT_OP( pb, 0 );
516                 *((char **)value) = pb->pb_op->o_dn.bv_val;
517                 break;
518         case SLAPI_MANAGEDSAIT:
519                 PBLOCK_ASSERT_OP( pb, 0 );
520                 *((int *)value) = get_manageDSAit( pb->pb_op );
521                 break;
522         case SLAPI_X_RELAX:
523                 PBLOCK_ASSERT_OP( pb, 0 );
524                 *((int *)value) = get_relax( pb->pb_op );
525                 break;
526         case SLAPI_BACKEND:
527                 PBLOCK_ASSERT_OP( pb, 0 );
528                 *((BackendDB **)value) = select_backend( &pb->pb_op->o_req_ndn, 0, 0 );
529                 break;
530         case SLAPI_BE_TYPE:
531                 PBLOCK_ASSERT_OP( pb, 0 );
532                 if ( pb->pb_op->o_bd != NULL )
533                         *((char **)value) = pb->pb_op->o_bd->bd_info->bi_type;
534                 else
535                         *value = NULL;
536                 break;
537         case SLAPI_CONNECTION:
538                 *value = pb->pb_conn;
539                 break;
540         case SLAPI_X_CONN_SSF:
541                 PBLOCK_ASSERT_OP( pb, 0 );
542                 *((slap_ssf_t *)value) = pb->pb_conn->c_ssf;
543                 break;
544         case SLAPI_X_CONN_SASL_CONTEXT:
545                 PBLOCK_ASSERT_CONN( pb );
546                 if ( pb->pb_conn->c_sasl_authctx != NULL )
547                         *value = pb->pb_conn->c_sasl_authctx;
548                 else
549                         *value = pb->pb_conn->c_sasl_sockctx;
550                 break;
551         case SLAPI_TARGET_DN:
552                 PBLOCK_ASSERT_OP( pb, 0 );
553                 *((char **)value) = pb->pb_op->o_req_dn.bv_val;
554                 break;
555         case SLAPI_REQUESTOR_ISROOT:
556                 *((int *)value) = pblock_be_call( pb, be_isroot );
557                 break;
558         case SLAPI_IS_REPLICATED_OPERATION:
559                 *((int *)value) = pblock_be_call( pb, be_slurp_update );
560                 break;
561         case SLAPI_CONN_AUTHTYPE:
562         case SLAPI_CONN_AUTHMETHOD: /* XXX should return SASL mech */
563                 PBLOCK_ASSERT_CONN( pb );
564                 *((char **)value) = pblock_get_authtype( &pb->pb_conn->c_authz,
565 #ifdef HAVE_TLS
566                                                          pb->pb_conn->c_is_tls
567 #else
568                                                          0
569 #endif
570                                                          );
571                 break;
572         case SLAPI_IS_INTERNAL_OPERATION:
573                 *((int *)value) = pb->pb_intop;
574                 break;
575         case SLAPI_X_CONN_IS_UDP:
576                 PBLOCK_ASSERT_CONN( pb );
577 #ifdef LDAP_CONNECTIONLESS
578                 *((int *)value) = pb->pb_conn->c_is_udp;
579 #else
580                 *((int *)value) = 0;
581 #endif
582                 break;
583         case SLAPI_CONN_ID:
584                 PBLOCK_ASSERT_CONN( pb );
585                 *((long *)value) = pb->pb_conn->c_connid;
586                 break;
587         case SLAPI_CONN_DN:
588                 PBLOCK_ASSERT_CONN( pb );
589 #if 0
590                 /* This would be necessary to keep plugin compat after the fix in ITS#4158 */
591                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND && pb->pb_rs->sr_err == LDAP_SUCCESS )
592                         *((char **)value) = pb->pb_op->orb_edn.bv_val;
593                 else
594 #endif
595                 *((char **)value) = pb->pb_conn->c_dn.bv_val;
596                 break;
597         case SLAPI_CONN_CLIENTIP:
598                 PBLOCK_ASSERT_CONN( pb );
599                 if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "IP=", 3 ) == 0 )
600                         *((char **)value) = &pb->pb_conn->c_peer_name.bv_val[3];
601                 else
602                         *value = NULL;
603                 break;
604         case SLAPI_X_CONN_CLIENTPATH:
605                 PBLOCK_ASSERT_CONN( pb );
606                 if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "PATH=", 3 ) == 0 )
607                         *((char **)value) = &pb->pb_conn->c_peer_name.bv_val[5];
608                 else
609                         *value = NULL;
610                 break;
611         case SLAPI_CONN_SERVERIP:
612                 PBLOCK_ASSERT_CONN( pb );
613                 if ( strncmp( pb->pb_conn->c_sock_name.bv_val, "IP=", 3 ) == 0 )
614                         *((char **)value) = &pb->pb_conn->c_sock_name.bv_val[3];
615                 else
616                         *value = NULL;
617                 break;
618         case SLAPI_X_CONN_SERVERPATH:
619                 PBLOCK_ASSERT_CONN( pb );
620                 if ( strncmp( pb->pb_conn->c_sock_name.bv_val, "PATH=", 3 ) == 0 )
621                         *((char **)value) = &pb->pb_conn->c_sock_name.bv_val[5];
622                 else
623                         *value = NULL;
624                 break;
625         case SLAPI_RESULT_CODE:
626         case SLAPI_PLUGIN_INTOP_RESULT:
627                 PBLOCK_ASSERT_OP( pb, 0 );
628                 *((int *)value) = pb->pb_rs->sr_err;
629                 break;
630         case SLAPI_RESULT_TEXT:
631                 PBLOCK_ASSERT_OP( pb, 0 );
632                 *((const char **)value) = pb->pb_rs->sr_text;
633                 break;
634         case SLAPI_RESULT_MATCHED:
635                 PBLOCK_ASSERT_OP( pb, 0 );
636                 *((const char **)value) = pb->pb_rs->sr_matched;
637                 break;
638         case SLAPI_ADD_ENTRY:
639                 PBLOCK_ASSERT_OP( pb, 0 );
640                 if ( pb->pb_op->o_tag == LDAP_REQ_ADD )
641                         *((Slapi_Entry **)value) = pb->pb_op->ora_e;
642                 else
643                         *value = NULL;
644                 break;
645         case SLAPI_MODIFY_MODS: {
646                 LDAPMod **mods = NULL;
647                 Modifications *ml = NULL;
648
649                 pblock_get_default( pb, param, (void **)&mods );
650                 if ( mods == NULL && pb->pb_intop == 0 ) {
651                         switch ( pb->pb_op->o_tag ) {
652                         case LDAP_REQ_MODIFY:
653                                 ml = pb->pb_op->orm_modlist;
654                                 break;
655                         case LDAP_REQ_MODRDN:
656                                 ml = pb->pb_op->orr_modlist;
657                                 break;
658                         default:
659                                 rc = PBLOCK_ERROR;
660                                 break;
661                         }
662                         if ( rc != PBLOCK_ERROR ) {
663                                 mods = slapi_int_modifications2ldapmods( ml );
664                                 pblock_set_default( pb, param, (void *)mods );
665                         }
666                 }
667                 *((LDAPMod ***)value) = mods;
668                 break;
669         }
670         case SLAPI_MODRDN_NEWRDN:
671                 PBLOCK_ASSERT_OP( pb, 0 );
672                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
673                         *((char **)value) = pb->pb_op->orr_newrdn.bv_val;
674                 else
675                         *value = NULL;
676                 break;
677         case SLAPI_MODRDN_NEWSUPERIOR:
678                 PBLOCK_ASSERT_OP( pb, 0 );
679                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN && pb->pb_op->orr_newSup != NULL )
680                         *((char **)value) = pb->pb_op->orr_newSup->bv_val;
681                 else
682                         *value = NULL;
683                 break;
684         case SLAPI_MODRDN_DELOLDRDN:
685                 PBLOCK_ASSERT_OP( pb, 0 );
686                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
687                         *((int *)value) = pb->pb_op->orr_deleteoldrdn;
688                 else
689                         *((int *)value) = 0;
690                 break;
691         case SLAPI_SEARCH_SCOPE:
692                 PBLOCK_ASSERT_OP( pb, 0 );
693                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
694                         *((int *)value) = pb->pb_op->ors_scope;
695                 else
696                         *((int *)value) = 0;
697                 break;
698         case SLAPI_SEARCH_DEREF:
699                 PBLOCK_ASSERT_OP( pb, 0 );
700                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
701                         *((int *)value) = pb->pb_op->ors_deref;
702                 else
703                         *((int *)value) = 0;
704                 break;
705         case SLAPI_SEARCH_SIZELIMIT:
706                 PBLOCK_ASSERT_OP( pb, 0 );
707                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
708                         *((int *)value) = pb->pb_op->ors_slimit;
709                 else
710                         *((int *)value) = 0;
711                 break;
712         case SLAPI_SEARCH_TIMELIMIT:
713                 PBLOCK_ASSERT_OP( pb, 0 );
714                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
715                         *((int *)value) = pb->pb_op->ors_tlimit;
716                 else
717                         *((int *)value) = 0;
718                 break;
719         case SLAPI_SEARCH_FILTER:
720                 PBLOCK_ASSERT_OP( pb, 0 );
721                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
722                         *((Slapi_Filter **)value) = pb->pb_op->ors_filter;
723                 else
724                         *((Slapi_Filter **)value) = NULL;
725                 break;
726         case SLAPI_SEARCH_STRFILTER:
727                 PBLOCK_ASSERT_OP( pb, 0 );
728                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
729                         *((char **)value) = pb->pb_op->ors_filterstr.bv_val;
730                 else
731                         *((char **)value) = NULL;
732                 break;
733         case SLAPI_SEARCH_ATTRS: {
734                 char **attrs = NULL;
735
736                 PBLOCK_ASSERT_OP( pb, 0 );
737                 if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) {
738                         rc = PBLOCK_ERROR;
739                         break;
740                 }
741                 pblock_get_default( pb, param, (void **)&attrs );
742                 if ( attrs == NULL && pb->pb_intop == 0 ) {
743                         attrs = anlist2charray_x( pb->pb_op->ors_attrs, 0, pb->pb_op->o_tmpmemctx );
744                         pblock_set_default( pb, param, (void *)attrs );
745                 }
746                 *((char ***)value) = attrs;
747                 break;
748         }
749         case SLAPI_SEARCH_ATTRSONLY:
750                 PBLOCK_ASSERT_OP( pb, 0 );
751                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
752                         *((int *)value) = pb->pb_op->ors_attrsonly;
753                 else
754                         *((int *)value) = 0;
755                 break;
756         case SLAPI_SEARCH_RESULT_ENTRY:
757                 PBLOCK_ASSERT_OP( pb, 0 );
758                 *((Slapi_Entry **)value) = pb->pb_rs->sr_entry;
759                 break;
760         case SLAPI_BIND_RET_SASLCREDS:
761                 PBLOCK_ASSERT_OP( pb, 0 );
762                 *((struct berval **)value) = pb->pb_rs->sr_sasldata;
763                 break;
764         case SLAPI_EXT_OP_REQ_OID:
765                 *((const char **)value) = pb->pb_op->ore_reqoid.bv_val;
766                 break;
767         case SLAPI_EXT_OP_REQ_VALUE:
768                 *((struct berval **)value) = pb->pb_op->ore_reqdata;
769                 break;
770         case SLAPI_EXT_OP_RET_OID:
771                 PBLOCK_ASSERT_OP( pb, 0 );
772                 *((const char **)value) = pb->pb_rs->sr_rspoid;
773                 break;
774         case SLAPI_EXT_OP_RET_VALUE:
775                 PBLOCK_ASSERT_OP( pb, 0 );
776                 *((struct berval **)value) = pb->pb_rs->sr_rspdata;
777                 break;
778         case SLAPI_BIND_METHOD:
779                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
780                         *((int *)value) = pb->pb_op->orb_method;
781                 else
782                         *((int *)value) = 0;
783                 break;
784         case SLAPI_BIND_CREDENTIALS:
785                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
786                         *((struct berval **)value) = &pb->pb_op->orb_cred;
787                 else
788                         *value = NULL;
789                 break;
790         case SLAPI_COMPARE_TYPE:
791                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
792                         *((char **)value) = pb->pb_op->orc_ava->aa_desc->ad_cname.bv_val;
793                 else
794                         *value = NULL;
795                 break;
796         case SLAPI_COMPARE_VALUE:
797                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
798                         *((struct berval **)value) = &pb->pb_op->orc_ava->aa_value;
799                 else
800                         *value = NULL;
801                 break;
802         case SLAPI_ABANDON_MSGID:
803                 if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON )
804                         *((int *)value) = pb->pb_op->orn_msgid;
805                 else
806                         *((int *)value) = 0;
807                 break;
808         default:
809                 rc = pblock_get_default( pb, param, value );
810                 break;
811         }
812
813         pblock_unlock( pb );
814
815         return rc;
816 }
817
818 static int
819 pblock_add_control( Slapi_PBlock *pb, LDAPControl *control )
820 {
821         LDAPControl **controls = NULL;
822         size_t i;
823
824         pblock_get_default( pb, SLAPI_RESCONTROLS, (void **)&controls );
825
826         if ( controls != NULL ) {
827                 for ( i = 0; controls[i] != NULL; i++ )
828                         ;
829         } else {
830                 i = 0;
831         }
832
833         controls = (LDAPControl **)slapi_ch_realloc( (char *)controls,
834                 ( i + 2 ) * sizeof(LDAPControl *));
835         controls[i++] = slapi_dup_control( control );
836         controls[i] = NULL;
837
838         return pblock_set_default( pb, SLAPI_RESCONTROLS, (void *)controls );
839 }
840
841 static int
842 pblock_set_dn( void *value, struct berval *dn, struct berval *ndn, void *memctx )
843 {
844         struct berval bv;
845
846         if ( !BER_BVISNULL( dn )) {
847                 slap_sl_free( dn->bv_val, memctx );
848                 BER_BVZERO( dn );
849         }
850         if ( !BER_BVISNULL( ndn )) {
851                 slap_sl_free( ndn->bv_val, memctx );
852                 BER_BVZERO( ndn );
853         }
854
855         bv.bv_val = (char *)value;
856         bv.bv_len = ( value != NULL ) ? strlen( bv.bv_val ) : 0;
857
858         return dnPrettyNormal( NULL, &bv, dn, ndn, memctx );
859 }
860
861 static int 
862 pblock_set( Slapi_PBlock *pb, int param, void *value ) 
863 {
864         int rc = PBLOCK_SUCCESS;
865
866         pblock_lock( pb );      
867
868         switch ( param ) {
869         case SLAPI_OPERATION:
870                 pb->pb_op = (Operation *)value;
871                 break;
872         case SLAPI_OPINITIATED_TIME:
873                 PBLOCK_ASSERT_OP( pb, 0 );
874                 pb->pb_op->o_time = *((long *)value);
875                 break;
876         case SLAPI_OPERATION_ID:
877                 PBLOCK_ASSERT_OP( pb, 0 );
878                 pb->pb_op->o_opid = *((long *)value);
879                 break;
880         case SLAPI_OPERATION_TYPE:
881                 PBLOCK_ASSERT_OP( pb, 0 );
882                 pb->pb_op->o_tag = *((ber_tag_t *)value);
883                 break;
884         case SLAPI_OPERATION_MSGID:
885                 PBLOCK_ASSERT_OP( pb, 0 );
886                 pb->pb_op->o_msgid = *((long *)value);
887                 break;
888         case SLAPI_X_OPERATION_DELETE_GLUE_PARENT:
889                 PBLOCK_ASSERT_OP( pb, 0 );
890                 pb->pb_op->o_delete_glue_parent = *((int *)value);
891                 break;
892         case SLAPI_X_OPERATION_NO_SCHEMA_CHECK:
893                 PBLOCK_ASSERT_OP( pb, 0 );
894                 pb->pb_op->o_no_schema_check = *((int *)value);
895                 break;
896         case SLAPI_X_OPERATION_NO_SUBORDINATE_GLUE:
897                 PBLOCK_ASSERT_OP( pb, 0 );
898                 pb->pb_op->o_no_subordinate_glue = *((int *)value);
899                 break;
900         case SLAPI_REQCONTROLS:
901                 PBLOCK_ASSERT_OP( pb, 0 );
902                 pb->pb_op->o_ctrls = (LDAPControl **)value;
903                 break;
904         case SLAPI_RESCONTROLS: {
905                 LDAPControl **ctrls = NULL;
906
907                 pblock_get_default( pb, param, (void **)&ctrls );
908                 if ( ctrls != NULL ) {
909                         /* free old ones first */
910                         ldap_controls_free( ctrls );
911                 }
912                 rc = pblock_set_default( pb, param, value );
913                 break;
914         }
915         case SLAPI_ADD_RESCONTROL:
916                 PBLOCK_ASSERT_OP( pb, 0 );
917                 rc = pblock_add_control( pb, (LDAPControl *)value );
918                 break;
919         case SLAPI_REQUESTOR_DN:
920                 PBLOCK_ASSERT_OP( pb, 0 );
921                 rc = pblock_set_dn( value, &pb->pb_op->o_dn, &pb->pb_op->o_ndn, pb->pb_op->o_tmpmemctx );
922                 break;
923         case SLAPI_MANAGEDSAIT:
924                 PBLOCK_ASSERT_OP( pb, 0 );
925                 pb->pb_op->o_managedsait = *((int *)value);
926                 break;
927         case SLAPI_X_RELAX:
928                 PBLOCK_ASSERT_OP( pb, 0 );
929                 pb->pb_op->o_relax = *((int *)value);
930                 break;
931         case SLAPI_BACKEND:
932                 PBLOCK_ASSERT_OP( pb, 0 );
933                 pb->pb_op->o_bd = (BackendDB *)value;
934                 break;
935         case SLAPI_CONNECTION:
936                 pb->pb_conn = (Connection *)value;
937                 break;
938         case SLAPI_X_CONN_SSF:
939                 PBLOCK_ASSERT_CONN( pb );
940                 PBLOCK_LOCK_CONN( pb );
941                 pb->pb_conn->c_ssf = (slap_ssf_t)(long)value;
942                 PBLOCK_UNLOCK_CONN( pb );
943                 break;
944         case SLAPI_X_CONN_SASL_CONTEXT:
945                 PBLOCK_ASSERT_CONN( pb );
946                 PBLOCK_LOCK_CONN( pb );
947                 pb->pb_conn->c_sasl_authctx = value;
948                 PBLOCK_UNLOCK_CONN( pb );
949                 break;
950         case SLAPI_TARGET_DN:
951                 PBLOCK_ASSERT_OP( pb, 0 );
952                 rc = pblock_set_dn( value, &pb->pb_op->o_req_dn, &pb->pb_op->o_req_ndn, pb->pb_op->o_tmpmemctx );
953                 break;
954         case SLAPI_CONN_ID:
955                 PBLOCK_ASSERT_CONN( pb );
956                 PBLOCK_LOCK_CONN( pb );
957                 pb->pb_conn->c_connid = *((long *)value);
958                 PBLOCK_UNLOCK_CONN( pb );
959                 break;
960         case SLAPI_CONN_DN:
961                 PBLOCK_ASSERT_CONN( pb );
962                 PBLOCK_LOCK_CONN( pb );
963                 rc = pblock_set_dn( value, &pb->pb_conn->c_dn, &pb->pb_conn->c_ndn, NULL );
964                 PBLOCK_UNLOCK_CONN( pb );
965                 break;
966         case SLAPI_RESULT_CODE:
967         case SLAPI_PLUGIN_INTOP_RESULT:
968                 PBLOCK_ASSERT_OP( pb, 0 );
969                 pb->pb_rs->sr_err = *((int *)value);
970                 break;
971         case SLAPI_RESULT_TEXT:
972                 PBLOCK_ASSERT_OP( pb, 0 );
973                 snprintf( pb->pb_textbuf, sizeof( pb->pb_textbuf ), "%s", (char *)value );
974                 pb->pb_rs->sr_text = pb->pb_textbuf;
975                 break;
976         case SLAPI_RESULT_MATCHED:
977                 PBLOCK_ASSERT_OP( pb, 0 );
978                 pb->pb_rs->sr_matched = (char *)value; /* XXX should dup? */
979                 break;
980         case SLAPI_ADD_ENTRY:
981                 PBLOCK_ASSERT_OP( pb, 0 );
982                 if ( pb->pb_op->o_tag == LDAP_REQ_ADD )
983                         pb->pb_op->ora_e = (Slapi_Entry *)value;
984                 else
985                         rc = PBLOCK_ERROR;
986                 break;
987         case SLAPI_MODIFY_MODS: {
988                 Modifications **mlp;
989                 Modifications *newmods;
990
991                 PBLOCK_ASSERT_OP( pb, 0 );
992                 rc = pblock_set_default( pb, param, value );
993                 if ( rc != PBLOCK_SUCCESS ) {
994                         break;
995                 }
996
997                 if ( pb->pb_op->o_tag == LDAP_REQ_MODIFY ) {
998                         mlp = &pb->pb_op->orm_modlist;
999                 } else if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
1000                         mlp = &pb->pb_op->ora_modlist;
1001                 } else if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
1002                         mlp = &pb->pb_op->orr_modlist;
1003                 } else {
1004                         break;
1005                 }
1006
1007                 newmods = slapi_int_ldapmods2modifications( (LDAPMod **)value );
1008                 if ( newmods != NULL ) {
1009                         slap_mods_free( *mlp, 1 );
1010                         *mlp = newmods;
1011                 }
1012                 break;
1013         }
1014         case SLAPI_MODRDN_NEWRDN:
1015                 PBLOCK_ASSERT_OP( pb, 0 );
1016                 PBLOCK_VALIDATE_IS_INTOP( pb );
1017                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
1018                         rc = pblock_set_dn( value, &pb->pb_op->orr_newrdn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx );
1019                         if ( rc == LDAP_SUCCESS )
1020                                 rc = rdn_validate( &pb->pb_op->orr_nnewrdn );
1021                 } else {
1022                         rc = PBLOCK_ERROR;
1023                 }
1024                 break;
1025         case SLAPI_MODRDN_NEWSUPERIOR:
1026                 PBLOCK_ASSERT_OP( pb, 0 );
1027                 PBLOCK_VALIDATE_IS_INTOP( pb );
1028                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
1029                         if ( value == NULL ) {
1030                                 if ( pb->pb_op->orr_newSup != NULL ) {
1031                                         pb->pb_op->o_tmpfree( pb->pb_op->orr_newSup, pb->pb_op->o_tmpmemctx );
1032                                         BER_BVZERO( pb->pb_op->orr_newSup );
1033                                         pb->pb_op->orr_newSup = NULL;
1034                                 }
1035                                 if ( pb->pb_op->orr_newSup != NULL ) {
1036                                         pb->pb_op->o_tmpfree( pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
1037                                         BER_BVZERO( pb->pb_op->orr_nnewSup );
1038                                         pb->pb_op->orr_nnewSup = NULL;
1039                                 }
1040                         } else {
1041                                 if ( pb->pb_op->orr_newSup == NULL ) {
1042                                         pb->pb_op->orr_newSup = (struct berval *)pb->pb_op->o_tmpalloc(
1043                                                 sizeof(struct berval), pb->pb_op->o_tmpmemctx );
1044                                         BER_BVZERO( pb->pb_op->orr_newSup );
1045                                 }
1046                                 if ( pb->pb_op->orr_nnewSup == NULL ) {
1047                                         pb->pb_op->orr_nnewSup = (struct berval *)pb->pb_op->o_tmpalloc(
1048                                                 sizeof(struct berval), pb->pb_op->o_tmpmemctx );
1049                                         BER_BVZERO( pb->pb_op->orr_nnewSup );
1050                                 }
1051                                 rc = pblock_set_dn( value, pb->pb_op->orr_newSup, pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
1052                         }
1053                 } else {
1054                         rc = PBLOCK_ERROR;
1055                 }
1056                 break;
1057         case SLAPI_MODRDN_DELOLDRDN:
1058                 PBLOCK_ASSERT_OP( pb, 0 );
1059                 PBLOCK_VALIDATE_IS_INTOP( pb );
1060                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
1061                         pb->pb_op->orr_deleteoldrdn = *((int *)value);
1062                 else
1063                         rc = PBLOCK_ERROR;
1064                 break;
1065         case SLAPI_SEARCH_SCOPE: {
1066                 int scope = *((int *)value);
1067
1068                 PBLOCK_ASSERT_OP( pb, 0 );
1069                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
1070                         switch ( *((int *)value) ) {
1071                         case LDAP_SCOPE_BASE:
1072                         case LDAP_SCOPE_ONELEVEL:
1073                         case LDAP_SCOPE_SUBTREE:
1074                         case LDAP_SCOPE_SUBORDINATE:
1075                                 pb->pb_op->ors_scope = scope;
1076                                 break;
1077                         default:
1078                                 rc = PBLOCK_ERROR;
1079                                 break;
1080                         }
1081                 } else {
1082                         rc = PBLOCK_ERROR;
1083                 }
1084                 break;
1085         }
1086         case SLAPI_SEARCH_DEREF:
1087                 PBLOCK_ASSERT_OP( pb, 0 );
1088                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1089                         pb->pb_op->ors_deref = *((int *)value);
1090                 else
1091                         rc = PBLOCK_ERROR;
1092                 break;
1093         case SLAPI_SEARCH_SIZELIMIT:
1094                 PBLOCK_ASSERT_OP( pb, 0 );
1095                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1096                         pb->pb_op->ors_slimit = *((int *)value);
1097                 else
1098                         rc = PBLOCK_ERROR;
1099                 break;
1100         case SLAPI_SEARCH_TIMELIMIT:
1101                 PBLOCK_ASSERT_OP( pb, 0 );
1102                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1103                         pb->pb_op->ors_tlimit = *((int *)value);
1104                 else
1105                         rc = PBLOCK_ERROR;
1106                 break;
1107         case SLAPI_SEARCH_FILTER:
1108                 PBLOCK_ASSERT_OP( pb, 0 );
1109                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1110                         pb->pb_op->ors_filter = (Slapi_Filter *)value;
1111                 else
1112                         rc = PBLOCK_ERROR;
1113                 break;
1114         case SLAPI_SEARCH_STRFILTER:
1115                 PBLOCK_ASSERT_OP( pb, 0 );
1116                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
1117                         pb->pb_op->ors_filterstr.bv_val = (char *)value;
1118                         pb->pb_op->ors_filterstr.bv_len = strlen((char *)value);
1119                 } else {
1120                         rc = PBLOCK_ERROR;
1121                 }
1122                 break;
1123         case SLAPI_SEARCH_ATTRS: {
1124                 AttributeName *an = NULL;
1125                 size_t i = 0, j = 0;
1126                 char **attrs = (char **)value;
1127
1128                 PBLOCK_ASSERT_OP( pb, 0 );
1129                 PBLOCK_VALIDATE_IS_INTOP( pb );
1130
1131                 if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) {
1132                         rc = PBLOCK_ERROR;
1133                         break;
1134                 }
1135                 /* also set mapped attrs */
1136                 rc = pblock_set_default( pb, param, value );
1137                 if ( rc != PBLOCK_SUCCESS ) {
1138                         break;
1139                 }
1140                 if ( pb->pb_op->ors_attrs != NULL ) {
1141                         pb->pb_op->o_tmpfree( pb->pb_op->ors_attrs, pb->pb_op->o_tmpmemctx );
1142                         pb->pb_op->ors_attrs = NULL;
1143                 }
1144                 if ( attrs != NULL ) {
1145                         for ( i = 0; attrs[i] != NULL; i++ )
1146                                 ;
1147                 }
1148                 if ( i ) {
1149                         an = (AttributeName *)pb->pb_op->o_tmpcalloc( i + 1,
1150                                 sizeof(AttributeName), pb->pb_op->o_tmpmemctx );
1151                         for ( i = 0; attrs[i] != NULL; i++ ) {
1152                                 an[j].an_desc = NULL;
1153                                 an[j].an_oc = NULL;
1154                                 an[j].an_oc_exclude = 0;
1155                                 an[j].an_name.bv_val = attrs[i];
1156                                 an[j].an_name.bv_len = strlen( attrs[i] );
1157                                 if ( slap_bv2ad( &an[j].an_name, &an[j].an_desc, &pb->pb_rs->sr_text ) == LDAP_SUCCESS ) {
1158                                         j++;
1159                                 }
1160                         }
1161                         an[j].an_name.bv_val = NULL;
1162                         an[j].an_name.bv_len = 0;
1163                 }       
1164                 pb->pb_op->ors_attrs = an;
1165                 break;
1166         }
1167         case SLAPI_SEARCH_ATTRSONLY:
1168                 PBLOCK_ASSERT_OP( pb, 0 );
1169                 PBLOCK_VALIDATE_IS_INTOP( pb );
1170
1171                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1172                         pb->pb_op->ors_attrsonly = *((int *)value);
1173                 else
1174                         rc = PBLOCK_ERROR;
1175                 break;
1176         case SLAPI_SEARCH_RESULT_ENTRY:
1177                 PBLOCK_ASSERT_OP( pb, 0 );
1178                 pb->pb_rs->sr_entry = (Slapi_Entry *)value;
1179                 break;
1180         case SLAPI_BIND_RET_SASLCREDS:
1181                 PBLOCK_ASSERT_OP( pb, 0 );
1182                 pb->pb_rs->sr_sasldata = (struct berval *)value;
1183                 break;
1184         case SLAPI_EXT_OP_REQ_OID:
1185                 PBLOCK_ASSERT_OP( pb, 0 );
1186                 PBLOCK_VALIDATE_IS_INTOP( pb );
1187
1188                 if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED ) {
1189                         pb->pb_op->ore_reqoid.bv_val = (char *)value;
1190                         pb->pb_op->ore_reqoid.bv_len = strlen((char *)value);
1191                 } else {
1192                         rc = PBLOCK_ERROR;
1193                 }
1194                 break;
1195         case SLAPI_EXT_OP_REQ_VALUE:
1196                 PBLOCK_ASSERT_OP( pb, 0 );
1197                 PBLOCK_VALIDATE_IS_INTOP( pb );
1198
1199                 if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED )
1200                         pb->pb_op->ore_reqdata = (struct berval *)value;
1201                 else
1202                         rc = PBLOCK_ERROR;
1203                 break;
1204         case SLAPI_EXT_OP_RET_OID:
1205                 PBLOCK_ASSERT_OP( pb, 0 );
1206                 pb->pb_rs->sr_rspoid = (char *)value;
1207                 break;
1208         case SLAPI_EXT_OP_RET_VALUE:
1209                 PBLOCK_ASSERT_OP( pb, 0 );
1210                 pb->pb_rs->sr_rspdata = (struct berval *)value;
1211                 break;
1212         case SLAPI_BIND_METHOD:
1213                 PBLOCK_ASSERT_OP( pb, 0 );
1214                 PBLOCK_VALIDATE_IS_INTOP( pb );
1215
1216                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
1217                         pb->pb_op->orb_method = *((int *)value);
1218                 else
1219                         rc = PBLOCK_ERROR;
1220                 break;
1221         case SLAPI_BIND_CREDENTIALS:
1222                 PBLOCK_ASSERT_OP( pb, 0 );
1223                 PBLOCK_VALIDATE_IS_INTOP( pb );
1224
1225                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
1226                         pb->pb_op->orb_cred = *((struct berval *)value);
1227                 else
1228                         rc = PBLOCK_ERROR;
1229                 break;
1230         case SLAPI_COMPARE_TYPE:
1231                 PBLOCK_ASSERT_OP( pb, 0 );
1232                 PBLOCK_VALIDATE_IS_INTOP( pb );
1233
1234                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) {
1235                         const char *text;
1236
1237                         pb->pb_op->orc_ava->aa_desc = NULL;
1238                         rc = slap_str2ad( (char *)value, &pb->pb_op->orc_ava->aa_desc, &text );
1239                 } else {
1240                         rc = PBLOCK_ERROR;
1241                 }
1242                 break;
1243         case SLAPI_COMPARE_VALUE:
1244                 PBLOCK_ASSERT_OP( pb, 0 );
1245                 PBLOCK_VALIDATE_IS_INTOP( pb );
1246
1247                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
1248                         pb->pb_op->orc_ava->aa_value = *((struct berval *)value);
1249                 else
1250                         rc = PBLOCK_ERROR;
1251                 break;
1252         case SLAPI_ABANDON_MSGID:
1253                 PBLOCK_ASSERT_OP( pb, 0 );
1254                 PBLOCK_VALIDATE_IS_INTOP( pb );
1255
1256                 if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON)
1257                         pb->pb_op->orn_msgid = *((int *)value);
1258                 else
1259                         rc = PBLOCK_ERROR;
1260                 break;
1261         case SLAPI_REQUESTOR_ISROOT:
1262         case SLAPI_IS_REPLICATED_OPERATION:
1263         case SLAPI_CONN_AUTHTYPE:
1264         case SLAPI_CONN_AUTHMETHOD:
1265         case SLAPI_IS_INTERNAL_OPERATION:
1266         case SLAPI_X_CONN_IS_UDP:
1267         case SLAPI_CONN_CLIENTIP:
1268         case SLAPI_X_CONN_CLIENTPATH:
1269         case SLAPI_CONN_SERVERIP:
1270         case SLAPI_X_CONN_SERVERPATH:
1271         case SLAPI_X_ADD_STRUCTURAL_CLASS:
1272                 /* These parameters cannot be set */
1273                 rc = PBLOCK_ERROR;
1274                 break;
1275         default:
1276                 rc = pblock_set_default( pb, param, value );
1277                 break;
1278         }
1279
1280         pblock_unlock( pb );
1281
1282         return rc;
1283 }
1284
1285 static void
1286 pblock_clear( Slapi_PBlock *pb ) 
1287 {
1288         pb->pb_nParams = 1;
1289 }
1290
1291 static int
1292 pblock_delete_param( Slapi_PBlock *p, int param ) 
1293 {
1294         int i;
1295
1296         pblock_lock(p);
1297
1298         for ( i = 0; i < p->pb_nParams; i++ ) { 
1299                 if ( p->pb_params[i] == param ) {
1300                         break;
1301                 }
1302         }
1303     
1304         if (i >= p->pb_nParams ) {
1305                 pblock_unlock( p );
1306                 return PBLOCK_ERROR;
1307         }
1308
1309         /* move last parameter to index of deleted parameter */
1310         if ( p->pb_nParams > 1 ) {
1311                 p->pb_params[i] = p->pb_params[p->pb_nParams - 1];
1312                 p->pb_values[i] = p->pb_values[p->pb_nParams - 1];
1313         }
1314         p->pb_nParams--;
1315
1316         pblock_unlock( p );     
1317
1318         return PBLOCK_SUCCESS;
1319 }
1320
1321 Slapi_PBlock *
1322 slapi_pblock_new(void) 
1323 {
1324         Slapi_PBlock *pb;
1325
1326         pb = (Slapi_PBlock *) ch_calloc( 1, sizeof(Slapi_PBlock) );
1327         if ( pb != NULL ) {
1328                 ldap_pvt_thread_mutex_init( &pb->pb_mutex );
1329
1330                 pb->pb_params[0] = SLAPI_IBM_PBLOCK;
1331                 pb->pb_values[0].pv_pointer = NULL;
1332                 pb->pb_nParams = 1;
1333                 pb->pb_conn = NULL;
1334                 pb->pb_op = NULL;
1335                 pb->pb_rs = NULL;
1336                 pb->pb_intop = 0;
1337         }
1338         return pb;
1339 }
1340
1341 static void
1342 pblock_destroy( Slapi_PBlock *pb )
1343 {
1344         LDAPControl **controls = NULL;
1345         LDAPMod **mods = NULL;
1346         char **attrs = NULL;
1347
1348         assert( pb != NULL );
1349
1350         pblock_get_default( pb, SLAPI_RESCONTROLS, (void **)&controls );
1351         if ( controls != NULL ) {
1352                 ldap_controls_free( controls );
1353         }
1354
1355         if ( pb->pb_intop ) {
1356                 slapi_int_connection_done_pb( pb );
1357         } else {
1358                 pblock_get_default( pb, SLAPI_MODIFY_MODS, (void **)&mods );
1359                 ldap_mods_free( mods, 1 );
1360
1361                 pblock_get_default( pb, SLAPI_SEARCH_ATTRS, (void **)&attrs );
1362                 if ( attrs != NULL )
1363                         pb->pb_op->o_tmpfree( attrs, pb->pb_op->o_tmpmemctx );
1364         }
1365
1366         ldap_pvt_thread_mutex_destroy( &pb->pb_mutex );
1367         slapi_ch_free( (void **)&pb ); 
1368 }
1369
1370 void 
1371 slapi_pblock_destroy( Slapi_PBlock *pb ) 
1372 {
1373         if ( pb != NULL ) {
1374                 pblock_destroy( pb );
1375         }
1376 }
1377
1378 int 
1379 slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value ) 
1380 {
1381         return pblock_get( pb, arg, (void **)value );
1382 }
1383
1384 int 
1385 slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value ) 
1386 {
1387         return pblock_set( pb, arg, value );
1388 }
1389
1390 void
1391 slapi_pblock_clear( Slapi_PBlock *pb ) 
1392 {
1393         pblock_clear( pb );
1394 }
1395
1396 int 
1397 slapi_pblock_delete_param( Slapi_PBlock *p, int param ) 
1398 {
1399         return pblock_delete_param( p, param );
1400 }
1401
1402 /*
1403  * OpenLDAP extension
1404  */
1405 int
1406 slapi_int_pblock_get_first( Backend *be, Slapi_PBlock **pb )
1407 {
1408         assert( pb != NULL );
1409         *pb = SLAPI_BACKEND_PBLOCK( be );
1410         return (*pb == NULL ? LDAP_OTHER : LDAP_SUCCESS);
1411 }
1412
1413 /*
1414  * OpenLDAP extension
1415  */
1416 int
1417 slapi_int_pblock_get_next( Slapi_PBlock **pb )
1418 {
1419         assert( pb != NULL );
1420         return slapi_pblock_get( *pb, SLAPI_IBM_PBLOCK, pb );
1421 }
1422
1423 #endif /* LDAP_SLAPI */
1424