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