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