1 /* $NetBSD: slapi_ops.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_ops.c,v 1.3 2021/08/14 16:15:02 christos Exp $");
27
28 #include "portable.h"
29
30 #include <ac/string.h>
31 #include <ac/stdarg.h>
32 #include <ac/ctype.h>
33 #include <ac/unistd.h>
34
35 #include <slap.h>
36 #include <lber_pvt.h>
37 #include <slapi.h>
38
39 #ifdef LDAP_SLAPI
40
41 static struct Listener slapi_listener = {
42 BER_BVC("slapi://"),
43 BER_BVC("slapi://")
44 };
45
46 static LDAPControl **
slapi_int_dup_controls(LDAPControl ** controls)47 slapi_int_dup_controls( LDAPControl **controls )
48 {
49 LDAPControl **c;
50 size_t i;
51
52 if ( controls == NULL )
53 return NULL;
54
55 for ( i = 0; controls[i] != NULL; i++ )
56 ;
57
58 c = (LDAPControl **) slapi_ch_calloc( i + 1, sizeof(LDAPControl *) );
59
60 for ( i = 0; controls[i] != NULL; i++ ) {
61 c[i] = slapi_dup_control( controls[i] );
62 }
63
64 return c;
65 }
66
67 static int
slapi_int_result(Operation * op,SlapReply * rs)68 slapi_int_result(
69 Operation *op,
70 SlapReply *rs )
71 {
72 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
73 plugin_result_callback prc = NULL;
74 void *callback_data = NULL;
75 LDAPControl **ctrls = NULL;
76
77 assert( pb != NULL );
78
79 slapi_pblock_get( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void **)&prc );
80 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
81
82 /* we need to duplicate controls because they might go out of scope */
83 ctrls = slapi_int_dup_controls( rs->sr_ctrls );
84 slapi_pblock_set( pb, SLAPI_RESCONTROLS, ctrls );
85
86 if ( prc != NULL ) {
87 (*prc)( rs->sr_err, callback_data );
88 }
89
90 return rs->sr_err;
91 }
92
93 static int
slapi_int_search_entry(Operation * op,SlapReply * rs)94 slapi_int_search_entry(
95 Operation *op,
96 SlapReply *rs )
97 {
98 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
99 plugin_search_entry_callback psec = NULL;
100 void *callback_data = NULL;
101 int rc = LDAP_SUCCESS;
102
103 assert( pb != NULL );
104
105 slapi_pblock_get( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void **)&psec );
106 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
107
108 if ( psec != NULL ) {
109 rc = (*psec)( rs->sr_entry, callback_data );
110 }
111
112 return rc;
113 }
114
115 static int
slapi_int_search_reference(Operation * op,SlapReply * rs)116 slapi_int_search_reference(
117 Operation *op,
118 SlapReply *rs )
119 {
120 int i, rc = LDAP_SUCCESS;
121 plugin_referral_entry_callback prec = NULL;
122 void *callback_data = NULL;
123 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
124
125 assert( pb != NULL );
126
127 slapi_pblock_get( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void **)&prec );
128 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
129
130 if ( prec != NULL ) {
131 for ( i = 0; rs->sr_ref[i].bv_val != NULL; i++ ) {
132 rc = (*prec)( rs->sr_ref[i].bv_val, callback_data );
133 if ( rc != LDAP_SUCCESS ) {
134 break;
135 }
136 }
137 }
138
139 return rc;
140 }
141
142 int
slapi_int_response(Slapi_Operation * op,SlapReply * rs)143 slapi_int_response( Slapi_Operation *op, SlapReply *rs )
144 {
145 int rc;
146
147 switch ( rs->sr_type ) {
148 case REP_RESULT:
149 rc = slapi_int_result( op, rs );
150 break;
151 case REP_SEARCH:
152 rc = slapi_int_search_entry( op, rs );
153 break;
154 case REP_SEARCHREF:
155 rc = slapi_int_search_reference( op, rs );
156 break;
157 default:
158 rc = LDAP_OTHER;
159 break;
160 }
161
162 assert( rc != SLAP_CB_CONTINUE ); /* never try to send a wire response */
163
164 return rc;
165 }
166
167 static int
slapi_int_get_ctrls(Slapi_PBlock * pb)168 slapi_int_get_ctrls( Slapi_PBlock *pb )
169 {
170 LDAPControl **c;
171 int rc = LDAP_SUCCESS;
172
173 if ( pb->pb_op->o_ctrls != NULL ) {
174 for ( c = pb->pb_op->o_ctrls; *c != NULL; c++ ) {
175 rc = slap_parse_ctrl( pb->pb_op, pb->pb_rs, *c, &pb->pb_rs->sr_text );
176 if ( rc != LDAP_SUCCESS )
177 break;
178 }
179 }
180
181 return rc;
182 }
183
184 void
slapi_int_connection_init_pb(Slapi_PBlock * pb,ber_tag_t tag)185 slapi_int_connection_init_pb( Slapi_PBlock *pb, ber_tag_t tag )
186 {
187 Connection *conn;
188 Operation *op;
189 ber_len_t max = sockbuf_max_incoming;
190
191 conn = (Connection *) slapi_ch_calloc( 1, sizeof(Connection) );
192
193 LDAP_STAILQ_INIT( &conn->c_pending_ops );
194
195 op = (Operation *) slapi_ch_calloc( 1, sizeof(OperationBuffer) );
196 op->o_hdr = &((OperationBuffer *) op)->ob_hdr;
197 op->o_controls = ((OperationBuffer *) op)->ob_controls;
198
199 op->o_callback = (slap_callback *) slapi_ch_calloc( 1, sizeof(slap_callback) );
200 op->o_callback->sc_response = slapi_int_response;
201 op->o_callback->sc_cleanup = NULL;
202 op->o_callback->sc_private = pb;
203 op->o_callback->sc_next = NULL;
204
205 conn->c_pending_ops.stqh_first = op;
206
207 /* connection object authorization information */
208 conn->c_authtype = LDAP_AUTH_NONE;
209 BER_BVZERO( &conn->c_authmech );
210 BER_BVZERO( &conn->c_dn );
211 BER_BVZERO( &conn->c_ndn );
212
213 conn->c_listener = &slapi_listener;
214 ber_dupbv( &conn->c_peer_domain, (struct berval *)&slap_unknown_bv );
215 ber_dupbv( &conn->c_peer_name, (struct berval *)&slap_unknown_bv );
216
217 LDAP_STAILQ_INIT( &conn->c_ops );
218
219 BER_BVZERO( &conn->c_sasl_bind_mech );
220 conn->c_sasl_authctx = NULL;
221 conn->c_sasl_sockctx = NULL;
222 conn->c_sasl_extra = NULL;
223
224 conn->c_sb = ber_sockbuf_alloc();
225
226 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
227
228 conn->c_currentber = NULL;
229
230 /* should check status of thread calls */
231 ldap_pvt_thread_mutex_init( &conn->c_mutex );
232 ldap_pvt_thread_mutex_init( &conn->c_write1_mutex );
233 ldap_pvt_thread_cond_init( &conn->c_write1_cv );
234
235 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
236
237 conn->c_n_ops_received = 0;
238 conn->c_n_ops_executing = 0;
239 conn->c_n_ops_pending = 0;
240 conn->c_n_ops_completed = 0;
241
242 conn->c_n_get = 0;
243 conn->c_n_read = 0;
244 conn->c_n_write = 0;
245
246 conn->c_protocol = LDAP_VERSION3;
247
248 conn->c_activitytime = conn->c_starttime = slap_get_time();
249
250 /*
251 * A real connection ID is required, because syncrepl associates
252 * pending CSNs with unique ( connection, operation ) tuples.
253 * Setting a fake connection ID will cause slap_get_commit_csn()
254 * to return a stale value.
255 */
256 connection_assign_nextid( conn );
257
258 conn->c_conn_state = SLAP_C_ACTIVE;
259
260 conn->c_ssf = conn->c_transport_ssf = local_ssf;
261 conn->c_tls_ssf = 0;
262
263 backend_connection_init( conn );
264
265 conn->c_send_ldap_result = slap_send_ldap_result;
266 conn->c_send_search_entry = slap_send_search_entry;
267 conn->c_send_ldap_extended = slap_send_ldap_extended;
268 conn->c_send_search_reference = slap_send_search_reference;
269
270 /* operation object */
271 op->o_tag = tag;
272 op->o_protocol = LDAP_VERSION3;
273 BER_BVZERO( &op->o_authmech );
274 op->o_time = slap_get_time();
275 op->o_do_not_cache = 1;
276 op->o_threadctx = ldap_pvt_thread_pool_context();
277 op->o_tmpmemctx = NULL;
278 op->o_tmpmfuncs = &ch_mfuncs;
279 op->o_conn = conn;
280 op->o_connid = conn->c_connid;
281 op->o_bd = frontendDB;
282
283 /* extensions */
284 slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op );
285 slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
286
287 pb->pb_rs = (SlapReply *)slapi_ch_calloc( 1, sizeof(SlapReply) );
288 pb->pb_op = op;
289 pb->pb_conn = conn;
290 pb->pb_intop = 1;
291
292 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
293 }
294
295 static void
slapi_int_set_operation_dn(Slapi_PBlock * pb)296 slapi_int_set_operation_dn( Slapi_PBlock *pb )
297 {
298 Backend *be;
299 Operation *op = pb->pb_op;
300
301 if ( BER_BVISNULL( &op->o_ndn ) ) {
302 /* set to root DN */
303 be = select_backend( &op->o_req_ndn, 1 );
304 if ( be != NULL ) {
305 ber_dupbv( &op->o_dn, &be->be_rootdn );
306 ber_dupbv( &op->o_ndn, &be->be_rootndn );
307 }
308 }
309 }
310
311 void
slapi_int_connection_done_pb(Slapi_PBlock * pb)312 slapi_int_connection_done_pb( Slapi_PBlock *pb )
313 {
314 Connection *conn;
315 Operation *op;
316
317 PBLOCK_ASSERT_INTOP( pb, 0 );
318
319 conn = pb->pb_conn;
320 op = pb->pb_op;
321
322 /* free allocated DNs */
323 if ( !BER_BVISNULL( &op->o_dn ) )
324 op->o_tmpfree( op->o_dn.bv_val, op->o_tmpmemctx );
325 if ( !BER_BVISNULL( &op->o_ndn ) )
326 op->o_tmpfree( op->o_ndn.bv_val, op->o_tmpmemctx );
327
328 if ( !BER_BVISNULL( &op->o_req_dn ) )
329 op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
330 if ( !BER_BVISNULL( &op->o_req_ndn ) )
331 op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
332
333 switch ( op->o_tag ) {
334 case LDAP_REQ_MODRDN:
335 if ( !BER_BVISNULL( &op->orr_newrdn ))
336 op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );
337 if ( !BER_BVISNULL( &op->orr_nnewrdn ))
338 op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );
339 if ( op->orr_newSup != NULL ) {
340 assert( !BER_BVISNULL( op->orr_newSup ) );
341 op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx );
342 op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
343 }
344 if ( op->orr_nnewSup != NULL ) {
345 assert( !BER_BVISNULL( op->orr_nnewSup ) );
346 op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx );
347 op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
348 }
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