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