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