1 /* $NetBSD: slapi_ops.c,v 1.4 2025/09/05 21:16:33 christos Exp $ */ 2 3 /* $OpenLDAP$ */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 2002-2024 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.4 2025/09/05 21:16:33 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 ** 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 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 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 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 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 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 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 conn->c_n_ops_async = 0; 242 243 conn->c_n_get = 0; 244 conn->c_n_read = 0; 245 conn->c_n_write = 0; 246 247 conn->c_protocol = LDAP_VERSION3; 248 249 conn->c_activitytime = conn->c_starttime = slap_get_time(); 250 251 /* 252 * A real connection ID is required, because syncrepl associates 253 * pending CSNs with unique ( connection, operation ) tuples. 254 * Setting a fake connection ID will cause slap_get_commit_csn() 255 * to return a stale value. 256 */ 257 connection_assign_nextid( conn ); 258 259 conn->c_conn_state = SLAP_C_ACTIVE; 260 261 conn->c_ssf = conn->c_transport_ssf = local_ssf; 262 conn->c_tls_ssf = 0; 263 264 backend_connection_init( conn ); 265 266 conn->c_send_ldap_result = slap_send_ldap_result; 267 conn->c_send_search_entry = slap_send_search_entry; 268 conn->c_send_ldap_extended = slap_send_ldap_extended; 269 conn->c_send_search_reference = slap_send_search_reference; 270 271 /* operation object */ 272 op->o_tag = tag; 273 op->o_protocol = LDAP_VERSION3; 274 BER_BVZERO( &op->o_authmech ); 275 op->o_time = slap_get_time(); 276 op->o_do_not_cache = 1; 277 op->o_threadctx = ldap_pvt_thread_pool_context(); 278 op->o_tmpmemctx = NULL; 279 op->o_tmpmfuncs = &ch_mfuncs; 280 op->o_conn = conn; 281 op->o_connid = conn->c_connid; 282 op->o_bd = frontendDB; 283 284 /* extensions */ 285 slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op ); 286 slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn ); 287 288 pb->pb_rs = (SlapReply *)slapi_ch_calloc( 1, sizeof(SlapReply) ); 289 pb->pb_op = op; 290 pb->pb_conn = conn; 291 pb->pb_intop = 1; 292 293 ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); 294 } 295 296 static void 297 slapi_int_set_operation_dn( Slapi_PBlock *pb ) 298 { 299 Backend *be; 300 Operation *op = pb->pb_op; 301 302 if ( BER_BVISNULL( &op->o_ndn ) ) { 303 /* set to root DN */ 304 be = select_backend( &op->o_req_ndn, 1 ); 305 if ( be != NULL ) { 306 ber_dupbv( &op->o_dn, &be->be_rootdn ); 307 ber_dupbv( &op->o_ndn, &be->be_rootndn ); 308 } 309 } 310 } 311 312 void 313 slapi_int_connection_done_pb( Slapi_PBlock *pb ) 314 { 315 Connection *conn; 316 Operation *op; 317 318 PBLOCK_ASSERT_INTOP( pb, 0 ); 319 320 conn = pb->pb_conn; 321 op = pb->pb_op; 322 323 /* free allocated DNs */ 324 if ( !BER_BVISNULL( &op->o_dn ) ) 325 op->o_tmpfree( op->o_dn.bv_val, op->o_tmpmemctx ); 326 if ( !BER_BVISNULL( &op->o_ndn ) ) 327 op->o_tmpfree( op->o_ndn.bv_val, op->o_tmpmemctx ); 328 329 if ( !BER_BVISNULL( &op->o_req_dn ) ) 330 op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); 331 if ( !BER_BVISNULL( &op->o_req_ndn ) ) 332 op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); 333 334 switch ( op->o_tag ) { 335 case LDAP_REQ_MODRDN: 336 if ( !BER_BVISNULL( &op->orr_newrdn )) 337 op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx ); 338 if ( !BER_BVISNULL( &op->orr_nnewrdn )) 339 op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx ); 340 if ( op->orr_newSup != NULL ) { 341 assert( !BER_BVISNULL( op->orr_newSup ) ); 342 op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx ); 343 op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx ); 344 } 345 if ( op->orr_nnewSup != NULL ) { 346 assert( !BER_BVISNULL( op->orr_nnewSup ) ); 347 op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx ); 348 op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx ); 349 } 350 if ( !BER_BVISNULL( &op->orr_newDN )) 351 op->o_tmpfree( op->orr_newDN.bv_val, op->o_tmpmemctx ); 352 if ( !BER_BVISNULL( &op->orr_nnewDN )) 353 op->o_tmpfree( op->orr_nnewDN.bv_val, op->o_tmpmemctx ); 354 slap_mods_free( op->orr_modlist, 1 ); 355 break; 356 case LDAP_REQ_ADD: 357 slap_mods_free( op->ora_modlist, 0 ); 358 break; 359 case LDAP_REQ_MODIFY: 360 slap_mods_free( op->orm_modlist, 1 ); 361 break; 362 case LDAP_REQ_SEARCH: 363 if ( op->ors_attrs != NULL ) { 364 op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx ); 365 op->ors_attrs = NULL; 366 } 367 break; 368 default: 369 break; 370 } 371 372 slapi_ch_free_string( &conn->c_authmech.bv_val ); 373 slapi_ch_free_string( &conn->c_dn.bv_val ); 374 slapi_ch_free_string( &conn->c_ndn.bv_val ); 375 slapi_ch_free_string( &conn->c_peer_domain.bv_val ); 376 slapi_ch_free_string( &conn->c_peer_name.bv_val ); 377 378 if ( conn->c_sb != NULL ) { 379 ber_sockbuf_free( conn->c_sb ); 380 } 381 382 slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, op ); 383 slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, conn ); 384 385 slapi_ch_free( (void **)&pb->pb_op->o_callback ); 386 slapi_ch_free( (void **)&pb->pb_op ); 387 slapi_ch_free( (void **)&pb->pb_conn ); 388 slapi_ch_free( (void **)&pb->pb_rs ); 389 } 390 391 static int 392 slapi_int_func_internal_pb( Slapi_PBlock *pb, slap_operation_t which ) 393 { 394 SlapReply *rs = pb->pb_rs; 395 int rc; 396 397 PBLOCK_ASSERT_INTOP( pb, 0 ); 398 399 rc = slapi_int_get_ctrls( pb ); 400 if ( rc != LDAP_SUCCESS ) { 401 rs->sr_err = rc; 402 return rc; 403 } 404 405 pb->pb_op->o_bd = frontendDB; 406 return (&frontendDB->be_bind)[which]( pb->pb_op, pb->pb_rs ); 407 } 408 409 int 410 slapi_delete_internal_pb( Slapi_PBlock *pb ) 411 { 412 if ( pb == NULL ) { 413 return -1; 414 } 415 416 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_DELETE ); 417 418 slapi_int_func_internal_pb( pb, op_delete ); 419 420 return 0; 421 } 422 423 int 424 slapi_add_internal_pb( Slapi_PBlock *pb ) 425 { 426 SlapReply *rs; 427 Slapi_Entry *entry_orig = NULL; 428 OpExtraDB oex; 429 int rc; 430 431 if ( pb == NULL ) { 432 return -1; 433 } 434 435 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_ADD ); 436 437 rs = pb->pb_rs; 438 439 entry_orig = pb->pb_op->ora_e; 440 pb->pb_op->ora_e = NULL; 441 442 /* 443 * The caller can specify a new entry, or a target DN and set 444 * of modifications, but not both. 445 */ 446 if ( entry_orig != NULL ) { 447 if ( pb->pb_op->ora_modlist != NULL || !BER_BVISNULL( &pb->pb_op->o_req_ndn )) { 448 rs->sr_err = LDAP_PARAM_ERROR; 449 goto cleanup; 450 } 451 452 assert( BER_BVISNULL( &pb->pb_op->o_req_dn ) ); /* shouldn't get set */ 453 ber_dupbv( &pb->pb_op->o_req_dn, &entry_orig->e_name ); 454 ber_dupbv( &pb->pb_op->o_req_ndn, &entry_orig->e_nname ); 455 } else if ( pb->pb_op->ora_modlist == NULL || BER_BVISNULL( &pb->pb_op->o_req_ndn )) { 456 rs->sr_err = LDAP_PARAM_ERROR; 457 goto cleanup; 458 } 459 460 pb->pb_op->ora_e = (Entry *)slapi_ch_calloc( 1, sizeof(Entry) ); 461 ber_dupbv( &pb->pb_op->ora_e->e_name, &pb->pb_op->o_req_dn ); 462 ber_dupbv( &pb->pb_op->ora_e->e_nname, &pb->pb_op->o_req_ndn ); 463 464 if ( entry_orig != NULL ) { 465 assert( pb->pb_op->ora_modlist == NULL ); 466 467 rs->sr_err = slap_entry2mods( entry_orig, &pb->pb_op->ora_modlist, 468 &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) ); 469 if ( rs->sr_err != LDAP_SUCCESS ) { 470 goto cleanup; 471 } 472 } else { 473 assert( pb->pb_op->ora_modlist != NULL ); 474 } 475 476 rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->ora_modlist, &rs->sr_text, 477 pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL ); 478 if ( rs->sr_err != LDAP_SUCCESS ) { 479 goto cleanup; 480 } 481 482 /* Duplicate the values, because we may call slapi_entry_free() */ 483 rs->sr_err = slap_mods2entry( pb->pb_op->ora_modlist, &pb->pb_op->ora_e, 484 1, 0, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) ); 485 if ( rs->sr_err != LDAP_SUCCESS ) { 486 goto cleanup; 487 } 488 489 oex.oe.oe_key = (void *)do_add; 490 oex.oe_db = NULL; 491 LDAP_SLIST_INSERT_HEAD(&pb->pb_op->o_extra, &oex.oe, oe_next); 492 rc = slapi_int_func_internal_pb( pb, op_add ); 493 LDAP_SLIST_REMOVE(&pb->pb_op->o_extra, &oex.oe, OpExtra, oe_next); 494 495 if ( !rc ) { 496 if ( pb->pb_op->ora_e != NULL && oex.oe_db != NULL ) { 497 BackendDB *bd = pb->pb_op->o_bd; 498 499 pb->pb_op->o_bd = oex.oe_db; 500 be_entry_release_w( pb->pb_op, pb->pb_op->ora_e ); 501 pb->pb_op->ora_e = NULL; 502 pb->pb_op->o_bd = bd; 503 } 504 } 505 506 cleanup: 507 508 if ( pb->pb_op->ora_e != NULL ) { 509 slapi_entry_free( pb->pb_op->ora_e ); 510 pb->pb_op->ora_e = NULL; 511 } 512 if ( entry_orig != NULL ) { 513 pb->pb_op->ora_e = entry_orig; 514 slap_mods_free( pb->pb_op->ora_modlist, 1 ); 515 pb->pb_op->ora_modlist = NULL; 516 } 517 518 return 0; 519 } 520 521 int 522 slapi_modrdn_internal_pb( Slapi_PBlock *pb ) 523 { 524 if ( pb == NULL ) { 525 return -1; 526 } 527 528 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODRDN ); 529 530 if ( BER_BVISEMPTY( &pb->pb_op->o_req_ndn ) ) { 531 pb->pb_rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 532 goto cleanup; 533 } 534 535 slapi_int_func_internal_pb( pb, op_modrdn ); 536 537 cleanup: 538 539 return 0; 540 } 541 542 int 543 slapi_modify_internal_pb( Slapi_PBlock *pb ) 544 { 545 SlapReply *rs; 546 547 if ( pb == NULL ) { 548 return -1; 549 } 550 551 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODIFY ); 552 553 rs = pb->pb_rs; 554 555 if ( pb->pb_op->orm_modlist == NULL ) { 556 rs->sr_err = LDAP_PARAM_ERROR; 557 goto cleanup; 558 } 559 560 if ( BER_BVISEMPTY( &pb->pb_op->o_req_ndn ) ) { 561 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 562 goto cleanup; 563 } 564 565 rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->orm_modlist, 566 &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL ); 567 if ( rs->sr_err != LDAP_SUCCESS ) { 568 goto cleanup; 569 } 570 571 slapi_int_func_internal_pb( pb, op_modify ); 572 573 cleanup: 574 575 return 0; 576 } 577 578 static int 579 slapi_int_search_entry_callback( Slapi_Entry *entry, void *callback_data ) 580 { 581 int nentries = 0, i = 0; 582 Slapi_Entry **head = NULL, **tp; 583 Slapi_PBlock *pb = (Slapi_PBlock *)callback_data; 584 585 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH ); 586 587 entry = slapi_entry_dup( entry ); 588 if ( entry == NULL ) { 589 return LDAP_NO_MEMORY; 590 } 591 592 slapi_pblock_get( pb, SLAPI_NENTRIES, &nentries ); 593 slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head ); 594 595 i = nentries + 1; 596 if ( nentries == 0 ) { 597 tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) ); 598 if ( tp == NULL ) { 599 slapi_entry_free( entry ); 600 return LDAP_NO_MEMORY; 601 } 602 603 tp[0] = entry; 604 } else { 605 tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head, 606 sizeof(Slapi_Entry *) * ( i + 1 ) ); 607 if ( tp == NULL ) { 608 slapi_entry_free( entry ); 609 return LDAP_NO_MEMORY; 610 } 611 tp[i - 1] = entry; 612 } 613 tp[i] = NULL; 614 615 slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp ); 616 slapi_pblock_set( pb, SLAPI_NENTRIES, (void *)&i ); 617 618 return LDAP_SUCCESS; 619 } 620 621 int 622 slapi_search_internal_pb( Slapi_PBlock *pb ) 623 { 624 return slapi_search_internal_callback_pb( pb, 625 (void *)pb, 626 NULL, 627 slapi_int_search_entry_callback, 628 NULL ); 629 } 630 631 int 632 slapi_search_internal_callback_pb( Slapi_PBlock *pb, 633 void *callback_data, 634 plugin_result_callback prc, 635 plugin_search_entry_callback psec, 636 plugin_referral_entry_callback prec ) 637 { 638 int free_filter = 0; 639 SlapReply *rs; 640 641 if ( pb == NULL ) { 642 return -1; 643 } 644 645 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH ); 646 647 rs = pb->pb_rs; 648 649 /* search callback and arguments */ 650 slapi_pblock_set( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void *)prc ); 651 slapi_pblock_set( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void *)psec ); 652 slapi_pblock_set( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void *)prec ); 653 slapi_pblock_set( pb, SLAPI_X_INTOP_CALLBACK_DATA, (void *)callback_data ); 654 655 if ( BER_BVISEMPTY( &pb->pb_op->ors_filterstr )) { 656 rs->sr_err = LDAP_PARAM_ERROR; 657 goto cleanup; 658 } 659 660 if ( pb->pb_op->ors_filter == NULL ) { 661 pb->pb_op->ors_filter = slapi_str2filter( pb->pb_op->ors_filterstr.bv_val ); 662 if ( pb->pb_op->ors_filter == NULL ) { 663 rs->sr_err = LDAP_PROTOCOL_ERROR; 664 goto cleanup; 665 } 666 667 free_filter = 1; 668 } 669 670 slapi_int_func_internal_pb( pb, op_search ); 671 672 cleanup: 673 if ( free_filter ) { 674 slapi_filter_free( pb->pb_op->ors_filter, 1 ); 675 pb->pb_op->ors_filter = NULL; 676 } 677 678 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_RESULT_CALLBACK ); 679 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK ); 680 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK ); 681 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_CALLBACK_DATA ); 682 683 return 0; 684 } 685 686 /* Wrappers for old API */ 687 688 void 689 slapi_search_internal_set_pb( Slapi_PBlock *pb, 690 const char *base, 691 int scope, 692 const char *filter, 693 char **attrs, 694 int attrsonly, 695 LDAPControl **controls, 696 const char *uniqueid, 697 Slapi_ComponentId *plugin_identity, 698 int operation_flags ) 699 { 700 int no_limit = SLAP_NO_LIMIT; 701 int deref = LDAP_DEREF_NEVER; 702 703 slapi_int_connection_init_pb( pb, LDAP_REQ_SEARCH ); 704 slapi_pblock_set( pb, SLAPI_SEARCH_TARGET, (void *)base ); 705 slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, (void *)&scope ); 706 slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, (void *)0 ); 707 slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, (void *)filter ); 708 slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, (void *)attrs ); 709 slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, (void *)&attrsonly ); 710 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 711 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid ); 712 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 713 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 714 slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, (void *)&deref ); 715 slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, (void *)&no_limit ); 716 slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, (void *)&no_limit ); 717 718 slapi_int_set_operation_dn( pb ); 719 } 720 721 Slapi_PBlock * 722 slapi_search_internal( 723 char *ldn, 724 int scope, 725 char *filStr, 726 LDAPControl **controls, 727 char **attrs, 728 int attrsonly ) 729 { 730 Slapi_PBlock *pb; 731 732 pb = slapi_pblock_new(); 733 734 slapi_search_internal_set_pb( pb, ldn, scope, filStr, 735 attrs, attrsonly, 736 controls, NULL, NULL, 0 ); 737 738 slapi_search_internal_pb( pb ); 739 740 return pb; 741 } 742 743 void 744 slapi_modify_internal_set_pb( Slapi_PBlock *pb, 745 const char *dn, 746 LDAPMod **mods, 747 LDAPControl **controls, 748 const char *uniqueid, 749 Slapi_ComponentId *plugin_identity, 750 int operation_flags ) 751 { 752 slapi_int_connection_init_pb( pb, LDAP_REQ_MODIFY ); 753 slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn ); 754 slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)mods ); 755 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 756 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid ); 757 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 758 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 759 slapi_int_set_operation_dn( pb ); 760 } 761 762 /* Function : slapi_modify_internal 763 * 764 * Description: Plugin functions call this routine to modify an entry 765 * in the backend directly 766 * Return values : LDAP_SUCCESS 767 * LDAP_PARAM_ERROR 768 * LDAP_NO_MEMORY 769 * LDAP_OTHER 770 * LDAP_UNWILLING_TO_PERFORM 771 */ 772 Slapi_PBlock * 773 slapi_modify_internal( 774 char *ldn, 775 LDAPMod **mods, 776 LDAPControl **controls, 777 int log_change ) 778 { 779 Slapi_PBlock *pb; 780 781 pb = slapi_pblock_new(); 782 783 slapi_modify_internal_set_pb( pb, ldn, mods, controls, NULL, NULL, 0 ); 784 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 785 slapi_modify_internal_pb( pb ); 786 787 return pb; 788 } 789 790 int 791 slapi_add_internal_set_pb( Slapi_PBlock *pb, 792 const char *dn, 793 LDAPMod **attrs, 794 LDAPControl **controls, 795 Slapi_ComponentId *plugin_identity, 796 int operation_flags ) 797 { 798 slapi_int_connection_init_pb( pb, LDAP_REQ_ADD ); 799 slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn ); 800 slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)attrs ); 801 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 802 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 803 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 804 slapi_int_set_operation_dn( pb ); 805 806 return 0; 807 } 808 809 Slapi_PBlock * 810 slapi_add_internal( 811 char * dn, 812 LDAPMod **attrs, 813 LDAPControl **controls, 814 int log_change ) 815 { 816 Slapi_PBlock *pb; 817 818 pb = slapi_pblock_new(); 819 820 slapi_add_internal_set_pb( pb, dn, attrs, controls, NULL, 0); 821 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 822 slapi_add_internal_pb( pb ); 823 824 return pb; 825 } 826 827 void 828 slapi_add_entry_internal_set_pb( Slapi_PBlock *pb, 829 Slapi_Entry *e, 830 LDAPControl **controls, 831 Slapi_ComponentId *plugin_identity, 832 int operation_flags ) 833 { 834 slapi_int_connection_init_pb( pb, LDAP_REQ_ADD ); 835 slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e ); 836 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 837 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 838 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 839 slapi_int_set_operation_dn( pb ); 840 } 841 842 Slapi_PBlock * 843 slapi_add_entry_internal( 844 Slapi_Entry *e, 845 LDAPControl **controls, 846 int log_change ) 847 { 848 Slapi_PBlock *pb; 849 850 pb = slapi_pblock_new(); 851 852 slapi_add_entry_internal_set_pb( pb, e, controls, NULL, 0 ); 853 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 854 slapi_add_internal_pb( pb ); 855 856 return pb; 857 } 858 859 void 860 slapi_rename_internal_set_pb( Slapi_PBlock *pb, 861 const char *olddn, 862 const char *newrdn, 863 const char *newsuperior, 864 int deloldrdn, 865 LDAPControl **controls, 866 const char *uniqueid, 867 Slapi_ComponentId *plugin_identity, 868 int operation_flags ) 869 { 870 slapi_int_connection_init_pb( pb, LDAP_REQ_MODRDN ); 871 slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)olddn ); 872 slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn ); 873 slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR, (void *)newsuperior ); 874 slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)&deloldrdn ); 875 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 876 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid ); 877 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 878 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 879 slap_modrdn2mods( pb->pb_op, pb->pb_rs ); 880 slapi_int_set_operation_dn( pb ); 881 } 882 883 /* Function : slapi_modrdn_internal 884 * 885 * Description : Plugin functions call this routine to modify the rdn 886 * of an entry in the backend directly 887 * Return values : LDAP_SUCCESS 888 * LDAP_PARAM_ERROR 889 * LDAP_NO_MEMORY 890 * LDAP_OTHER 891 * LDAP_UNWILLING_TO_PERFORM 892 * 893 * NOTE: This function does not support the "newSuperior" option from LDAP V3. 894 */ 895 Slapi_PBlock * 896 slapi_modrdn_internal( 897 char *olddn, 898 char *lnewrdn, 899 int deloldrdn, 900 LDAPControl **controls, 901 int log_change ) 902 { 903 Slapi_PBlock *pb; 904 905 pb = slapi_pblock_new (); 906 907 slapi_rename_internal_set_pb( pb, olddn, lnewrdn, NULL, 908 deloldrdn, controls, NULL, NULL, 0 ); 909 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 910 slapi_modrdn_internal_pb( pb ); 911 912 return pb; 913 } 914 915 void 916 slapi_delete_internal_set_pb( Slapi_PBlock *pb, 917 const char *dn, 918 LDAPControl **controls, 919 const char *uniqueid, 920 Slapi_ComponentId *plugin_identity, 921 int operation_flags ) 922 { 923 slapi_int_connection_init_pb( pb, LDAP_REQ_DELETE ); 924 slapi_pblock_set( pb, SLAPI_TARGET_DN, (void *)dn ); 925 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 926 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid ); 927 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 928 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 929 slapi_int_set_operation_dn( pb ); 930 } 931 932 /* Function : slapi_delete_internal 933 * 934 * Description : Plugin functions call this routine to delete an entry 935 * in the backend directly 936 * Return values : LDAP_SUCCESS 937 * LDAP_PARAM_ERROR 938 * LDAP_NO_MEMORY 939 * LDAP_OTHER 940 * LDAP_UNWILLING_TO_PERFORM 941 */ 942 Slapi_PBlock * 943 slapi_delete_internal( 944 char *ldn, 945 LDAPControl **controls, 946 int log_change ) 947 { 948 Slapi_PBlock *pb; 949 950 pb = slapi_pblock_new(); 951 952 slapi_delete_internal_set_pb( pb, ldn, controls, NULL, NULL, 0 ); 953 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 954 slapi_delete_internal_pb( pb ); 955 956 return pb; 957 } 958 959 #endif /* LDAP_SLAPI */ 960