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