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