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