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 ** 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 * 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 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 * 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 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 * 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 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 * 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 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 * 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