]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_pblock.c
Remember to NULL terminate control arrays - not sure how I managed to
[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++] = slapi_dup_control( control );
766         controls[i] = NULL;
767
768         return pblock_set_default( pb, SLAPI_RESCONTROLS, (void *)controls );
769 }
770
771 static int
772 pblock_set_dn( void *value, struct berval *dn, struct berval *ndn, void *memctx )
773 {
774         struct berval bv;
775
776         if ( !BER_BVISNULL( dn )) {
777                 slap_sl_free( dn->bv_val, memctx );
778                 BER_BVZERO( dn );
779         }
780         if ( !BER_BVISNULL( ndn )) {
781                 slap_sl_free( ndn->bv_val, memctx );
782                 BER_BVZERO( ndn );
783         }
784
785         bv.bv_val = (char *)value;
786         bv.bv_len = strlen( bv.bv_val );
787
788         return dnPrettyNormal( NULL, &bv, dn, ndn, memctx );
789 }
790
791 static int 
792 pblock_set( Slapi_PBlock *pb, int param, void *value ) 
793 {
794         int rc = PBLOCK_SUCCESS;
795
796         pblock_lock( pb );      
797
798         switch ( param ) {
799         case SLAPI_OPERATION:
800                 pb->pb_op = (Operation *)value;
801                 break;
802         case SLAPI_OPINITIATED_TIME:
803                 PBLOCK_ASSERT_OP( pb, 0 );
804                 pb->pb_op->o_time = *((long *)value);
805                 break;
806         case SLAPI_OPERATION_ID:
807                 PBLOCK_ASSERT_OP( pb, 0 );
808                 pb->pb_op->o_opid = *((long *)value);
809                 break;
810         case SLAPI_OPERATION_TYPE:
811                 PBLOCK_ASSERT_OP( pb, 0 );
812                 pb->pb_op->o_tag = *((ber_tag_t *)value);
813                 break;
814         case SLAPI_REQCONTROLS:
815                 PBLOCK_ASSERT_OP( pb, 0 );
816                 pb->pb_op->o_ctrls = (LDAPControl **)value;
817                 break;
818         case SLAPI_RESCONTROLS: {
819                 LDAPControl **ctrls = NULL;
820
821                 pblock_get_default( pb, param, (void **)&ctrls );
822                 if ( ctrls != NULL ) {
823                         /* free old ones first */
824                         ldap_controls_free( ctrls );
825                 }
826                 rc = pblock_set_default( pb, param, value );
827                 break;
828         }
829         case SLAPI_ADD_RESCONTROL:
830                 PBLOCK_ASSERT_OP( pb, 0 );
831                 rc = pblock_add_control( pb, (LDAPControl *)value );
832                 break;
833         case SLAPI_REQUESTOR_DN:
834                 PBLOCK_ASSERT_OP( pb, 0 );
835                 rc = pblock_set_dn( value, &pb->pb_op->o_dn, &pb->pb_op->o_ndn, pb->pb_op->o_tmpmemctx );
836                 break;
837         case SLAPI_MANAGEDSAIT:
838                 PBLOCK_ASSERT_OP( pb, 0 );
839                 pb->pb_op->o_managedsait = *((int *)value);
840                 break;
841         case SLAPI_BACKEND:
842                 PBLOCK_ASSERT_OP( pb, 0 );
843                 pb->pb_op->o_bd = (BackendDB *)value;
844                 break;
845         case SLAPI_CONNECTION:
846                 pb->pb_conn = (Connection *)value;
847                 break;
848         case SLAPI_X_CONN_SSF:
849                 PBLOCK_ASSERT_CONN( pb );
850                 PBLOCK_LOCK_CONN( pb );
851                 pb->pb_conn->c_ssf = (slap_ssf_t)value;
852                 PBLOCK_UNLOCK_CONN( pb );
853                 break;
854         case SLAPI_X_CONN_SASL_CONTEXT:
855                 PBLOCK_ASSERT_CONN( pb );
856                 PBLOCK_LOCK_CONN( pb );
857                 pb->pb_conn->c_sasl_authctx = value;
858                 PBLOCK_UNLOCK_CONN( pb );
859                 break;
860         case SLAPI_TARGET_DN:
861                 PBLOCK_ASSERT_OP( pb, 0 );
862                 rc = pblock_set_dn( value, &pb->pb_op->o_req_dn, &pb->pb_op->o_req_ndn, pb->pb_op->o_tmpmemctx );
863                 break;
864         case SLAPI_CONN_ID:
865                 PBLOCK_ASSERT_CONN( pb );
866                 PBLOCK_LOCK_CONN( pb );
867                 pb->pb_conn->c_connid = *((long *)value);
868                 PBLOCK_UNLOCK_CONN( pb );
869                 break;
870         case SLAPI_CONN_DN:
871                 PBLOCK_ASSERT_CONN( pb );
872                 PBLOCK_LOCK_CONN( pb );
873                 rc = pblock_set_dn( value, &pb->pb_conn->c_dn, &pb->pb_conn->c_ndn, NULL );
874                 PBLOCK_UNLOCK_CONN( pb );
875                 break;
876         case SLAPI_RESULT_CODE:
877         case SLAPI_PLUGIN_INTOP_RESULT:
878                 PBLOCK_ASSERT_OP( pb, 0 );
879                 pb->pb_rs->sr_err = *((int *)value);
880                 break;
881         case SLAPI_RESULT_TEXT:
882                 PBLOCK_ASSERT_OP( pb, 0 );
883                 snprintf( pb->pb_textbuf, sizeof( pb->pb_textbuf ), "%s", (char *)value );
884                 pb->pb_rs->sr_text = pb->pb_textbuf;
885                 break;
886         case SLAPI_RESULT_MATCHED:
887                 PBLOCK_ASSERT_OP( pb, 0 );
888                 pb->pb_rs->sr_matched = (char *)value; /* XXX should dup? */
889                 break;
890         case SLAPI_ADD_ENTRY:
891                 PBLOCK_ASSERT_OP( pb, 0 );
892                 if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
893                         pb->pb_op->ora_e = (Slapi_Entry *)value;
894                 } else {
895                         rc = PBLOCK_ERROR;
896                 }
897                 break;
898         case SLAPI_MODIFY_MODS: {
899                 Modifications **mlp;
900
901                 PBLOCK_ASSERT_OP( pb, 0 );
902                 rc = pblock_set_default( pb, param, value );
903                 if ( rc != PBLOCK_SUCCESS ) {
904                         break;
905                 }
906
907                 if ( pb->pb_op->o_tag == LDAP_REQ_MODIFY ) {
908                         mlp = &pb->pb_op->orm_modlist;
909                 } else if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
910                         mlp = &pb->pb_op->ora_modlist;
911                 } else {
912                         break;
913                 }
914
915                 if ( *mlp != NULL ) {
916                         slapi_int_mods_free( *mlp );
917                         *mlp = NULL;
918                 }
919                 *mlp = slapi_int_ldapmods2modifications( (LDAPMod **)value, NULL );
920                 break;
921         }
922         case SLAPI_MODRDN_NEWRDN:
923                 PBLOCK_ASSERT_OP( pb, 0 );
924                 PBLOCK_VALIDATE_IS_INTOP( pb );
925                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
926                         rc = pblock_set_dn( value, &pb->pb_op->orr_newrdn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx );
927                         if ( rc == LDAP_SUCCESS )
928                                 rc = rdn_validate( &pb->pb_op->orr_nnewrdn );
929                 } else {
930                         rc = PBLOCK_ERROR;
931                 }
932                 break;
933         case SLAPI_MODRDN_NEWSUPERIOR:
934                 PBLOCK_ASSERT_OP( pb, 0 );
935                 PBLOCK_VALIDATE_IS_INTOP( pb );
936                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
937                         if ( value == NULL ) {
938                                 if ( pb->pb_op->orr_newSup != NULL ) {
939                                         pb->pb_op->o_tmpfree( pb->pb_op->orr_newSup, pb->pb_op->o_tmpmemctx );
940                                         BER_BVZERO( pb->pb_op->orr_newSup );
941                                         pb->pb_op->orr_newSup = NULL;
942                                 }
943                                 if ( pb->pb_op->orr_newSup != NULL ) {
944                                         pb->pb_op->o_tmpfree( pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
945                                         BER_BVZERO( pb->pb_op->orr_nnewSup );
946                                         pb->pb_op->orr_nnewSup = NULL;
947                                 }
948                         } else {
949                                 if ( pb->pb_op->orr_newSup == NULL ) {
950                                         pb->pb_op->orr_newSup = (struct berval *)pb->pb_op->o_tmpalloc(
951                                                 sizeof(struct berval), pb->pb_op->o_tmpmemctx );
952                                         BER_BVZERO( pb->pb_op->orr_newSup );
953                                 }
954                                 if ( pb->pb_op->orr_nnewSup == NULL ) {
955                                         pb->pb_op->orr_nnewSup = (struct berval *)pb->pb_op->o_tmpalloc(
956                                                 sizeof(struct berval), pb->pb_op->o_tmpmemctx );
957                                         BER_BVZERO( pb->pb_op->orr_nnewSup );
958                                 }
959                                 rc = pblock_set_dn( value, pb->pb_op->orr_newSup, pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
960                         }
961                 } else {
962                         rc = PBLOCK_ERROR;
963                 }
964                 break;
965         case SLAPI_MODRDN_DELOLDRDN:
966                 PBLOCK_ASSERT_OP( pb, 0 );
967                 PBLOCK_VALIDATE_IS_INTOP( pb );
968                 if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
969                         pb->pb_op->orr_deleteoldrdn = *((int *)value);
970                 else
971                         rc = PBLOCK_ERROR;
972                 break;
973         case SLAPI_SEARCH_SCOPE: {
974                 int scope = *((int *)value);
975
976                 PBLOCK_ASSERT_OP( pb, 0 );
977                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
978                         switch ( *((int *)value) ) {
979                         case LDAP_SCOPE_BASE:
980                         case LDAP_SCOPE_ONELEVEL:
981                         case LDAP_SCOPE_SUBTREE:
982 #ifdef LDAP_SCOPE_SUBORDINATE
983                         case LDAP_SCOPE_SUBORDINATE:
984 #endif
985                                 pb->pb_op->ors_scope = scope;
986                                 break;
987                         default:
988                                 rc = PBLOCK_ERROR;
989                                 break;
990                         }
991                 } else {
992                         rc = PBLOCK_ERROR;
993                 }
994                 break;
995         }
996         case SLAPI_SEARCH_DEREF:
997                 PBLOCK_ASSERT_OP( pb, 0 );
998                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
999                         pb->pb_op->ors_deref = *((int *)value);
1000                 else
1001                         rc = PBLOCK_ERROR;
1002                 break;
1003         case SLAPI_SEARCH_SIZELIMIT:
1004                 PBLOCK_ASSERT_OP( pb, 0 );
1005                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1006                         pb->pb_op->ors_slimit = *((int *)value);
1007                 else
1008                         rc = PBLOCK_ERROR;
1009                 break;
1010         case SLAPI_SEARCH_TIMELIMIT:
1011                 PBLOCK_ASSERT_OP( pb, 0 );
1012                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1013                         pb->pb_op->ors_tlimit = *((int *)value);
1014                 else
1015                         rc = PBLOCK_ERROR;
1016                 break;
1017         case SLAPI_SEARCH_FILTER:
1018                 PBLOCK_ASSERT_OP( pb, 0 );
1019                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1020                         pb->pb_op->ors_filter = (Slapi_Filter *)value;
1021                 else
1022                         rc = PBLOCK_ERROR;
1023                 break;
1024         case SLAPI_SEARCH_STRFILTER:
1025                 PBLOCK_ASSERT_OP( pb, 0 );
1026                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
1027                         pb->pb_op->ors_filterstr.bv_val = (char *)value;
1028                         pb->pb_op->ors_filterstr.bv_len = strlen((char *)value);
1029                 } else {
1030                         rc = PBLOCK_ERROR;
1031                 }
1032                 break;
1033         case SLAPI_SEARCH_ATTRS: {
1034                 AttributeName *an = NULL;
1035                 size_t i = 0;
1036                 char **attrs = (char **)value;
1037
1038                 PBLOCK_ASSERT_OP( pb, 0 );
1039                 PBLOCK_VALIDATE_IS_INTOP( pb );
1040
1041                 if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) {
1042                         rc = PBLOCK_ERROR;
1043                         break;
1044                 }
1045                 /* also set mapped attrs */
1046                 rc = pblock_set_default( pb, param, value );
1047                 if ( rc != PBLOCK_SUCCESS ) {
1048                         break;
1049                 }
1050                 if ( pb->pb_op->ors_attrs != NULL ) {
1051                         pb->pb_op->o_tmpfree( pb->pb_op->ors_attrs, pb->pb_op->o_tmpmemctx );
1052                         pb->pb_op->ors_attrs = NULL;
1053                 }
1054                 if ( attrs != NULL ) {
1055                         for ( i = 0; attrs[i] != NULL; i++ )
1056                                 ;
1057                 }
1058                 if ( i ) {
1059                         an = (AttributeName *)pb->pb_op->o_tmpalloc( (i + 1) *
1060                                 sizeof(AttributeName), pb->pb_op->o_tmpmemctx );
1061                         for ( i = 0; attrs[i] != NULL; i++ ) {
1062                                 an[i].an_desc = NULL;
1063                                 an[i].an_oc = NULL;
1064                                 an[i].an_oc_exclude = 0;
1065                                 an[i].an_name.bv_val = attrs[i];
1066                                 an[i].an_name.bv_len = strlen( attrs[i] );
1067                                 slap_bv2ad( &an[i].an_name, &an[i].an_desc, &pb->pb_rs->sr_text );
1068                         }
1069                         an[i].an_name.bv_val = NULL;
1070                         an[i].an_name.bv_len = 0;
1071                 }       
1072                 pb->pb_op->ors_attrs = an;
1073                 break;
1074         }
1075         case SLAPI_SEARCH_ATTRSONLY:
1076                 PBLOCK_ASSERT_OP( pb, 0 );
1077                 PBLOCK_VALIDATE_IS_INTOP( pb );
1078
1079                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1080                         pb->pb_op->ors_attrsonly = *((int *)value);
1081                 else
1082                         rc = PBLOCK_ERROR;
1083                 break;
1084         case SLAPI_SEARCH_RESULT_ENTRY:
1085                 PBLOCK_ASSERT_OP( pb, 0 );
1086                 pb->pb_rs->sr_entry = (Slapi_Entry *)value;
1087                 break;
1088         case SLAPI_BIND_RET_SASLCREDS:
1089                 PBLOCK_ASSERT_OP( pb, 0 );
1090                 pb->pb_rs->sr_sasldata = (struct berval *)value;
1091                 break;
1092         case SLAPI_EXT_OP_REQ_OID:
1093                 PBLOCK_ASSERT_OP( pb, 0 );
1094                 PBLOCK_VALIDATE_IS_INTOP( pb );
1095
1096                 if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED ) {
1097                         pb->pb_op->ore_reqoid.bv_val = (char *)value;
1098                         pb->pb_op->ore_reqoid.bv_len = strlen((char *)value);
1099                 } else {
1100                         rc = PBLOCK_ERROR;
1101                 }
1102                 break;
1103         case SLAPI_EXT_OP_REQ_VALUE:
1104                 PBLOCK_ASSERT_OP( pb, 0 );
1105                 PBLOCK_VALIDATE_IS_INTOP( pb );
1106
1107                 if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED )
1108                         pb->pb_op->ore_reqdata = (struct berval *)value;
1109                 else
1110                         rc = PBLOCK_ERROR;
1111                 break;
1112         case SLAPI_EXT_OP_RET_OID:
1113                 PBLOCK_ASSERT_OP( pb, 0 );
1114                 pb->pb_rs->sr_rspoid = (char *)value;
1115                 break;
1116         case SLAPI_EXT_OP_RET_VALUE:
1117                 PBLOCK_ASSERT_OP( pb, 0 );
1118                 pb->pb_rs->sr_rspdata = (struct berval *)value;
1119                 break;
1120         case SLAPI_BIND_METHOD:
1121                 PBLOCK_ASSERT_OP( pb, 0 );
1122                 PBLOCK_VALIDATE_IS_INTOP( pb );
1123
1124                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
1125                         pb->pb_op->orb_method = *((int *)value);
1126                 else
1127                         rc = PBLOCK_ERROR;
1128                 break;
1129         case SLAPI_BIND_CREDENTIALS:
1130                 PBLOCK_ASSERT_OP( pb, 0 );
1131                 PBLOCK_VALIDATE_IS_INTOP( pb );
1132
1133                 if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
1134                         pb->pb_op->orb_cred = *((struct berval *)value);
1135                 else
1136                         rc = PBLOCK_ERROR;
1137                 break;
1138         case SLAPI_COMPARE_TYPE:
1139                 PBLOCK_ASSERT_OP( pb, 0 );
1140                 PBLOCK_VALIDATE_IS_INTOP( pb );
1141
1142                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) {
1143                         const char *text;
1144
1145                         pb->pb_op->orc_ava->aa_desc = NULL;
1146                         rc = slap_str2ad( (char *)value, &pb->pb_op->orc_ava->aa_desc, &text );
1147                 } else {
1148                         rc = PBLOCK_ERROR;
1149                 }
1150                 break;
1151         case SLAPI_COMPARE_VALUE:
1152                 PBLOCK_ASSERT_OP( pb, 0 );
1153                 PBLOCK_VALIDATE_IS_INTOP( pb );
1154
1155                 if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
1156                         pb->pb_op->orc_ava->aa_value = *((struct berval *)value);
1157                 else
1158                         rc = PBLOCK_ERROR;
1159                 break;
1160         case SLAPI_ABANDON_MSGID:
1161                 PBLOCK_ASSERT_OP( pb, 0 );
1162                 PBLOCK_VALIDATE_IS_INTOP( pb );
1163
1164                 if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON)
1165                         pb->pb_op->orn_msgid = *((int *)value);
1166                 else
1167                         rc = PBLOCK_ERROR;
1168                 break;
1169         case SLAPI_REQUESTOR_ISROOT:
1170         case SLAPI_IS_REPLICATED_OPERATION:
1171         case SLAPI_CONN_AUTHTYPE:
1172         case SLAPI_CONN_AUTHMETHOD:
1173         case SLAPI_X_CONN_IS_UDP:
1174         case SLAPI_CONN_CLIENTIP:
1175         case SLAPI_X_CONN_CLIENTPATH:
1176         case SLAPI_CONN_SERVERIP:
1177         case SLAPI_X_CONN_SERVERPATH:
1178                 /* These parameters cannot be set */
1179                 rc = PBLOCK_ERROR;
1180                 break;
1181         default:
1182                 rc = pblock_set_default( pb, param, value );
1183                 break;
1184         }
1185
1186         pblock_unlock( pb );
1187
1188         return rc;
1189 }
1190
1191 static void
1192 pblock_clear( Slapi_PBlock *pb ) 
1193 {
1194         pb->pb_nParams = 1;
1195 }
1196
1197 static int
1198 pblock_delete_param( Slapi_PBlock *p, int param ) 
1199 {
1200         int i;
1201
1202         pblock_lock(p);
1203
1204         for ( i = 0; i < p->pb_nParams; i++ ) { 
1205                 if ( p->pb_params[i] == param ) {
1206                         break;
1207                 }
1208         }
1209     
1210         if (i >= p->pb_nParams ) {
1211                 pblock_unlock( p );
1212                 return PBLOCK_ERROR;
1213         }
1214
1215         /* move last parameter to index of deleted parameter */
1216         if ( p->pb_nParams > 1 ) {
1217                 p->pb_params[i] = p->pb_params[p->pb_nParams - 1];
1218                 p->pb_values[i] = p->pb_values[p->pb_nParams - 1];
1219         }
1220         p->pb_nParams--;
1221
1222         pblock_unlock( p );     
1223
1224         return PBLOCK_SUCCESS;
1225 }
1226
1227 Slapi_PBlock *
1228 slapi_pblock_new(void) 
1229 {
1230         Slapi_PBlock *pb;
1231
1232         pb = (Slapi_PBlock *) ch_calloc( 1, sizeof(Slapi_PBlock) );
1233         if ( pb != NULL ) {
1234                 ldap_pvt_thread_mutex_init( &pb->pb_mutex );
1235
1236                 pb->pb_params[0] = SLAPI_IBM_PBLOCK;
1237                 pb->pb_values[0].pv_pointer = NULL;
1238                 pb->pb_nParams = 1;
1239                 pb->pb_conn = NULL;
1240                 pb->pb_op = NULL;
1241                 pb->pb_rs = NULL;
1242                 pb->pb_intop = 0;
1243         }
1244         return pb;
1245 }
1246
1247 static void
1248 pblock_destroy( Slapi_PBlock *pb )
1249 {
1250         LDAPControl **controls = NULL;
1251         LDAPMod **mods = NULL;
1252         char **attrs = NULL;
1253
1254         assert( pb != NULL );
1255
1256         pblock_get_default( pb, SLAPI_RESCONTROLS, (void **)&controls );
1257         if ( controls != NULL ) {
1258                 ldap_controls_free( controls );
1259         }
1260
1261         if ( pb->pb_intop ) {
1262                 slapi_int_connection_done_pb( pb );
1263         } else {
1264                 pblock_get_default( pb, SLAPI_MODIFY_MODS, (void **)&mods );
1265                 slapi_int_free_ldapmods( mods );
1266
1267                 pblock_get_default( pb, SLAPI_SEARCH_ATTRS, (void **)&attrs );
1268                 if ( attrs != NULL )
1269                         pb->pb_op->o_tmpfree( attrs, pb->pb_op->o_tmpmemctx );
1270         }
1271
1272         ldap_pvt_thread_mutex_destroy( &pb->pb_mutex );
1273         slapi_ch_free( (void **)&pb ); 
1274 }
1275
1276 void 
1277 slapi_pblock_destroy( Slapi_PBlock *pb ) 
1278 {
1279         if ( pb != NULL ) {
1280                 pblock_destroy( pb );
1281         }
1282 }
1283
1284 int 
1285 slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value ) 
1286 {
1287         return pblock_get( pb, arg, (void **)value );
1288 }
1289
1290 int 
1291 slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value ) 
1292 {
1293         return pblock_set( pb, arg, value );
1294 }
1295
1296 void
1297 slapi_pblock_clear( Slapi_PBlock *pb ) 
1298 {
1299         pblock_clear( pb );
1300 }
1301
1302 int 
1303 slapi_pblock_delete_param( Slapi_PBlock *p, int param ) 
1304 {
1305         return pblock_delete_param( p, param );
1306 }
1307
1308 /*
1309  * OpenLDAP extension
1310  */
1311 int
1312 slapi_int_pblock_get_first( Backend *be, Slapi_PBlock **pb )
1313 {
1314         assert( pb != NULL );
1315         *pb = SLAPI_BACKEND_PBLOCK( be );
1316         return (*pb == NULL ? LDAP_OTHER : LDAP_SUCCESS);
1317 }
1318
1319 /*
1320  * OpenLDAP extension
1321  */
1322 int
1323 slapi_int_pblock_get_next( Slapi_PBlock **pb )
1324 {
1325         assert( pb != NULL );
1326         return slapi_pblock_get( *pb, SLAPI_IBM_PBLOCK, pb );
1327 }
1328
1329 #endif /* LDAP_SLAPI */
1330