]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_pblock.c
Add ability to cache negative results and specify negative TTL on templates
[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_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_X_ADD_STRUCTURAL_CLASS:
281         case SLAPI_PLUGIN_AUDIT_DATA:
282         case SLAPI_IBM_PBLOCK:
283         case SLAPI_PLUGIN_VERSION:
284                 return PBLOCK_CLASS_POINTER;
285                 break;
286         default:
287                 break;
288         }
289
290         return PBLOCK_CLASS_INVALID;
291 }
292
293 static void
294 pblock_lock( Slapi_PBlock *pb )
295 {
296         ldap_pvt_thread_mutex_lock(&pb->pb_mutex);
297 }
298
299 static void
300 pblock_unlock( Slapi_PBlock *pb )
301 {
302         ldap_pvt_thread_mutex_unlock(&pb->pb_mutex);
303 }
304
305 static int 
306 pblock_get_default( Slapi_PBlock *pb, int param, void **value ) 
307 {       
308         int i;
309         slapi_pblock_class_t pbClass;
310
311         pbClass = pblock_get_param_class( param );
312         if ( pbClass == PBLOCK_CLASS_INVALID ) {
313                 return PBLOCK_ERROR;
314         }
315         
316         switch ( pbClass ) {
317         case PBLOCK_CLASS_INTEGER:
318                 *((int *)value) = 0;
319                 break;
320         case PBLOCK_CLASS_LONG_INTEGER:
321                 *((long *)value) = 0L;
322                 break;
323         case PBLOCK_CLASS_POINTER:
324         case PBLOCK_CLASS_FUNCTION_POINTER:
325                 *value = NULL;
326                 break;
327         case PBLOCK_CLASS_INVALID:
328                 return PBLOCK_ERROR;
329         }
330
331         for ( i = 0; i < pb->pb_nParams; i++ ) {
332                 if ( pb->pb_params[i] == param ) {
333                         switch ( pbClass ) {
334                         case PBLOCK_CLASS_INTEGER:
335                                 *((int *)value) = pb->pb_values[i].pv_integer;
336                                 break;
337                         case PBLOCK_CLASS_LONG_INTEGER:
338                                 *((long *)value) = pb->pb_values[i].pv_long_integer;
339                                 break;
340                         case PBLOCK_CLASS_POINTER:
341                                 *value = pb->pb_values[i].pv_pointer;
342                                 break;
343                         case PBLOCK_CLASS_FUNCTION_POINTER:
344                                 *value = pb->pb_values[i].pv_function_pointer;
345                                 break;
346                         default:
347                                 break;
348                         }
349                         break;
350                 }
351         }
352
353         return PBLOCK_SUCCESS;
354 }
355
356 static char *
357 pblock_get_authtype( AuthorizationInformation *authz, int is_tls )
358 {
359         char *authType;
360
361         switch ( authz->sai_method ) {
362         case LDAP_AUTH_SASL:
363                 authType = SLAPD_AUTH_SASL;
364                 break;
365         case LDAP_AUTH_SIMPLE:
366                 authType = SLAPD_AUTH_SIMPLE;
367                 break;
368         case LDAP_AUTH_NONE:
369                 authType = SLAPD_AUTH_NONE;
370                 break;
371         default:
372                 authType = NULL;
373                 break;
374         }
375
376         if ( is_tls && authType == NULL ) {
377                 authType = SLAPD_AUTH_SSL;
378         }
379
380         return authType;
381 }
382
383 static int 
384 pblock_set_default( Slapi_PBlock *pb, int param, void *value ) 
385 {
386         slapi_pblock_class_t pbClass;
387         size_t i;
388
389         pbClass = pblock_get_param_class( param );
390         if ( pbClass == PBLOCK_CLASS_INVALID ) {
391                 return PBLOCK_ERROR;
392         }
393
394         if ( pb->pb_nParams == PBLOCK_MAX_PARAMS ) {
395                 return PBLOCK_ERROR;
396         }
397
398         for ( i = 0; i < pb->pb_nParams; i++ ) {
399                 if ( pb->pb_params[i] == param )
400                         break;
401         }
402         if ( i >= pb->pb_nParams ) {
403                 pb->pb_params[i] = param;
404                 pb->pb_nParams++;
405         }
406
407         switch ( pbClass ) {
408         case PBLOCK_CLASS_INTEGER:
409                 pb->pb_values[i].pv_integer = (*((int *)value));
410                 break;
411         case PBLOCK_CLASS_LONG_INTEGER:
412                 pb->pb_values[i].pv_long_integer = (*((long *)value));
413                 break;
414         case PBLOCK_CLASS_POINTER:
415                 pb->pb_values[i].pv_pointer = value;
416                 break;
417         case PBLOCK_CLASS_FUNCTION_POINTER:
418                 pb->pb_values[i].pv_function_pointer = value;
419                 break;
420         default:
421                 break;
422         }
423
424         return PBLOCK_SUCCESS;
425 }
426
427 static int
428 pblock_be_call( Slapi_PBlock *pb, int (*bep)(Operation *) )
429 {
430         BackendDB *be_orig;
431         Operation *op;
432         int rc;
433
434         PBLOCK_ASSERT_OP( pb, 0 );
435         op = pb->pb_op;
436
437         be_orig = op->o_bd;
438         op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
439         rc = (*bep)( op );
440         op->o_bd = be_orig;
441
442         return rc;
443 }
444
445 static int 
446 pblock_get( Slapi_PBlock *pb, int param, void **value ) 
447 {
448         int rc = PBLOCK_SUCCESS;
449
450         pblock_lock( pb );
451
452         switch ( param ) {
453         case SLAPI_OPERATION:
454                 *value = pb->pb_op;
455                 break;
456         case SLAPI_OPINITIATED_TIME:
457                 PBLOCK_ASSERT_OP( pb, 0 );
458                 *((long *)value) = pb->pb_op->o_time;
459                 break;
460         case SLAPI_OPERATION_ID:
461                 PBLOCK_ASSERT_OP( pb, 0 );
462                 *((long *)value) = pb->pb_op->o_opid;
463                 break;
464         case SLAPI_OPERATION_TYPE:
465                 PBLOCK_ASSERT_OP( pb, 0 );
466                 *((ber_tag_t *)value) = pb->pb_op->o_tag;
467                 break;
468         case SLAPI_X_OPERATION_DELETE_GLUE_PARENT:
469                 PBLOCK_ASSERT_OP( pb, 0 );
470                 *((ber_tag_t *)value) = pb->pb_op->o_delete_glue_parent;
471                 break;
472         case SLAPI_X_OPERATION_NO_SCHEMA_CHECK:
473                 PBLOCK_ASSERT_OP( pb, 0 );
474                 *((int *)value) = get_no_schema_check( pb->pb_op );
475                 break;
476         case SLAPI_X_ADD_STRUCTURAL_CLASS:
477                 PBLOCK_ASSERT_OP( pb, 0 );
478
479                 if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
480                         struct berval tmpval = BER_BVNULL;
481
482                         rc = mods_structural_class( pb->pb_op->ora_modlist,
483                                 &tmpval, &pb->pb_rs->sr_text,
484                                 pb->pb_textbuf, sizeof( pb->pb_textbuf ));
485                         *((char **)value) = tmpval.bv_val;
486                 } else {
487                         rc = PBLOCK_ERROR;
488                 }
489                 break;
490         case SLAPI_REQCONTROLS:
491                 PBLOCK_ASSERT_OP( pb, 0 );
492                 *((LDAPControl ***)value) = pb->pb_op->o_ctrls;
493                 break;
494         case SLAPI_REQUESTOR_DN:
495                 PBLOCK_ASSERT_OP( pb, 0 );
496                 *((char **)value) = pb->pb_op->o_dn.bv_val;
497                 break;
498         case SLAPI_MANAGEDSAIT:
499                 PBLOCK_ASSERT_OP( pb, 0 );
500                 *((int *)value) = get_manageDSAit( pb->pb_op );
501                 break;
502         case SLAPI_X_MANAGEDIT:
503                 PBLOCK_ASSERT_OP( pb, 0 );
504                 *((int *)value) = get_manageDIT( pb->pb_op );
505                 break;
506         case SLAPI_BACKEND:
507                 PBLOCK_ASSERT_OP( pb, 0 );
508                 *((BackendDB **)value) = select_backend( &pb->pb_op->o_req_ndn, 0, 0 );
509                 break;
510         case SLAPI_BE_TYPE:
511                 PBLOCK_ASSERT_OP( pb, 0 );
512                 if ( pb->pb_op->o_bd != NULL )
513                         *((char **)value) = pb->pb_op->o_bd->bd_info->bi_type;
514                 else
515                         *value = NULL;
516                 break;
517         case SLAPI_CONNECTION:
518                 *value = pb->pb_conn;
519                 break;
520         case SLAPI_X_CONN_SSF:
521                 PBLOCK_ASSERT_OP( pb, 0 );
522                 *((slap_ssf_t *)value) = pb->pb_conn->c_ssf;
523                 break;
524         case SLAPI_X_CONN_SASL_CONTEXT:
525                 PBLOCK_ASSERT_CONN( pb );
526                 if ( pb->pb_conn->c_sasl_authctx != NULL )
527                         *value = pb->pb_conn->c_sasl_authctx;
528                 else
529                         *value = pb->pb_conn->c_sasl_sockctx;
530                 break;
531         case SLAPI_TARGET_DN:
532                 PBLOCK_ASSERT_OP( pb, 0 );
533                 *((char **)value) = pb->pb_op->o_req_dn.bv_val;
534                 break;
535         case SLAPI_REQUESTOR_ISROOT:
536                 *((int *)value) = pblock_be_call( pb, be_isroot );
537                 break;
538         case SLAPI_IS_REPLICATED_OPERATION:
539                 *((int *)value) = pblock_be_call( pb, be_slurp_update );
540                 break;
541         case SLAPI_CONN_AUTHTYPE:
542         case SLAPI_CONN_AUTHMETHOD: /* XXX should return SASL mech */
543                 PBLOCK_ASSERT_CONN( pb );
544                 *((char **)value) = pblock_get_authtype( &pb->pb_conn->c_authz,
545 #ifdef HAVE_TLS
546                                                          pb->pb_conn->c_is_tls
547 #else
548                                                          0
549 #endif
550                                                          );
551                 break;
552         case SLAPI_X_CONN_IS_UDP:
553                 PBLOCK_ASSERT_CONN( pb );
554 #ifdef LDAP_CONNECTIONLESS
555                 *((int *)value) = pb->pb_conn->c_is_udp;
556 #else
557                 *((int *)value) = 0;
558 #endif
559                 break;
560         case SLAPI_CONN_ID:
561                 PBLOCK_ASSERT_CONN( pb );
562                 *((long *)value) = pb->pb_conn->c_connid;
563                 break;
564         case SLAPI_CONN_DN:
565                 PBLOCK_ASSERT_CONN( pb );
566                 *((char **)value) = pb->pb_conn->c_dn.bv_val;
567                 break;
568         case SLAPI_CONN_CLIENTIP:
569                 PBLOCK_ASSERT_CONN( pb );
570                 if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "IP=", 3 ) == 0 )
571                         *((char **)value) = &pb->pb_conn->c_peer_name.bv_val[3];
572                 else
573                         *value = NULL;
574                 break;
575         case SLAPI_X_CONN_CLIENTPATH:
576                 PBLOCK_ASSERT_CONN( pb );
577                 if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "PATH=", 3 ) == 0 )
578                         *((char **)value) = &pb->pb_conn->c_peer_name.bv_val[5];
579                 else
580                         *value = NULL;
581                 break;
582         case SLAPI_CONN_SERVERIP:
583                 PBLOCK_ASSERT_CONN( pb );
584                 if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "IP=", 3 ) == 0 )
585                         *((char **)value) = &pb->pb_conn->c_sock_name.bv_val[3];
586                 else
587                         *value = NULL;
588                 break;
589         case SLAPI_X_CONN_SERVERPATH:
590                 PBLOCK_ASSERT_CONN( pb );
591                 if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "PATH=", 3 ) == 0 )
592                         *((char **)value) = &pb->pb_conn->c_sock_name.bv_val[5];
593                 else
594                         *value = NULL;
595                 break;
596         case SLAPI_RESULT_CODE:
597         case SLAPI_PLUGIN_INTOP_RESULT:
598                 PBLOCK_ASSERT_OP( pb, 0 );
599                 *((int *)value) = pb->pb_rs->sr_err;
600                 break;
601         case SLAPI_RESULT_TEXT:
602                 PBLOCK_ASSERT_OP( pb, 0 );
603                 *((const char **)value) = pb->pb_rs->sr_text;
604                 break;
605         case SLAPI_RESULT_MATCHED:
606                 PBLOCK_ASSERT_OP( pb, 0 );
607                 *((const char **)value) = pb->pb_rs->sr_matched;
608                 break;
609         case SLAPI_ADD_ENTRY:
610                 PBLOCK_ASSERT_OP( pb, 0 );
611                 if ( pb->pb_op->o_tag == LDAP_REQ_ADD )
612                         *((Slapi_Entry **)value) = pb->pb_op->ora_e;
613                 else
614                         *value = NULL;
615                 break;
616         case SLAPI_MODIFY_MODS: {
617                 LDAPMod **mods = NULL;
618                 Modifications *ml;
619
620                 pblock_get_default( pb, param, (void **)&mods );
621                 if ( mods == NULL && pb->pb_intop == 0 ) {
622                         switch ( pb->pb_op->o_tag ) {
623                         case LDAP_REQ_MODIFY:
624                                 ml = pb->pb_op->orm_modlist;
625                                 break;
626                         case LDAP_REQ_MODRDN:
627                                 ml = pb->pb_op->orr_modlist;
628                                 break;
629                         defaulat:
630                                 rc = PBLOCK_ERROR;
631                                 break;
632                         }
633                         mods = slapi_int_modifications2ldapmods( ml );
634                         pblock_set_default( pb, param, (void *)mods );
635                 }
636                 *((LDAPMod ***)value) = mods;
637                 break;
638         }
639         case SLAPI_MODRDN_NEWRDN:
640                 PBLOCK_ASSERT_OP( pb, 0 );
641                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
642                         *((char **)value) = pb->pb_op->orr_newrdn.bv_val;
643                 else
644                         *value = NULL;
645                 break;
646         case SLAPI_MODRDN_NEWSUPERIOR:
647                 PBLOCK_ASSERT_OP( pb, 0 );
648                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN && pb->pb_op->orr_newSup != NULL )
649                         *((char **)value) = pb->pb_op->orr_newSup->bv_val;
650                 else
651                         *value = NULL;
652                 break;
653         case SLAPI_MODRDN_DELOLDRDN:
654                 PBLOCK_ASSERT_OP( pb, 0 );
655                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
656                         *((int *)value) = pb->pb_op->orr_deleteoldrdn;
657                 else
658                         *((int *)value) = 0;
659                 break;
660         case SLAPI_SEARCH_SCOPE:
661                 PBLOCK_ASSERT_OP( pb, 0 );
662                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
663                         *((int *)value) = pb->pb_op->ors_scope;
664                 else
665                         *((int *)value) = 0;
666                 break;
667         case SLAPI_SEARCH_DEREF:
668                 PBLOCK_ASSERT_OP( pb, 0 );
669                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
670                         *((int *)value) = pb->pb_op->ors_deref;
671                 else
672                         *((int *)value) = 0;
673                 break;
674         case SLAPI_SEARCH_SIZELIMIT:
675                 PBLOCK_ASSERT_OP( pb, 0 );
676                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
677                         *((int *)value) = pb->pb_op->ors_slimit;
678                 else
679                         *((int *)value) = 0;
680                 break;
681         case SLAPI_SEARCH_TIMELIMIT:
682                 PBLOCK_ASSERT_OP( pb, 0 );
683                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
684                         *((int *)value) = pb->pb_op->ors_tlimit;
685                 else
686                         *((int *)value) = 0;
687                 break;
688         case SLAPI_SEARCH_FILTER:
689                 PBLOCK_ASSERT_OP( pb, 0 );
690                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
691                         *((Slapi_Filter **)value) = pb->pb_op->ors_filter;
692                 else
693                         *((Slapi_Filter **)value) = NULL;
694                 break;
695         case SLAPI_SEARCH_STRFILTER:
696                 PBLOCK_ASSERT_OP( pb, 0 );
697                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
698                         *((char **)value) = pb->pb_op->ors_filterstr.bv_val;
699                 else
700                         *((char **)value) = NULL;
701                 break;
702         case SLAPI_SEARCH_ATTRS: {
703                 char **attrs = NULL;
704
705                 PBLOCK_ASSERT_OP( pb, 0 );
706                 if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) {
707                         rc = PBLOCK_ERROR;
708                         break;
709                 }
710                 pblock_get_default( pb, param, (void **)&attrs );
711                 if ( attrs == NULL && pb->pb_intop == 0 ) {
712                         attrs = anlist2charray_x( pb->pb_op->ors_attrs, 0, pb->pb_op->o_tmpmemctx );
713                         pblock_set_default( pb, param, (void *)attrs );
714                 }
715                 *((char ***)value) = attrs;
716                 break;
717         }
718         case SLAPI_SEARCH_ATTRSONLY:
719                 PBLOCK_ASSERT_OP( pb, 0 );
720                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
721                         *((int *)value) = pb->pb_op->ors_attrsonly;
722                 else
723                         *((int *)value) = 0;
724                 break;
725         case SLAPI_SEARCH_RESULT_ENTRY:
726                 PBLOCK_ASSERT_OP( pb, 0 );
727                 *((Slapi_Entry **)value) = pb->pb_rs->sr_entry;
728                 break;
729         case SLAPI_BIND_RET_SASLCREDS:
730                 PBLOCK_ASSERT_OP( pb, 0 );
731                 *((struct berval **)value) = pb->pb_rs->sr_sasldata;
732                 break;
733         case SLAPI_EXT_OP_REQ_OID:
734                 *((const char **)value) = pb->pb_op->ore_reqoid.bv_val;
735                 break;
736         case SLAPI_EXT_OP_REQ_VALUE:
737                 *((struct berval **)value) = pb->pb_op->ore_reqdata;
738                 break;
739         case SLAPI_EXT_OP_RET_OID:
740                 PBLOCK_ASSERT_OP( pb, 0 );
741                 *((const char **)value) = pb->pb_rs->sr_rspoid;
742                 break;
743         case SLAPI_EXT_OP_RET_VALUE:
744                 PBLOCK_ASSERT_OP( pb, 0 );
745                 *((struct berval **)value) = pb->pb_rs->sr_rspdata;
746                 break;
747         case SLAPI_BIND_METHOD:
748                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
749                         *((int *)value) = pb->pb_op->orb_method;
750                 else
751                         *((int *)value) = 0;
752                 break;
753         case SLAPI_BIND_CREDENTIALS:
754                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
755                         *((struct berval **)value) = &pb->pb_op->orb_cred;
756                 else
757                         *value = NULL;
758                 break;
759         case SLAPI_COMPARE_TYPE:
760                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
761                         *((char **)value) = pb->pb_op->orc_ava->aa_desc->ad_cname.bv_val;
762                 else
763                         *value = NULL;
764                 break;
765         case SLAPI_COMPARE_VALUE:
766                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
767                         *((struct berval **)value) = &pb->pb_op->orc_ava->aa_value;
768                 else
769                         *value = NULL;
770                 break;
771         case SLAPI_ABANDON_MSGID:
772                 if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON )
773                         *((int *)value) = pb->pb_op->orn_msgid;
774                 else
775                         *((int *)value) = 0;
776                 break;
777         default:
778                 rc = pblock_get_default( pb, param, value );
779                 break;
780         }
781
782         pblock_unlock( pb );
783
784         return rc;
785 }
786
787 static int
788 pblock_add_control( Slapi_PBlock *pb, LDAPControl *control )
789 {
790         LDAPControl **controls = NULL;
791         size_t i;
792
793         pblock_get_default( pb, SLAPI_RESCONTROLS, (void **)&controls );
794
795         if ( controls != NULL ) {
796                 for ( i = 0; controls[i] != NULL; i++ )
797                         ;
798         } else {
799                 i = 0;
800         }
801
802         controls = (LDAPControl **)slapi_ch_realloc( (char *)controls,
803                 ( i + 2 ) * sizeof(LDAPControl *));
804         controls[i++] = slapi_dup_control( control );
805         controls[i] = NULL;
806
807         return pblock_set_default( pb, SLAPI_RESCONTROLS, (void *)controls );
808 }
809
810 static int
811 pblock_set_dn( void *value, struct berval *dn, struct berval *ndn, void *memctx )
812 {
813         struct berval bv;
814
815         if ( !BER_BVISNULL( dn )) {
816                 slap_sl_free( dn->bv_val, memctx );
817                 BER_BVZERO( dn );
818         }
819         if ( !BER_BVISNULL( ndn )) {
820                 slap_sl_free( ndn->bv_val, memctx );
821                 BER_BVZERO( ndn );
822         }
823
824         bv.bv_val = (char *)value;
825         bv.bv_len = ( value != NULL ) ? strlen( bv.bv_val ) : 0;
826
827         return dnPrettyNormal( NULL, &bv, dn, ndn, memctx );
828 }
829
830 static int 
831 pblock_set( Slapi_PBlock *pb, int param, void *value ) 
832 {
833         int rc = PBLOCK_SUCCESS;
834
835         pblock_lock( pb );      
836
837         switch ( param ) {
838         case SLAPI_OPERATION:
839                 pb->pb_op = (Operation *)value;
840                 break;
841         case SLAPI_OPINITIATED_TIME:
842                 PBLOCK_ASSERT_OP( pb, 0 );
843                 pb->pb_op->o_time = *((long *)value);
844                 break;
845         case SLAPI_OPERATION_ID:
846                 PBLOCK_ASSERT_OP( pb, 0 );
847                 pb->pb_op->o_opid = *((long *)value);
848                 break;
849         case SLAPI_OPERATION_TYPE:
850                 PBLOCK_ASSERT_OP( pb, 0 );
851                 pb->pb_op->o_tag = *((ber_tag_t *)value);
852                 break;
853         case SLAPI_X_OPERATION_DELETE_GLUE_PARENT:
854                 PBLOCK_ASSERT_OP( pb, 0 );
855                 pb->pb_op->o_delete_glue_parent = *((int *)value);
856                 break;
857         case SLAPI_X_OPERATION_NO_SCHEMA_CHECK:
858                 PBLOCK_ASSERT_OP( pb, 0 );
859                 pb->pb_op->o_no_schema_check = *((int *)value);
860                 break;
861         case SLAPI_REQCONTROLS:
862                 PBLOCK_ASSERT_OP( pb, 0 );
863                 pb->pb_op->o_ctrls = (LDAPControl **)value;
864                 break;
865         case SLAPI_RESCONTROLS: {
866                 LDAPControl **ctrls = NULL;
867
868                 pblock_get_default( pb, param, (void **)&ctrls );
869                 if ( ctrls != NULL ) {
870                         /* free old ones first */
871                         ldap_controls_free( ctrls );
872                 }
873                 rc = pblock_set_default( pb, param, value );
874                 break;
875         }
876         case SLAPI_ADD_RESCONTROL:
877                 PBLOCK_ASSERT_OP( pb, 0 );
878                 rc = pblock_add_control( pb, (LDAPControl *)value );
879                 break;
880         case SLAPI_REQUESTOR_DN:
881                 PBLOCK_ASSERT_OP( pb, 0 );
882                 rc = pblock_set_dn( value, &pb->pb_op->o_dn, &pb->pb_op->o_ndn, pb->pb_op->o_tmpmemctx );
883                 break;
884         case SLAPI_MANAGEDSAIT:
885                 PBLOCK_ASSERT_OP( pb, 0 );
886                 pb->pb_op->o_managedsait = *((int *)value);
887                 break;
888         case SLAPI_X_MANAGEDIT:
889                 PBLOCK_ASSERT_OP( pb, 0 );
890                 pb->pb_op->o_managedit = *((int *)value);
891                 break;
892         case SLAPI_BACKEND:
893                 PBLOCK_ASSERT_OP( pb, 0 );
894                 pb->pb_op->o_bd = (BackendDB *)value;
895                 break;
896         case SLAPI_CONNECTION:
897                 pb->pb_conn = (Connection *)value;
898                 break;
899         case SLAPI_X_CONN_SSF:
900                 PBLOCK_ASSERT_CONN( pb );
901                 PBLOCK_LOCK_CONN( pb );
902                 pb->pb_conn->c_ssf = (slap_ssf_t)(long)value;
903                 PBLOCK_UNLOCK_CONN( pb );
904                 break;
905         case SLAPI_X_CONN_SASL_CONTEXT:
906                 PBLOCK_ASSERT_CONN( pb );
907                 PBLOCK_LOCK_CONN( pb );
908                 pb->pb_conn->c_sasl_authctx = value;
909                 PBLOCK_UNLOCK_CONN( pb );
910                 break;
911         case SLAPI_TARGET_DN:
912                 PBLOCK_ASSERT_OP( pb, 0 );
913                 rc = pblock_set_dn( value, &pb->pb_op->o_req_dn, &pb->pb_op->o_req_ndn, pb->pb_op->o_tmpmemctx );
914                 break;
915         case SLAPI_CONN_ID:
916                 PBLOCK_ASSERT_CONN( pb );
917                 PBLOCK_LOCK_CONN( pb );
918                 pb->pb_conn->c_connid = *((long *)value);
919                 PBLOCK_UNLOCK_CONN( pb );
920                 break;
921         case SLAPI_CONN_DN:
922                 PBLOCK_ASSERT_CONN( pb );
923                 PBLOCK_LOCK_CONN( pb );
924                 rc = pblock_set_dn( value, &pb->pb_conn->c_dn, &pb->pb_conn->c_ndn, NULL );
925                 PBLOCK_UNLOCK_CONN( pb );
926                 break;
927         case SLAPI_RESULT_CODE:
928         case SLAPI_PLUGIN_INTOP_RESULT:
929                 PBLOCK_ASSERT_OP( pb, 0 );
930                 pb->pb_rs->sr_err = *((int *)value);
931                 break;
932         case SLAPI_RESULT_TEXT:
933                 PBLOCK_ASSERT_OP( pb, 0 );
934                 snprintf( pb->pb_textbuf, sizeof( pb->pb_textbuf ), "%s", (char *)value );
935                 pb->pb_rs->sr_text = pb->pb_textbuf;
936                 break;
937         case SLAPI_RESULT_MATCHED:
938                 PBLOCK_ASSERT_OP( pb, 0 );
939                 pb->pb_rs->sr_matched = (char *)value; /* XXX should dup? */
940                 break;
941         case SLAPI_ADD_ENTRY:
942                 PBLOCK_ASSERT_OP( pb, 0 );
943                 if ( pb->pb_op->o_tag == LDAP_REQ_ADD )
944                         pb->pb_op->ora_e = (Slapi_Entry *)value;
945                 else
946                         rc = PBLOCK_ERROR;
947                 break;
948         case SLAPI_MODIFY_MODS: {
949                 Modifications **mlp;
950                 Modifications *newmods;
951
952                 PBLOCK_ASSERT_OP( pb, 0 );
953                 rc = pblock_set_default( pb, param, value );
954                 if ( rc != PBLOCK_SUCCESS ) {
955                         break;
956                 }
957
958                 if ( pb->pb_op->o_tag == LDAP_REQ_MODIFY ) {
959                         mlp = &pb->pb_op->orm_modlist;
960                 } else if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
961                         mlp = &pb->pb_op->ora_modlist;
962                 } else if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
963                         mlp = &pb->pb_op->orr_modlist;
964                 } else {
965                         break;
966                 }
967
968                 newmods = slapi_int_ldapmods2modifications( (LDAPMod **)value );
969                 if ( newmods != NULL ) {
970                         slap_mods_free( *mlp, 1 );
971                         *mlp = newmods;
972                 }
973                 break;
974         }
975         case SLAPI_MODRDN_NEWRDN:
976                 PBLOCK_ASSERT_OP( pb, 0 );
977                 PBLOCK_VALIDATE_IS_INTOP( pb );
978                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
979                         rc = pblock_set_dn( value, &pb->pb_op->orr_newrdn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx );
980                         if ( rc == LDAP_SUCCESS )
981                                 rc = rdn_validate( &pb->pb_op->orr_nnewrdn );
982                 } else {
983                         rc = PBLOCK_ERROR;
984                 }
985                 break;
986         case SLAPI_MODRDN_NEWSUPERIOR:
987                 PBLOCK_ASSERT_OP( pb, 0 );
988                 PBLOCK_VALIDATE_IS_INTOP( pb );
989                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
990                         if ( value == NULL ) {
991                                 if ( pb->pb_op->orr_newSup != NULL ) {
992                                         pb->pb_op->o_tmpfree( pb->pb_op->orr_newSup, pb->pb_op->o_tmpmemctx );
993                                         BER_BVZERO( pb->pb_op->orr_newSup );
994                                         pb->pb_op->orr_newSup = NULL;
995                                 }
996                                 if ( pb->pb_op->orr_newSup != NULL ) {
997                                         pb->pb_op->o_tmpfree( pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
998                                         BER_BVZERO( pb->pb_op->orr_nnewSup );
999                                         pb->pb_op->orr_nnewSup = NULL;
1000                                 }
1001                         } else {
1002                                 if ( pb->pb_op->orr_newSup == NULL ) {
1003                                         pb->pb_op->orr_newSup = (struct berval *)pb->pb_op->o_tmpalloc(
1004                                                 sizeof(struct berval), pb->pb_op->o_tmpmemctx );
1005                                         BER_BVZERO( pb->pb_op->orr_newSup );
1006                                 }
1007                                 if ( pb->pb_op->orr_nnewSup == NULL ) {
1008                                         pb->pb_op->orr_nnewSup = (struct berval *)pb->pb_op->o_tmpalloc(
1009                                                 sizeof(struct berval), pb->pb_op->o_tmpmemctx );
1010                                         BER_BVZERO( pb->pb_op->orr_nnewSup );
1011                                 }
1012                                 rc = pblock_set_dn( value, pb->pb_op->orr_newSup, pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
1013                         }
1014                 } else {
1015                         rc = PBLOCK_ERROR;
1016                 }
1017                 break;
1018         case SLAPI_MODRDN_DELOLDRDN:
1019                 PBLOCK_ASSERT_OP( pb, 0 );
1020                 PBLOCK_VALIDATE_IS_INTOP( pb );
1021                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
1022                         pb->pb_op->orr_deleteoldrdn = *((int *)value);
1023                 else
1024                         rc = PBLOCK_ERROR;
1025                 break;
1026         case SLAPI_SEARCH_SCOPE: {
1027                 int scope = *((int *)value);
1028
1029                 PBLOCK_ASSERT_OP( pb, 0 );
1030                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
1031                         switch ( *((int *)value) ) {
1032                         case LDAP_SCOPE_BASE:
1033                         case LDAP_SCOPE_ONELEVEL:
1034                         case LDAP_SCOPE_SUBTREE:
1035                         case LDAP_SCOPE_SUBORDINATE:
1036                                 pb->pb_op->ors_scope = scope;
1037                                 break;
1038                         default:
1039                                 rc = PBLOCK_ERROR;
1040                                 break;
1041                         }
1042                 } else {
1043                         rc = PBLOCK_ERROR;
1044                 }
1045                 break;
1046         }
1047         case SLAPI_SEARCH_DEREF:
1048                 PBLOCK_ASSERT_OP( pb, 0 );
1049                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1050                         pb->pb_op->ors_deref = *((int *)value);
1051                 else
1052                         rc = PBLOCK_ERROR;
1053                 break;
1054         case SLAPI_SEARCH_SIZELIMIT:
1055                 PBLOCK_ASSERT_OP( pb, 0 );
1056                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1057                         pb->pb_op->ors_slimit = *((int *)value);
1058                 else
1059                         rc = PBLOCK_ERROR;
1060                 break;
1061         case SLAPI_SEARCH_TIMELIMIT:
1062                 PBLOCK_ASSERT_OP( pb, 0 );
1063                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1064                         pb->pb_op->ors_tlimit = *((int *)value);
1065                 else
1066                         rc = PBLOCK_ERROR;
1067                 break;
1068         case SLAPI_SEARCH_FILTER:
1069                 PBLOCK_ASSERT_OP( pb, 0 );
1070                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1071                         pb->pb_op->ors_filter = (Slapi_Filter *)value;
1072                 else
1073                         rc = PBLOCK_ERROR;
1074                 break;
1075         case SLAPI_SEARCH_STRFILTER:
1076                 PBLOCK_ASSERT_OP( pb, 0 );
1077                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
1078                         pb->pb_op->ors_filterstr.bv_val = (char *)value;
1079                         pb->pb_op->ors_filterstr.bv_len = strlen((char *)value);
1080                 } else {
1081                         rc = PBLOCK_ERROR;
1082                 }
1083                 break;
1084         case SLAPI_SEARCH_ATTRS: {
1085                 AttributeName *an = NULL;
1086                 size_t i = 0;
1087                 char **attrs = (char **)value;
1088
1089                 PBLOCK_ASSERT_OP( pb, 0 );
1090                 PBLOCK_VALIDATE_IS_INTOP( pb );
1091
1092                 if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) {
1093                         rc = PBLOCK_ERROR;
1094                         break;
1095                 }
1096                 /* also set mapped attrs */
1097                 rc = pblock_set_default( pb, param, value );
1098                 if ( rc != PBLOCK_SUCCESS ) {
1099                         break;
1100                 }
1101                 if ( pb->pb_op->ors_attrs != NULL ) {
1102                         pb->pb_op->o_tmpfree( pb->pb_op->ors_attrs, pb->pb_op->o_tmpmemctx );
1103                         pb->pb_op->ors_attrs = NULL;
1104                 }
1105                 if ( attrs != NULL ) {
1106                         for ( i = 0; attrs[i] != NULL; i++ )
1107                                 ;
1108                 }
1109                 if ( i ) {
1110                         an = (AttributeName *)pb->pb_op->o_tmpalloc( (i + 1) *
1111                                 sizeof(AttributeName), pb->pb_op->o_tmpmemctx );
1112                         for ( i = 0; attrs[i] != NULL; i++ ) {
1113                                 an[i].an_desc = NULL;
1114                                 an[i].an_oc = NULL;
1115                                 an[i].an_oc_exclude = 0;
1116                                 an[i].an_name.bv_val = attrs[i];
1117                                 an[i].an_name.bv_len = strlen( attrs[i] );
1118                                 slap_bv2ad( &an[i].an_name, &an[i].an_desc, &pb->pb_rs->sr_text );
1119                         }
1120                         an[i].an_name.bv_val = NULL;
1121                         an[i].an_name.bv_len = 0;
1122                 }       
1123                 pb->pb_op->ors_attrs = an;
1124                 break;
1125         }
1126         case SLAPI_SEARCH_ATTRSONLY:
1127                 PBLOCK_ASSERT_OP( pb, 0 );
1128                 PBLOCK_VALIDATE_IS_INTOP( pb );
1129
1130                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1131                         pb->pb_op->ors_attrsonly = *((int *)value);
1132                 else
1133                         rc = PBLOCK_ERROR;
1134                 break;
1135         case SLAPI_SEARCH_RESULT_ENTRY:
1136                 PBLOCK_ASSERT_OP( pb, 0 );
1137                 pb->pb_rs->sr_entry = (Slapi_Entry *)value;
1138                 break;
1139         case SLAPI_BIND_RET_SASLCREDS:
1140                 PBLOCK_ASSERT_OP( pb, 0 );
1141                 pb->pb_rs->sr_sasldata = (struct berval *)value;
1142                 break;
1143         case SLAPI_EXT_OP_REQ_OID:
1144                 PBLOCK_ASSERT_OP( pb, 0 );
1145                 PBLOCK_VALIDATE_IS_INTOP( pb );
1146
1147                 if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED ) {
1148                         pb->pb_op->ore_reqoid.bv_val = (char *)value;
1149                         pb->pb_op->ore_reqoid.bv_len = strlen((char *)value);
1150                 } else {
1151                         rc = PBLOCK_ERROR;
1152                 }
1153                 break;
1154         case SLAPI_EXT_OP_REQ_VALUE:
1155                 PBLOCK_ASSERT_OP( pb, 0 );
1156                 PBLOCK_VALIDATE_IS_INTOP( pb );
1157
1158                 if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED )
1159                         pb->pb_op->ore_reqdata = (struct berval *)value;
1160                 else
1161                         rc = PBLOCK_ERROR;
1162                 break;
1163         case SLAPI_EXT_OP_RET_OID:
1164                 PBLOCK_ASSERT_OP( pb, 0 );
1165                 pb->pb_rs->sr_rspoid = (char *)value;
1166                 break;
1167         case SLAPI_EXT_OP_RET_VALUE:
1168                 PBLOCK_ASSERT_OP( pb, 0 );
1169                 pb->pb_rs->sr_rspdata = (struct berval *)value;
1170                 break;
1171         case SLAPI_BIND_METHOD:
1172                 PBLOCK_ASSERT_OP( pb, 0 );
1173                 PBLOCK_VALIDATE_IS_INTOP( pb );
1174
1175                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
1176                         pb->pb_op->orb_method = *((int *)value);
1177                 else
1178                         rc = PBLOCK_ERROR;
1179                 break;
1180         case SLAPI_BIND_CREDENTIALS:
1181                 PBLOCK_ASSERT_OP( pb, 0 );
1182                 PBLOCK_VALIDATE_IS_INTOP( pb );
1183
1184                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
1185                         pb->pb_op->orb_cred = *((struct berval *)value);
1186                 else
1187                         rc = PBLOCK_ERROR;
1188                 break;
1189         case SLAPI_COMPARE_TYPE:
1190                 PBLOCK_ASSERT_OP( pb, 0 );
1191                 PBLOCK_VALIDATE_IS_INTOP( pb );
1192
1193                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) {
1194                         const char *text;
1195
1196                         pb->pb_op->orc_ava->aa_desc = NULL;
1197                         rc = slap_str2ad( (char *)value, &pb->pb_op->orc_ava->aa_desc, &text );
1198                 } else {
1199                         rc = PBLOCK_ERROR;
1200                 }
1201                 break;
1202         case SLAPI_COMPARE_VALUE:
1203                 PBLOCK_ASSERT_OP( pb, 0 );
1204                 PBLOCK_VALIDATE_IS_INTOP( pb );
1205
1206                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
1207                         pb->pb_op->orc_ava->aa_value = *((struct berval *)value);
1208                 else
1209                         rc = PBLOCK_ERROR;
1210                 break;
1211         case SLAPI_ABANDON_MSGID:
1212                 PBLOCK_ASSERT_OP( pb, 0 );
1213                 PBLOCK_VALIDATE_IS_INTOP( pb );
1214
1215                 if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON)
1216                         pb->pb_op->orn_msgid = *((int *)value);
1217                 else
1218                         rc = PBLOCK_ERROR;
1219                 break;
1220         case SLAPI_REQUESTOR_ISROOT:
1221         case SLAPI_IS_REPLICATED_OPERATION:
1222         case SLAPI_CONN_AUTHTYPE:
1223         case SLAPI_CONN_AUTHMETHOD:
1224         case SLAPI_X_CONN_IS_UDP:
1225         case SLAPI_CONN_CLIENTIP:
1226         case SLAPI_X_CONN_CLIENTPATH:
1227         case SLAPI_CONN_SERVERIP:
1228         case SLAPI_X_CONN_SERVERPATH:
1229         case SLAPI_X_ADD_STRUCTURAL_CLASS:
1230                 /* These parameters cannot be set */
1231                 rc = PBLOCK_ERROR;
1232                 break;
1233         default:
1234                 rc = pblock_set_default( pb, param, value );
1235                 break;
1236         }
1237
1238         pblock_unlock( pb );
1239
1240         return rc;
1241 }
1242
1243 static void
1244 pblock_clear( Slapi_PBlock *pb ) 
1245 {
1246         pb->pb_nParams = 1;
1247 }
1248
1249 static int
1250 pblock_delete_param( Slapi_PBlock *p, int param ) 
1251 {
1252         int i;
1253
1254         pblock_lock(p);
1255
1256         for ( i = 0; i < p->pb_nParams; i++ ) { 
1257                 if ( p->pb_params[i] == param ) {
1258                         break;
1259                 }
1260         }
1261     
1262         if (i >= p->pb_nParams ) {
1263                 pblock_unlock( p );
1264                 return PBLOCK_ERROR;
1265         }
1266
1267         /* move last parameter to index of deleted parameter */
1268         if ( p->pb_nParams > 1 ) {
1269                 p->pb_params[i] = p->pb_params[p->pb_nParams - 1];
1270                 p->pb_values[i] = p->pb_values[p->pb_nParams - 1];
1271         }
1272         p->pb_nParams--;
1273
1274         pblock_unlock( p );     
1275
1276         return PBLOCK_SUCCESS;
1277 }
1278
1279 Slapi_PBlock *
1280 slapi_pblock_new(void) 
1281 {
1282         Slapi_PBlock *pb;
1283
1284         pb = (Slapi_PBlock *) ch_calloc( 1, sizeof(Slapi_PBlock) );
1285         if ( pb != NULL ) {
1286                 ldap_pvt_thread_mutex_init( &pb->pb_mutex );
1287
1288                 pb->pb_params[0] = SLAPI_IBM_PBLOCK;
1289                 pb->pb_values[0].pv_pointer = NULL;
1290                 pb->pb_nParams = 1;
1291                 pb->pb_conn = NULL;
1292                 pb->pb_op = NULL;
1293                 pb->pb_rs = NULL;
1294                 pb->pb_intop = 0;
1295         }
1296         return pb;
1297 }
1298
1299 static void
1300 pblock_destroy( Slapi_PBlock *pb )
1301 {
1302         LDAPControl **controls = NULL;
1303         LDAPMod **mods = NULL;
1304         char **attrs = NULL;
1305
1306         assert( pb != NULL );
1307
1308         pblock_get_default( pb, SLAPI_RESCONTROLS, (void **)&controls );
1309         if ( controls != NULL ) {
1310                 ldap_controls_free( controls );
1311         }
1312
1313         if ( pb->pb_intop ) {
1314                 slapi_int_connection_done_pb( pb );
1315         } else {
1316                 pblock_get_default( pb, SLAPI_MODIFY_MODS, (void **)&mods );
1317                 ldap_mods_free( mods, 1 );
1318
1319                 pblock_get_default( pb, SLAPI_SEARCH_ATTRS, (void **)&attrs );
1320                 if ( attrs != NULL )
1321                         pb->pb_op->o_tmpfree( attrs, pb->pb_op->o_tmpmemctx );
1322         }
1323
1324         ldap_pvt_thread_mutex_destroy( &pb->pb_mutex );
1325         slapi_ch_free( (void **)&pb ); 
1326 }
1327
1328 void 
1329 slapi_pblock_destroy( Slapi_PBlock *pb ) 
1330 {
1331         if ( pb != NULL ) {
1332                 pblock_destroy( pb );
1333         }
1334 }
1335
1336 int 
1337 slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value ) 
1338 {
1339         return pblock_get( pb, arg, (void **)value );
1340 }
1341
1342 int 
1343 slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value ) 
1344 {
1345         return pblock_set( pb, arg, value );
1346 }
1347
1348 void
1349 slapi_pblock_clear( Slapi_PBlock *pb ) 
1350 {
1351         pblock_clear( pb );
1352 }
1353
1354 int 
1355 slapi_pblock_delete_param( Slapi_PBlock *p, int param ) 
1356 {
1357         return pblock_delete_param( p, param );
1358 }
1359
1360 /*
1361  * OpenLDAP extension
1362  */
1363 int
1364 slapi_int_pblock_get_first( Backend *be, Slapi_PBlock **pb )
1365 {
1366         assert( pb != NULL );
1367         *pb = SLAPI_BACKEND_PBLOCK( be );
1368         return (*pb == NULL ? LDAP_OTHER : LDAP_SUCCESS);
1369 }
1370
1371 /*
1372  * OpenLDAP extension
1373  */
1374 int
1375 slapi_int_pblock_get_next( Slapi_PBlock **pb )
1376 {
1377         assert( pb != NULL );
1378         return slapi_pblock_get( *pb, SLAPI_IBM_PBLOCK, pb );
1379 }
1380
1381 #endif /* LDAP_SLAPI */
1382