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