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