1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 2002-2021 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
25 #include <ac/string.h>
26 #include <ac/stdarg.h>
27 #include <ac/ctype.h>
28 #include <ac/unistd.h>
29
30 #include <slap.h>
31 #include <lber_pvt.h>
32 #include <slapi.h>
33
34 #ifdef LDAP_SLAPI
35
36 static struct Listener slapi_listener = {
37 BER_BVC("slapi://"),
38 BER_BVC("slapi://")
39 };
40
41 static LDAPControl **
slapi_int_dup_controls(LDAPControl ** controls)42 slapi_int_dup_controls( LDAPControl **controls )
43 {
44 LDAPControl **c;
45 size_t i;
46
47 if ( controls == NULL )
48 return NULL;
49
50 for ( i = 0; controls[i] != NULL; i++ )
51 ;
52
53 c = (LDAPControl **) slapi_ch_calloc( i + 1, sizeof(LDAPControl *) );
54
55 for ( i = 0; controls[i] != NULL; i++ ) {
56 c[i] = slapi_dup_control( controls[i] );
57 }
58
59 return c;
60 }
61
62 static int
slapi_int_result(Operation * op,SlapReply * rs)63 slapi_int_result(
64 Operation *op,
65 SlapReply *rs )
66 {
67 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
68 plugin_result_callback prc = NULL;
69 void *callback_data = NULL;
70 LDAPControl **ctrls = NULL;
71
72 assert( pb != NULL );
73
74 slapi_pblock_get( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void **)&prc );
75 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
76
77 /* we need to duplicate controls because they might go out of scope */
78 ctrls = slapi_int_dup_controls( rs->sr_ctrls );
79 slapi_pblock_set( pb, SLAPI_RESCONTROLS, ctrls );
80
81 if ( prc != NULL ) {
82 (*prc)( rs->sr_err, callback_data );
83 }
84
85 return rs->sr_err;
86 }
87
88 static int
slapi_int_search_entry(Operation * op,SlapReply * rs)89 slapi_int_search_entry(
90 Operation *op,
91 SlapReply *rs )
92 {
93 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
94 plugin_search_entry_callback psec = NULL;
95 void *callback_data = NULL;
96 int rc = LDAP_SUCCESS;
97
98 assert( pb != NULL );
99
100 slapi_pblock_get( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void **)&psec );
101 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
102
103 if ( psec != NULL ) {
104 rc = (*psec)( rs->sr_entry, callback_data );
105 }
106
107 return rc;
108 }
109
110 static int
slapi_int_search_reference(Operation * op,SlapReply * rs)111 slapi_int_search_reference(
112 Operation *op,
113 SlapReply *rs )
114 {
115 int i, rc = LDAP_SUCCESS;
116 plugin_referral_entry_callback prec = NULL;
117 void *callback_data = NULL;
118 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
119
120 assert( pb != NULL );
121
122 slapi_pblock_get( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void **)&prec );
123 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
124
125 if ( prec != NULL ) {
126 for ( i = 0; rs->sr_ref[i].bv_val != NULL; i++ ) {
127 rc = (*prec)( rs->sr_ref[i].bv_val, callback_data );
128 if ( rc != LDAP_SUCCESS ) {
129 break;
130 }
131 }
132 }
133
134 return rc;
135 }
136
137 int
slapi_int_response(Slapi_Operation * op,SlapReply * rs)138 slapi_int_response( Slapi_Operation *op, SlapReply *rs )
139 {
140 int rc;
141
142 switch ( rs->sr_type ) {
143 case REP_RESULT:
144 rc = slapi_int_result( op, rs );
145 break;
146 case REP_SEARCH:
147 rc = slapi_int_search_entry( op, rs );
148 break;
149 case REP_SEARCHREF:
150 rc = slapi_int_search_reference( op, rs );
151 break;
152 default:
153 rc = LDAP_OTHER;
154 break;
155 }
156
157 assert( rc != SLAP_CB_CONTINUE ); /* never try to send a wire response */
158
159 return rc;
160 }
161
162 static int
slapi_int_get_ctrls(Slapi_PBlock * pb)163 slapi_int_get_ctrls( Slapi_PBlock *pb )
164 {
165 LDAPControl **c;
166 int rc = LDAP_SUCCESS;
167
168 if ( pb->pb_op->o_ctrls != NULL ) {
169 for ( c = pb->pb_op->o_ctrls; *c != NULL; c++ ) {
170 rc = slap_parse_ctrl( pb->pb_op, pb->pb_rs, *c, &pb->pb_rs->sr_text );
171 if ( rc != LDAP_SUCCESS )
172 break;
173 }
174 }
175
176 return rc;
177 }
178
179 void
slapi_int_connection_init_pb(Slapi_PBlock * pb,ber_tag_t tag)180 slapi_int_connection_init_pb( Slapi_PBlock *pb, ber_tag_t tag )
181 {
182 Connection *conn;
183 Operation *op;
184 ber_len_t max = sockbuf_max_incoming;
185
186 conn = (Connection *) slapi_ch_calloc( 1, sizeof(Connection) );
187
188 LDAP_STAILQ_INIT( &conn->c_pending_ops );
189
190 op = (Operation *) slapi_ch_calloc( 1, sizeof(OperationBuffer) );
191 op->o_hdr = &((OperationBuffer *) op)->ob_hdr;
192 op->o_controls = ((OperationBuffer *) op)->ob_controls;
193
194 op->o_callback = (slap_callback *) slapi_ch_calloc( 1, sizeof(slap_callback) );
195 op->o_callback->sc_response = slapi_int_response;
196 op->o_callback->sc_cleanup = NULL;
197 op->o_callback->sc_private = pb;
198 op->o_callback->sc_next = NULL;
199
200 conn->c_pending_ops.stqh_first = op;
201
202 /* connection object authorization information */
203 conn->c_authtype = LDAP_AUTH_NONE;
204 BER_BVZERO( &conn->c_authmech );
205 BER_BVZERO( &conn->c_dn );
206 BER_BVZERO( &conn->c_ndn );
207
208 conn->c_listener = &slapi_listener;
209 ber_dupbv( &conn->c_peer_domain, (struct berval *)&slap_unknown_bv );
210 ber_dupbv( &conn->c_peer_name, (struct berval *)&slap_unknown_bv );
211
212 LDAP_STAILQ_INIT( &conn->c_ops );
213
214 BER_BVZERO( &conn->c_sasl_bind_mech );
215 conn->c_sasl_authctx = NULL;
216 conn->c_sasl_sockctx = NULL;
217 conn->c_sasl_extra = NULL;
218
219 conn->c_sb = ber_sockbuf_alloc();
220
221 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
222
223 conn->c_currentber = NULL;
224
225 /* should check status of thread calls */
226 ldap_pvt_thread_mutex_init( &conn->c_mutex );
227 ldap_pvt_thread_mutex_init( &conn->c_write1_mutex );
228 ldap_pvt_thread_cond_init( &conn->c_write1_cv );
229
230 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
231
232 conn->c_n_ops_received = 0;
233 conn->c_n_ops_executing = 0;
234 conn->c_n_ops_pending = 0;
235 conn->c_n_ops_completed = 0;
236 conn->c_n_ops_async = 0;
237
238 conn->c_n_get = 0;
239 conn->c_n_read = 0;
240 conn->c_n_write = 0;
241
242 conn->c_protocol = LDAP_VERSION3;
243
244 conn->c_activitytime = conn->c_starttime = slap_get_time();
245
246 /*
247 * A real connection ID is required, because syncrepl associates
248 * pending CSNs with unique ( connection, operation ) tuples.
249 * Setting a fake connection ID will cause slap_get_commit_csn()
250 * to return a stale value.
251 */
252 connection_assign_nextid( conn );
253
254 conn->c_conn_state = SLAP_C_ACTIVE;
255
256 conn->c_ssf = conn->c_transport_ssf = local_ssf;
257 conn->c_tls_ssf = 0;
258
259 backend_connection_init( conn );
260
261 conn->c_send_ldap_result = slap_send_ldap_result;
262 conn->c_send_search_entry = slap_send_search_entry;
263 conn->c_send_ldap_extended = slap_send_ldap_extended;
264 conn->c_send_search_reference = slap_send_search_reference;
265
266 /* operation object */
267 op->o_tag = tag;
268 op->o_protocol = LDAP_VERSION3;
269 BER_BVZERO( &op->o_authmech );
270 op->o_time = slap_get_time();
271 op->o_do_not_cache = 1;
272 op->o_threadctx = ldap_pvt_thread_pool_context();
273 op->o_tmpmemctx = NULL;
274 op->o_tmpmfuncs = &ch_mfuncs;
275 op->o_conn = conn;
276 op->o_connid = conn->c_connid;
277 op->o_bd = frontendDB;
278
279 /* extensions */
280 slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op );
281 slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
282
283 pb->pb_rs = (SlapReply *)slapi_ch_calloc( 1, sizeof(SlapReply) );
284 pb->pb_op = op;
285 pb->pb_conn = conn;
286 pb->pb_intop = 1;
287
288 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
289 }
290
291 static void
slapi_int_set_operation_dn(Slapi_PBlock * pb)292 slapi_int_set_operation_dn( Slapi_PBlock *pb )
293 {
294 Backend *be;
295 Operation *op = pb->pb_op;
296
297 if ( BER_BVISNULL( &op->o_ndn ) ) {
298 /* set to root DN */
299 be = select_backend( &op->o_req_ndn, 1 );
300 if ( be != NULL ) {
301 ber_dupbv( &op->o_dn, &be->be_rootdn );
302 ber_dupbv( &op->o_ndn, &be->be_rootndn );
303 }
304 }
305 }
306
307 void
slapi_int_connection_done_pb(Slapi_PBlock * pb)308 slapi_int_connection_done_pb( Slapi_PBlock *pb )
309 {
310 Connection *conn;
311 Operation *op;
312
313 PBLOCK_ASSERT_INTOP( pb, 0 );
314
315 conn = pb->pb_conn;
316 op = pb->pb_op;
317
318 /* free allocated DNs */
319 if ( !BER_BVISNULL( &op->o_dn ) )
320 op->o_tmpfree( op->o_dn.bv_val, op->o_tmpmemctx );
321 if ( !BER_BVISNULL( &op->o_ndn ) )
322 op->o_tmpfree( op->o_ndn.bv_val, op->o_tmpmemctx );
323
324 if ( !BER_BVISNULL( &op->o_req_dn ) )
325 op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
326 if ( !BER_BVISNULL( &op->o_req_ndn ) )
327 op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
328
329 switch ( op->o_tag ) {
330 case LDAP_REQ_MODRDN:
331 if ( !BER_BVISNULL( &op->orr_newrdn ))
332 op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );
333 if ( !BER_BVISNULL( &op->orr_nnewrdn ))
334 op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );
335 if ( op->orr_newSup != NULL ) {
336 assert( !BER_BVISNULL( op->orr_newSup ) );
337 op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx );
338 op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
339 }
340 if ( op->orr_nnewSup != NULL ) {
341 assert( !BER_BVISNULL( op->orr_nnewSup ) );
342 op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx );
343 op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
344 }
345 if ( !BER_BVISNULL( &op->orr_newDN ))
346 op->o_tmpfree( op->orr_newDN.bv_val, op->o_tmpmemctx );
347 if ( !BER_BVISNULL( &op->orr_nnewDN ))
348 op->o_tmpfree( op->orr_nnewDN.bv_val, op->o_tmpmemctx );
349 slap_mods_free( op->orr_modlist, 1 );
350 break;
351 case LDAP_REQ_ADD:
352 slap_mods_free( op->ora_modlist, 0 );
353 break;
354 case LDAP_REQ_MODIFY:
355 slap_mods_free( op->orm_modlist, 1 );
356 break;
357 case LDAP_REQ_SEARCH:
358 if ( op->ors_attrs != NULL ) {
359 op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
360 op->ors_attrs = NULL;
361 }
362 break;
363 default:
364 break;
365 }
366
367 slapi_ch_free_string( &conn->c_authmech.bv_val );
368 slapi_ch_free_string( &conn->c_dn.bv_val );
369 slapi_ch_free_string( &conn->c_ndn.bv_val );
370 slapi_ch_free_string( &conn->c_peer_domain.bv_val );
371 slapi_ch_free_string( &conn->c_peer_name.bv_val );
372
373 if ( conn->c_sb != NULL ) {
374 ber_sockbuf_free( conn->c_sb );
375 }
376
377 slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, op );
378 slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
379
380 slapi_ch_free( (void **)&pb->pb_op->o_callback );
381 slapi_ch_free( (void **)&pb->pb_op );
382 slapi_ch_free( (void **)&pb->pb_conn );
383 slapi_ch_free( (void **)&pb->pb_rs );
384 }
385
386 static int
slapi_int_func_internal_pb(Slapi_PBlock * pb,slap_operation_t which)387 slapi_int_func_internal_pb( Slapi_PBlock *pb, slap_operation_t which )
388 {
389 SlapReply *rs = pb->pb_rs;
390 int rc;
391
392 PBLOCK_ASSERT_INTOP( pb, 0 );
393
394 rc = slapi_int_get_ctrls( pb );
395 if ( rc != LDAP_SUCCESS ) {
396 rs->sr_err = rc;
397 return rc;
398 }
399
400 pb->pb_op->o_bd = frontendDB;
401 return (&frontendDB->be_bind)[which]( pb->pb_op, pb->pb_rs );
402 }
403
404 int
slapi_delete_internal_pb(Slapi_PBlock * pb)405 slapi_delete_internal_pb( Slapi_PBlock *pb )
406 {
407 if ( pb == NULL ) {
408 return -1;
409 }
410
411 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_DELETE );
412
413 slapi_int_func_internal_pb( pb, op_delete );
414
415 return 0;
416 }
417
418 int
slapi_add_internal_pb(Slapi_PBlock * pb)419 slapi_add_internal_pb( Slapi_PBlock *pb )
420 {
421 SlapReply *rs;
422 Slapi_Entry *entry_orig = NULL;
423 OpExtraDB oex;
424 int rc;
425
426 if ( pb == NULL ) {
427 return -1;
428 }
429
430 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_ADD );
431
432 rs = pb->pb_rs;
433
434 entry_orig = pb->pb_op->ora_e;
435 pb->pb_op->ora_e = NULL;
436
437 /*
438 * The caller can specify a new entry, or a target DN and set
439 * of modifications, but not both.
440 */
441 if ( entry_orig != NULL ) {
442 if ( pb->pb_op->ora_modlist != NULL || !BER_BVISNULL( &pb->pb_op->o_req_ndn )) {
443 rs->sr_err = LDAP_PARAM_ERROR;
444 goto cleanup;
445 }
446
447 assert( BER_BVISNULL( &pb->pb_op->o_req_dn ) ); /* shouldn't get set */
448 ber_dupbv( &pb->pb_op->o_req_dn, &entry_orig->e_name );
449 ber_dupbv( &pb->pb_op->o_req_ndn, &entry_orig->e_nname );
450 } else if ( pb->pb_op->ora_modlist == NULL || BER_BVISNULL( &pb->pb_op->o_req_ndn )) {
451 rs->sr_err = LDAP_PARAM_ERROR;
452 goto cleanup;
453 }
454
455 pb->pb_op->ora_e = (Entry *)slapi_ch_calloc( 1, sizeof(Entry) );
456 ber_dupbv( &pb->pb_op->ora_e->e_name, &pb->pb_op->o_req_dn );
457 ber_dupbv( &pb->pb_op->ora_e->e_nname, &pb->pb_op->o_req_ndn );
458
459 if ( entry_orig != NULL ) {
460 assert( pb->pb_op->ora_modlist == NULL );
461
462 rs->sr_err = slap_entry2mods( entry_orig, &pb->pb_op->ora_modlist,
463 &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) );
464 if ( rs->sr_err != LDAP_SUCCESS ) {
465 goto cleanup;
466 }
467 } else {
468 assert( pb->pb_op->ora_modlist != NULL );
469 }
470
471 rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->ora_modlist, &rs->sr_text,
472 pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL );
473 if ( rs->sr_err != LDAP_SUCCESS ) {
474 goto cleanup;
475 }
476
477 /* Duplicate the values, because we may call slapi_entry_free() */
478 rs->sr_err = slap_mods2entry( pb->pb_op->ora_modlist, &pb->pb_op->ora_e,
479 1, 0, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) );
480 if ( rs->sr_err != LDAP_SUCCESS ) {
481 goto cleanup;
482 }
483
484 oex.oe.oe_key = (void *)do_add;
485 oex.oe_db = NULL;
486 LDAP_SLIST_INSERT_HEAD(&pb->pb_op->o_extra, &oex.oe, oe_next);
487 rc = slapi_int_func_internal_pb( pb, op_add );
488 LDAP_SLIST_REMOVE(&pb->pb_op->o_extra, &oex.oe, OpExtra, oe_next);
489
490 if ( !rc ) {
491 if ( pb->pb_op->ora_e != NULL && oex.oe_db != NULL ) {
492 BackendDB *bd = pb->pb_op->o_bd;
493
494 pb->pb_op->o_bd = oex.oe_db;
495 be_entry_release_w( pb->pb_op, pb->pb_op->ora_e );
496 pb->pb_op->ora_e = NULL;
497 pb->pb_op->o_bd = bd;
498 }
499 }
500
501 cleanup:
502
503 if ( pb->pb_op->ora_e != NULL ) {
504 slapi_entry_free( pb->pb_op->ora_e );
505 pb->pb_op->ora_e = NULL;
506 }
507 if ( entry_orig != NULL ) {
508 pb->pb_op->ora_e = entry_orig;
509 slap_mods_free( pb->pb_op->ora_modlist, 1 );
510 pb->pb_op->ora_modlist = NULL;
511 }
512
513 return 0;
514 }
515
516 int
slapi_modrdn_internal_pb(Slapi_PBlock * pb)517 slapi_modrdn_internal_pb( Slapi_PBlock *pb )
518 {
519 if ( pb == NULL ) {
520 return -1;
521 }
522
523 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODRDN );
524
525 if ( BER_BVISEMPTY( &pb->pb_op->o_req_ndn ) ) {
526 pb->pb_rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
527 goto cleanup;
528 }
529
530 slapi_int_func_internal_pb( pb, op_modrdn );
531
532 cleanup:
533
534 return 0;
535 }
536
537 int
slapi_modify_internal_pb(Slapi_PBlock * pb)538 slapi_modify_internal_pb( Slapi_PBlock *pb )
539 {
540 SlapReply *rs;
541
542 if ( pb == NULL ) {
543 return -1;
544 }
545
546 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODIFY );
547
548 rs = pb->pb_rs;
549
550 if ( pb->pb_op->orm_modlist == NULL ) {
551 rs->sr_err = LDAP_PARAM_ERROR;
552 goto cleanup;
553 }
554
555 if ( BER_BVISEMPTY( &pb->pb_op->o_req_ndn ) ) {
556 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
557 goto cleanup;
558 }
559
560 rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->orm_modlist,
561 &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL );
562 if ( rs->sr_err != LDAP_SUCCESS ) {
563 goto cleanup;
564 }
565
566 slapi_int_func_internal_pb( pb, op_modify );
567
568 cleanup:
569
570 return 0;
571 }
572
573 static int
slapi_int_search_entry_callback(Slapi_Entry * entry,void * callback_data)574 slapi_int_search_entry_callback( Slapi_Entry *entry, void *callback_data )
575 {
576 int nentries = 0, i = 0;
577 Slapi_Entry **head = NULL, **tp;
578 Slapi_PBlock *pb = (Slapi_PBlock *)callback_data;
579
580 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH );
581
582 entry = slapi_entry_dup( entry );
583 if ( entry == NULL ) {
584 return LDAP_NO_MEMORY;
585 }
586
587 slapi_pblock_get( pb, SLAPI_NENTRIES, &nentries );
588 slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );
589
590 i = nentries + 1;
591 if ( nentries == 0 ) {
592 tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );
593 if ( tp == NULL ) {
594 slapi_entry_free( entry );
595 return LDAP_NO_MEMORY;
596 }
597
598 tp[0] = entry;
599 } else {
600 tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,
601 sizeof(Slapi_Entry *) * ( i + 1 ) );
602 if ( tp == NULL ) {
603 slapi_entry_free( entry );
604 return LDAP_NO_MEMORY;
605 }
606 tp[i - 1] = entry;
607 }
608 tp[i] = NULL;
609
610 slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );
611 slapi_pblock_set( pb, SLAPI_NENTRIES, (void *)&i );
612
613 return LDAP_SUCCESS;
614 }
615
616 int
slapi_search_internal_pb(Slapi_PBlock * pb)617 slapi_search_internal_pb( Slapi_PBlock *pb )
618 {
619 return slapi_search_internal_callback_pb( pb,
620 (void *)pb,
621 NULL,
622 slapi_int_search_entry_callback,
623 NULL );
624 }
625
626 int
slapi_search_internal_callback_pb(Slapi_PBlock * pb,void * callback_data,plugin_result_callback prc,plugin_search_entry_callback psec,plugin_referral_entry_callback prec)627 slapi_search_internal_callback_pb( Slapi_PBlock *pb,
628 void *callback_data,
629 plugin_result_callback prc,
630 plugin_search_entry_callback psec,
631 plugin_referral_entry_callback prec )
632 {
633 int free_filter = 0;
634 SlapReply *rs;
635
636 if ( pb == NULL ) {
637 return -1;
638 }
639
640 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH );
641
642 rs = pb->pb_rs;
643
644 /* search callback and arguments */
645 slapi_pblock_set( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void *)prc );
646 slapi_pblock_set( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void *)psec );
647 slapi_pblock_set( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void *)prec );
648 slapi_pblock_set( pb, SLAPI_X_INTOP_CALLBACK_DATA, (void *)callback_data );
649
650 if ( BER_BVISEMPTY( &pb->pb_op->ors_filterstr )) {
651 rs->sr_err = LDAP_PARAM_ERROR;
652 goto cleanup;
653 }
654
655 if ( pb->pb_op->ors_filter == NULL ) {
656 pb->pb_op->ors_filter = slapi_str2filter( pb->pb_op->ors_filterstr.bv_val );
657 if ( pb->pb_op->ors_filter == NULL ) {
658 rs->sr_err = LDAP_PROTOCOL_ERROR;
659 goto cleanup;
660 }
661
662 free_filter = 1;
663 }
664
665 slapi_int_func_internal_pb( pb, op_search );
666
667 cleanup:
668 if ( free_filter ) {
669 slapi_filter_free( pb->pb_op->ors_filter, 1 );
670 pb->pb_op->ors_filter = NULL;
671 }
672
673 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_RESULT_CALLBACK );
674 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK );
675 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK );
676 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_CALLBACK_DATA );
677
678 return 0;
679 }
680
681 /* Wrappers for old API */
682
683 void
slapi_search_internal_set_pb(Slapi_PBlock * pb,const char * base,int scope,const char * filter,char ** attrs,int attrsonly,LDAPControl ** controls,const char * uniqueid,Slapi_ComponentId * plugin_identity,int operation_flags)684 slapi_search_internal_set_pb( Slapi_PBlock *pb,
685 const char *base,
686 int scope,
687 const char *filter,
688 char **attrs,
689 int attrsonly,
690 LDAPControl **controls,
691 const char *uniqueid,
692 Slapi_ComponentId *plugin_identity,
693 int operation_flags )
694 {
695 int no_limit = SLAP_NO_LIMIT;
696 int deref = LDAP_DEREF_NEVER;
697
698 slapi_int_connection_init_pb( pb, LDAP_REQ_SEARCH );
699 slapi_pblock_set( pb, SLAPI_SEARCH_TARGET, (void *)base );
700 slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, (void *)&scope );
701 slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, (void *)0 );
702 slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, (void *)filter );
703 slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, (void *)attrs );
704 slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, (void *)&attrsonly );
705 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
706 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
707 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
708 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags );
709 slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, (void *)&deref );
710 slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, (void *)&no_limit );
711 slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, (void *)&no_limit );
712
713 slapi_int_set_operation_dn( pb );
714 }
715
716 Slapi_PBlock *
slapi_search_internal(char * ldn,int scope,char * filStr,LDAPControl ** controls,char ** attrs,int attrsonly)717 slapi_search_internal(
718 char *ldn,
719 int scope,
720 char *filStr,
721 LDAPControl **controls,
722 char **attrs,
723 int attrsonly )
724 {
725 Slapi_PBlock *pb;
726
727 pb = slapi_pblock_new();
728
729 slapi_search_internal_set_pb( pb, ldn, scope, filStr,
730 attrs, attrsonly,
731 controls, NULL, NULL, 0 );
732
733 slapi_search_internal_pb( pb );
734
735 return pb;
736 }
737
738 void
slapi_modify_internal_set_pb(Slapi_PBlock * pb,const char * dn,LDAPMod ** mods,LDAPControl ** controls,const char * uniqueid,Slapi_ComponentId * plugin_identity,int operation_flags)739 slapi_modify_internal_set_pb( Slapi_PBlock *pb,
740 const char *dn,
741 LDAPMod **mods,
742 LDAPControl **controls,
743 const char *uniqueid,
744 Slapi_ComponentId *plugin_identity,
745 int operation_flags )
746 {
747 slapi_int_connection_init_pb( pb, LDAP_REQ_MODIFY );
748 slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn );
749 slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)mods );
750 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
751 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
752 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
753 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags );
754 slapi_int_set_operation_dn( pb );
755 }
756
757 /* Function : slapi_modify_internal
758 *
759 * Description: Plugin functions call this routine to modify an entry
760 * in the backend directly
761 * Return values : LDAP_SUCCESS
762 * LDAP_PARAM_ERROR
763 * LDAP_NO_MEMORY
764 * LDAP_OTHER
765 * LDAP_UNWILLING_TO_PERFORM
766 */
767 Slapi_PBlock *
slapi_modify_internal(char * ldn,LDAPMod ** mods,LDAPControl ** controls,int log_change)768 slapi_modify_internal(
769 char *ldn,
770 LDAPMod **mods,
771 LDAPControl **controls,
772 int log_change )
773 {
774 Slapi_PBlock *pb;
775
776 pb = slapi_pblock_new();
777
778 slapi_modify_internal_set_pb( pb, ldn, mods, controls, NULL, NULL, 0 );
779 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
780 slapi_modify_internal_pb( pb );
781
782 return pb;
783 }
784
785 int
slapi_add_internal_set_pb(Slapi_PBlock * pb,const char * dn,LDAPMod ** attrs,LDAPControl ** controls,Slapi_ComponentId * plugin_identity,int operation_flags)786 slapi_add_internal_set_pb( Slapi_PBlock *pb,
787 const char *dn,
788 LDAPMod **attrs,
789 LDAPControl **controls,
790 Slapi_ComponentId *plugin_identity,
791 int operation_flags )
792 {
793 slapi_int_connection_init_pb( pb, LDAP_REQ_ADD );
794 slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn );
795 slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)attrs );
796 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
797 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
798 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags );
799 slapi_int_set_operation_dn( pb );
800
801 return 0;
802 }
803
804 Slapi_PBlock *
slapi_add_internal(char * dn,LDAPMod ** attrs,LDAPControl ** controls,int log_change)805 slapi_add_internal(
806 char * dn,
807 LDAPMod **attrs,
808 LDAPControl **controls,
809 int log_change )
810 {
811 Slapi_PBlock *pb;
812
813 pb = slapi_pblock_new();
814
815 slapi_add_internal_set_pb( pb, dn, attrs, controls, NULL, 0);
816 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
817 slapi_add_internal_pb( pb );
818
819 return pb;
820 }
821
822 void
slapi_add_entry_internal_set_pb(Slapi_PBlock * pb,Slapi_Entry * e,LDAPControl ** controls,Slapi_ComponentId * plugin_identity,int operation_flags)823 slapi_add_entry_internal_set_pb( Slapi_PBlock *pb,
824 Slapi_Entry *e,
825 LDAPControl **controls,
826 Slapi_ComponentId *plugin_identity,
827 int operation_flags )
828 {
829 slapi_int_connection_init_pb( pb, LDAP_REQ_ADD );
830 slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e );
831 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
832 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
833 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags );
834 slapi_int_set_operation_dn( pb );
835 }
836
837 Slapi_PBlock *
slapi_add_entry_internal(Slapi_Entry * e,LDAPControl ** controls,int log_change)838 slapi_add_entry_internal(
839 Slapi_Entry *e,
840 LDAPControl **controls,
841 int log_change )
842 {
843 Slapi_PBlock *pb;
844
845 pb = slapi_pblock_new();
846
847 slapi_add_entry_internal_set_pb( pb, e, controls, NULL, 0 );
848 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
849 slapi_add_internal_pb( pb );
850
851 return pb;
852 }
853
854 void
slapi_rename_internal_set_pb(Slapi_PBlock * pb,const char * olddn,const char * newrdn,const char * newsuperior,int deloldrdn,LDAPControl ** controls,const char * uniqueid,Slapi_ComponentId * plugin_identity,int operation_flags)855 slapi_rename_internal_set_pb( Slapi_PBlock *pb,
856 const char *olddn,
857 const char *newrdn,
858 const char *newsuperior,
859 int deloldrdn,
860 LDAPControl **controls,
861 const char *uniqueid,
862 Slapi_ComponentId *plugin_identity,
863 int operation_flags )
864 {
865 slapi_int_connection_init_pb( pb, LDAP_REQ_MODRDN );
866 slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)olddn );
867 slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn );
868 slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR, (void *)newsuperior );
869 slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)&deloldrdn );
870 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
871 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
872 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
873 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags );
874 slap_modrdn2mods( pb->pb_op, pb->pb_rs );
875 slapi_int_set_operation_dn( pb );
876 }
877
878 /* Function : slapi_modrdn_internal
879 *
880 * Description : Plugin functions call this routine to modify the rdn
881 * of an entry in the backend directly
882 * Return values : LDAP_SUCCESS
883 * LDAP_PARAM_ERROR
884 * LDAP_NO_MEMORY
885 * LDAP_OTHER
886 * LDAP_UNWILLING_TO_PERFORM
887 *
888 * NOTE: This function does not support the "newSuperior" option from LDAP V3.
889 */
890 Slapi_PBlock *
slapi_modrdn_internal(char * olddn,char * lnewrdn,int deloldrdn,LDAPControl ** controls,int log_change)891 slapi_modrdn_internal(
892 char *olddn,
893 char *lnewrdn,
894 int deloldrdn,
895 LDAPControl **controls,
896 int log_change )
897 {
898 Slapi_PBlock *pb;
899
900 pb = slapi_pblock_new ();
901
902 slapi_rename_internal_set_pb( pb, olddn, lnewrdn, NULL,
903 deloldrdn, controls, NULL, NULL, 0 );
904 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
905 slapi_modrdn_internal_pb( pb );
906
907 return pb;
908 }
909
910 void
slapi_delete_internal_set_pb(Slapi_PBlock * pb,const char * dn,LDAPControl ** controls,const char * uniqueid,Slapi_ComponentId * plugin_identity,int operation_flags)911 slapi_delete_internal_set_pb( Slapi_PBlock *pb,
912 const char *dn,
913 LDAPControl **controls,
914 const char *uniqueid,
915 Slapi_ComponentId *plugin_identity,
916 int operation_flags )
917 {
918 slapi_int_connection_init_pb( pb, LDAP_REQ_DELETE );
919 slapi_pblock_set( pb, SLAPI_TARGET_DN, (void *)dn );
920 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
921 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
922 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
923 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags );
924 slapi_int_set_operation_dn( pb );
925 }
926
927 /* Function : slapi_delete_internal
928 *
929 * Description : Plugin functions call this routine to delete an entry
930 * in the backend directly
931 * Return values : LDAP_SUCCESS
932 * LDAP_PARAM_ERROR
933 * LDAP_NO_MEMORY
934 * LDAP_OTHER
935 * LDAP_UNWILLING_TO_PERFORM
936 */
937 Slapi_PBlock *
slapi_delete_internal(char * ldn,LDAPControl ** controls,int log_change)938 slapi_delete_internal(
939 char *ldn,
940 LDAPControl **controls,
941 int log_change )
942 {
943 Slapi_PBlock *pb;
944
945 pb = slapi_pblock_new();
946
947 slapi_delete_internal_set_pb( pb, ldn, controls, NULL, NULL, 0 );
948 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
949 slapi_delete_internal_pb( pb );
950
951 return pb;
952 }
953
954 #endif /* LDAP_SLAPI */
955