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