1 /* $NetBSD: slapi_ops.c,v 1.1.1.3 2010/12/12 15:23:52 adam Exp $ */ 2 3 /* OpenLDAP: pkg/ldap/servers/slapd/slapi/slapi_ops.c,v 1.111.2.8 2010/04/13 20:23:50 kurt Exp */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 2002-2010 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 "portable.h" 26 27 #include <ac/string.h> 28 #include <ac/stdarg.h> 29 #include <ac/ctype.h> 30 #include <ac/unistd.h> 31 32 #include <slap.h> 33 #include <lber_pvt.h> 34 #include <slapi.h> 35 36 #ifdef LDAP_SLAPI 37 38 static struct Listener slapi_listener = { 39 BER_BVC("slapi://"), 40 BER_BVC("slapi://") 41 }; 42 43 static LDAPControl ** 44 slapi_int_dup_controls( LDAPControl **controls ) 45 { 46 LDAPControl **c; 47 size_t i; 48 49 if ( controls == NULL ) 50 return NULL; 51 52 for ( i = 0; controls[i] != NULL; i++ ) 53 ; 54 55 c = (LDAPControl **) slapi_ch_calloc( i + 1, sizeof(LDAPControl *) ); 56 57 for ( i = 0; controls[i] != NULL; i++ ) { 58 c[i] = slapi_dup_control( controls[i] ); 59 } 60 61 return c; 62 } 63 64 static int 65 slapi_int_result( 66 Operation *op, 67 SlapReply *rs ) 68 { 69 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op ); 70 plugin_result_callback prc = NULL; 71 void *callback_data = NULL; 72 LDAPControl **ctrls = NULL; 73 74 assert( pb != NULL ); 75 76 slapi_pblock_get( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void **)&prc ); 77 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data ); 78 79 /* we need to duplicate controls because they might go out of scope */ 80 ctrls = slapi_int_dup_controls( rs->sr_ctrls ); 81 slapi_pblock_set( pb, SLAPI_RESCONTROLS, ctrls ); 82 83 if ( prc != NULL ) { 84 (*prc)( rs->sr_err, callback_data ); 85 } 86 87 return rs->sr_err; 88 } 89 90 static int 91 slapi_int_search_entry( 92 Operation *op, 93 SlapReply *rs ) 94 { 95 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op ); 96 plugin_search_entry_callback psec = NULL; 97 void *callback_data = NULL; 98 int rc = LDAP_SUCCESS; 99 100 assert( pb != NULL ); 101 102 slapi_pblock_get( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void **)&psec ); 103 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data ); 104 105 if ( psec != NULL ) { 106 rc = (*psec)( rs->sr_entry, callback_data ); 107 } 108 109 return rc; 110 } 111 112 static int 113 slapi_int_search_reference( 114 Operation *op, 115 SlapReply *rs ) 116 { 117 int i, rc = LDAP_SUCCESS; 118 plugin_referral_entry_callback prec = NULL; 119 void *callback_data = NULL; 120 Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op ); 121 122 assert( pb != NULL ); 123 124 slapi_pblock_get( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void **)&prec ); 125 slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data ); 126 127 if ( prec != NULL ) { 128 for ( i = 0; rs->sr_ref[i].bv_val != NULL; i++ ) { 129 rc = (*prec)( rs->sr_ref[i].bv_val, callback_data ); 130 if ( rc != LDAP_SUCCESS ) { 131 break; 132 } 133 } 134 } 135 136 return rc; 137 } 138 139 int 140 slapi_int_response( Slapi_Operation *op, SlapReply *rs ) 141 { 142 int rc; 143 144 switch ( rs->sr_type ) { 145 case REP_RESULT: 146 rc = slapi_int_result( op, rs ); 147 break; 148 case REP_SEARCH: 149 rc = slapi_int_search_entry( op, rs ); 150 break; 151 case REP_SEARCHREF: 152 rc = slapi_int_search_reference( op, rs ); 153 break; 154 default: 155 rc = LDAP_OTHER; 156 break; 157 } 158 159 assert( rc != SLAP_CB_CONTINUE ); /* never try to send a wire response */ 160 161 return rc; 162 } 163 164 static int 165 slapi_int_get_ctrls( Slapi_PBlock *pb ) 166 { 167 LDAPControl **c; 168 int rc = LDAP_SUCCESS; 169 170 if ( pb->pb_op->o_ctrls != NULL ) { 171 for ( c = pb->pb_op->o_ctrls; *c != NULL; c++ ) { 172 rc = slap_parse_ctrl( pb->pb_op, pb->pb_rs, *c, &pb->pb_rs->sr_text ); 173 if ( rc != LDAP_SUCCESS ) 174 break; 175 } 176 } 177 178 return rc; 179 } 180 181 void 182 slapi_int_connection_init_pb( Slapi_PBlock *pb, ber_tag_t tag ) 183 { 184 Connection *conn; 185 Operation *op; 186 ber_len_t max = sockbuf_max_incoming; 187 188 conn = (Connection *) slapi_ch_calloc( 1, sizeof(Connection) ); 189 190 LDAP_STAILQ_INIT( &conn->c_pending_ops ); 191 192 op = (Operation *) slapi_ch_calloc( 1, sizeof(OperationBuffer) ); 193 op->o_hdr = &((OperationBuffer *) op)->ob_hdr; 194 op->o_controls = ((OperationBuffer *) op)->ob_controls; 195 196 op->o_callback = (slap_callback *) slapi_ch_calloc( 1, sizeof(slap_callback) ); 197 op->o_callback->sc_response = slapi_int_response; 198 op->o_callback->sc_cleanup = NULL; 199 op->o_callback->sc_private = pb; 200 op->o_callback->sc_next = NULL; 201 202 conn->c_pending_ops.stqh_first = op; 203 204 /* connection object authorization information */ 205 conn->c_authtype = LDAP_AUTH_NONE; 206 BER_BVZERO( &conn->c_authmech ); 207 BER_BVZERO( &conn->c_dn ); 208 BER_BVZERO( &conn->c_ndn ); 209 210 conn->c_listener = &slapi_listener; 211 ber_dupbv( &conn->c_peer_domain, (struct berval *)&slap_unknown_bv ); 212 ber_dupbv( &conn->c_peer_name, (struct berval *)&slap_unknown_bv ); 213 214 LDAP_STAILQ_INIT( &conn->c_ops ); 215 216 BER_BVZERO( &conn->c_sasl_bind_mech ); 217 conn->c_sasl_authctx = NULL; 218 conn->c_sasl_sockctx = NULL; 219 conn->c_sasl_extra = NULL; 220 221 conn->c_sb = ber_sockbuf_alloc(); 222 223 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); 224 225 conn->c_currentber = NULL; 226 227 /* should check status of thread calls */ 228 ldap_pvt_thread_mutex_init( &conn->c_mutex ); 229 ldap_pvt_thread_mutex_init( &conn->c_write1_mutex ); 230 ldap_pvt_thread_mutex_init( &conn->c_write2_mutex ); 231 ldap_pvt_thread_cond_init( &conn->c_write1_cv ); 232 ldap_pvt_thread_cond_init( &conn->c_write2_cv ); 233 234 ldap_pvt_thread_mutex_lock( &conn->c_mutex ); 235 236 conn->c_n_ops_received = 0; 237 conn->c_n_ops_executing = 0; 238 conn->c_n_ops_pending = 0; 239 conn->c_n_ops_completed = 0; 240 241 conn->c_n_get = 0; 242 conn->c_n_read = 0; 243 conn->c_n_write = 0; 244 245 conn->c_protocol = LDAP_VERSION3; 246 247 conn->c_activitytime = conn->c_starttime = slap_get_time(); 248 249 /* 250 * A real connection ID is required, because syncrepl associates 251 * pending CSNs with unique ( connection, operation ) tuples. 252 * Setting a fake connection ID will cause slap_get_commit_csn() 253 * to return a stale value. 254 */ 255 connection_assign_nextid( conn ); 256 257 conn->c_conn_state = 0x01; /* SLAP_C_ACTIVE */ 258 conn->c_struct_state = 0x02; /* SLAP_C_USED */ 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 BI_op_bind **func; 390 SlapReply *rs = pb->pb_rs; 391 int rc; 392 393 PBLOCK_ASSERT_INTOP( pb, 0 ); 394 395 rc = slapi_int_get_ctrls( pb ); 396 if ( rc != LDAP_SUCCESS ) { 397 rs->sr_err = rc; 398 return rc; 399 } 400 401 pb->pb_op->o_bd = frontendDB; 402 func = &frontendDB->be_bind; 403 404 return func[which]( pb->pb_op, pb->pb_rs ); 405 } 406 407 int 408 slapi_delete_internal_pb( Slapi_PBlock *pb ) 409 { 410 if ( pb == NULL ) { 411 return -1; 412 } 413 414 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_DELETE ); 415 416 slapi_int_func_internal_pb( pb, op_delete ); 417 418 return 0; 419 } 420 421 int 422 slapi_add_internal_pb( Slapi_PBlock *pb ) 423 { 424 SlapReply *rs; 425 Slapi_Entry *entry_orig = NULL; 426 OpExtraDB oex; 427 int rc; 428 429 if ( pb == NULL ) { 430 return -1; 431 } 432 433 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_ADD ); 434 435 rs = pb->pb_rs; 436 437 entry_orig = pb->pb_op->ora_e; 438 pb->pb_op->ora_e = NULL; 439 440 /* 441 * The caller can specify a new entry, or a target DN and set 442 * of modifications, but not both. 443 */ 444 if ( entry_orig != NULL ) { 445 if ( pb->pb_op->ora_modlist != NULL || !BER_BVISNULL( &pb->pb_op->o_req_ndn )) { 446 rs->sr_err = LDAP_PARAM_ERROR; 447 goto cleanup; 448 } 449 450 assert( BER_BVISNULL( &pb->pb_op->o_req_dn ) ); /* shouldn't get set */ 451 ber_dupbv( &pb->pb_op->o_req_dn, &entry_orig->e_name ); 452 ber_dupbv( &pb->pb_op->o_req_ndn, &entry_orig->e_nname ); 453 } else if ( pb->pb_op->ora_modlist == NULL || BER_BVISNULL( &pb->pb_op->o_req_ndn )) { 454 rs->sr_err = LDAP_PARAM_ERROR; 455 goto cleanup; 456 } 457 458 pb->pb_op->ora_e = (Entry *)slapi_ch_calloc( 1, sizeof(Entry) ); 459 ber_dupbv( &pb->pb_op->ora_e->e_name, &pb->pb_op->o_req_dn ); 460 ber_dupbv( &pb->pb_op->ora_e->e_nname, &pb->pb_op->o_req_ndn ); 461 462 if ( entry_orig != NULL ) { 463 assert( pb->pb_op->ora_modlist == NULL ); 464 465 rs->sr_err = slap_entry2mods( entry_orig, &pb->pb_op->ora_modlist, 466 &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) ); 467 if ( rs->sr_err != LDAP_SUCCESS ) { 468 goto cleanup; 469 } 470 } else { 471 assert( pb->pb_op->ora_modlist != NULL ); 472 } 473 474 rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->ora_modlist, &rs->sr_text, 475 pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL ); 476 if ( rs->sr_err != LDAP_SUCCESS ) { 477 goto cleanup; 478 } 479 480 /* Duplicate the values, because we may call slapi_entry_free() */ 481 rs->sr_err = slap_mods2entry( pb->pb_op->ora_modlist, &pb->pb_op->ora_e, 482 1, 0, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) ); 483 if ( rs->sr_err != LDAP_SUCCESS ) { 484 goto cleanup; 485 } 486 487 oex.oe.oe_key = (void *)do_add; 488 oex.oe_db = NULL; 489 LDAP_SLIST_INSERT_HEAD(&pb->pb_op->o_extra, &oex.oe, oe_next); 490 rc = slapi_int_func_internal_pb( pb, op_add ); 491 LDAP_SLIST_REMOVE(&pb->pb_op->o_extra, &oex.oe, OpExtra, oe_next); 492 493 if ( !rc ) { 494 if ( pb->pb_op->ora_e != NULL && oex.oe_db != NULL ) { 495 BackendDB *bd = pb->pb_op->o_bd; 496 497 pb->pb_op->o_bd = oex.oe_db; 498 be_entry_release_w( pb->pb_op, pb->pb_op->ora_e ); 499 pb->pb_op->ora_e = NULL; 500 pb->pb_op->o_bd = bd; 501 } 502 } 503 504 cleanup: 505 506 if ( pb->pb_op->ora_e != NULL ) { 507 slapi_entry_free( pb->pb_op->ora_e ); 508 pb->pb_op->ora_e = NULL; 509 } 510 if ( entry_orig != NULL ) { 511 pb->pb_op->ora_e = entry_orig; 512 slap_mods_free( pb->pb_op->ora_modlist, 1 ); 513 pb->pb_op->ora_modlist = NULL; 514 } 515 516 return 0; 517 } 518 519 int 520 slapi_modrdn_internal_pb( Slapi_PBlock *pb ) 521 { 522 if ( pb == NULL ) { 523 return -1; 524 } 525 526 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODRDN ); 527 528 if ( BER_BVISEMPTY( &pb->pb_op->o_req_ndn ) ) { 529 pb->pb_rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 530 goto cleanup; 531 } 532 533 slapi_int_func_internal_pb( pb, op_modrdn ); 534 535 cleanup: 536 537 return 0; 538 } 539 540 int 541 slapi_modify_internal_pb( Slapi_PBlock *pb ) 542 { 543 SlapReply *rs; 544 545 if ( pb == NULL ) { 546 return -1; 547 } 548 549 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODIFY ); 550 551 rs = pb->pb_rs; 552 553 if ( pb->pb_op->orm_modlist == NULL ) { 554 rs->sr_err = LDAP_PARAM_ERROR; 555 goto cleanup; 556 } 557 558 if ( BER_BVISEMPTY( &pb->pb_op->o_req_ndn ) ) { 559 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 560 goto cleanup; 561 } 562 563 rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->orm_modlist, 564 &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL ); 565 if ( rs->sr_err != LDAP_SUCCESS ) { 566 goto cleanup; 567 } 568 569 slapi_int_func_internal_pb( pb, op_modify ); 570 571 cleanup: 572 573 return 0; 574 } 575 576 static int 577 slapi_int_search_entry_callback( Slapi_Entry *entry, void *callback_data ) 578 { 579 int nentries = 0, i = 0; 580 Slapi_Entry **head = NULL, **tp; 581 Slapi_PBlock *pb = (Slapi_PBlock *)callback_data; 582 583 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH ); 584 585 entry = slapi_entry_dup( entry ); 586 if ( entry == NULL ) { 587 return LDAP_NO_MEMORY; 588 } 589 590 slapi_pblock_get( pb, SLAPI_NENTRIES, &nentries ); 591 slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head ); 592 593 i = nentries + 1; 594 if ( nentries == 0 ) { 595 tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) ); 596 if ( tp == NULL ) { 597 slapi_entry_free( entry ); 598 return LDAP_NO_MEMORY; 599 } 600 601 tp[0] = entry; 602 } else { 603 tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head, 604 sizeof(Slapi_Entry *) * ( i + 1 ) ); 605 if ( tp == NULL ) { 606 slapi_entry_free( entry ); 607 return LDAP_NO_MEMORY; 608 } 609 tp[i - 1] = entry; 610 } 611 tp[i] = NULL; 612 613 slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp ); 614 slapi_pblock_set( pb, SLAPI_NENTRIES, (void *)&i ); 615 616 return LDAP_SUCCESS; 617 } 618 619 int 620 slapi_search_internal_pb( Slapi_PBlock *pb ) 621 { 622 return slapi_search_internal_callback_pb( pb, 623 (void *)pb, 624 NULL, 625 slapi_int_search_entry_callback, 626 NULL ); 627 } 628 629 int 630 slapi_search_internal_callback_pb( Slapi_PBlock *pb, 631 void *callback_data, 632 plugin_result_callback prc, 633 plugin_search_entry_callback psec, 634 plugin_referral_entry_callback prec ) 635 { 636 int free_filter = 0; 637 SlapReply *rs; 638 639 if ( pb == NULL ) { 640 return -1; 641 } 642 643 PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH ); 644 645 rs = pb->pb_rs; 646 647 /* search callback and arguments */ 648 slapi_pblock_set( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void *)prc ); 649 slapi_pblock_set( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void *)psec ); 650 slapi_pblock_set( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void *)prec ); 651 slapi_pblock_set( pb, SLAPI_X_INTOP_CALLBACK_DATA, (void *)callback_data ); 652 653 if ( BER_BVISEMPTY( &pb->pb_op->ors_filterstr )) { 654 rs->sr_err = LDAP_PARAM_ERROR; 655 goto cleanup; 656 } 657 658 if ( pb->pb_op->ors_filter == NULL ) { 659 pb->pb_op->ors_filter = slapi_str2filter( pb->pb_op->ors_filterstr.bv_val ); 660 if ( pb->pb_op->ors_filter == NULL ) { 661 rs->sr_err = LDAP_PROTOCOL_ERROR; 662 goto cleanup; 663 } 664 665 free_filter = 1; 666 } 667 668 slapi_int_func_internal_pb( pb, op_search ); 669 670 cleanup: 671 if ( free_filter ) { 672 slapi_filter_free( pb->pb_op->ors_filter, 1 ); 673 pb->pb_op->ors_filter = NULL; 674 } 675 676 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_RESULT_CALLBACK ); 677 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK ); 678 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK ); 679 slapi_pblock_delete_param( pb, SLAPI_X_INTOP_CALLBACK_DATA ); 680 681 return 0; 682 } 683 684 /* Wrappers for old API */ 685 686 void 687 slapi_search_internal_set_pb( Slapi_PBlock *pb, 688 const char *base, 689 int scope, 690 const char *filter, 691 char **attrs, 692 int attrsonly, 693 LDAPControl **controls, 694 const char *uniqueid, 695 Slapi_ComponentId *plugin_identity, 696 int operation_flags ) 697 { 698 int no_limit = SLAP_NO_LIMIT; 699 int deref = LDAP_DEREF_NEVER; 700 701 slapi_int_connection_init_pb( pb, LDAP_REQ_SEARCH ); 702 slapi_pblock_set( pb, SLAPI_SEARCH_TARGET, (void *)base ); 703 slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, (void *)&scope ); 704 slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, (void *)0 ); 705 slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, (void *)filter ); 706 slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, (void *)attrs ); 707 slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, (void *)&attrsonly ); 708 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 709 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid ); 710 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 711 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 712 slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, (void *)&deref ); 713 slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, (void *)&no_limit ); 714 slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, (void *)&no_limit ); 715 716 slapi_int_set_operation_dn( pb ); 717 } 718 719 Slapi_PBlock * 720 slapi_search_internal( 721 char *ldn, 722 int scope, 723 char *filStr, 724 LDAPControl **controls, 725 char **attrs, 726 int attrsonly ) 727 { 728 Slapi_PBlock *pb; 729 730 pb = slapi_pblock_new(); 731 732 slapi_search_internal_set_pb( pb, ldn, scope, filStr, 733 attrs, attrsonly, 734 controls, NULL, NULL, 0 ); 735 736 slapi_search_internal_pb( pb ); 737 738 return pb; 739 } 740 741 void 742 slapi_modify_internal_set_pb( Slapi_PBlock *pb, 743 const char *dn, 744 LDAPMod **mods, 745 LDAPControl **controls, 746 const char *uniqueid, 747 Slapi_ComponentId *plugin_identity, 748 int operation_flags ) 749 { 750 slapi_int_connection_init_pb( pb, LDAP_REQ_MODIFY ); 751 slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn ); 752 slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)mods ); 753 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 754 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid ); 755 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 756 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 757 slapi_int_set_operation_dn( pb ); 758 } 759 760 /* Function : slapi_modify_internal 761 * 762 * Description: Plugin functions call this routine to modify an entry 763 * in the backend directly 764 * Return values : LDAP_SUCCESS 765 * LDAP_PARAM_ERROR 766 * LDAP_NO_MEMORY 767 * LDAP_OTHER 768 * LDAP_UNWILLING_TO_PERFORM 769 */ 770 Slapi_PBlock * 771 slapi_modify_internal( 772 char *ldn, 773 LDAPMod **mods, 774 LDAPControl **controls, 775 int log_change ) 776 { 777 Slapi_PBlock *pb; 778 779 pb = slapi_pblock_new(); 780 781 slapi_modify_internal_set_pb( pb, ldn, mods, controls, NULL, NULL, 0 ); 782 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 783 slapi_modify_internal_pb( pb ); 784 785 return pb; 786 } 787 788 int 789 slapi_add_internal_set_pb( Slapi_PBlock *pb, 790 const char *dn, 791 LDAPMod **attrs, 792 LDAPControl **controls, 793 Slapi_ComponentId *plugin_identity, 794 int operation_flags ) 795 { 796 slapi_int_connection_init_pb( pb, LDAP_REQ_ADD ); 797 slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn ); 798 slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)attrs ); 799 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 800 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 801 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 802 slapi_int_set_operation_dn( pb ); 803 804 return 0; 805 } 806 807 Slapi_PBlock * 808 slapi_add_internal( 809 char * dn, 810 LDAPMod **attrs, 811 LDAPControl **controls, 812 int log_change ) 813 { 814 Slapi_PBlock *pb; 815 816 pb = slapi_pblock_new(); 817 818 slapi_add_internal_set_pb( pb, dn, attrs, controls, NULL, 0); 819 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 820 slapi_add_internal_pb( pb ); 821 822 return pb; 823 } 824 825 void 826 slapi_add_entry_internal_set_pb( Slapi_PBlock *pb, 827 Slapi_Entry *e, 828 LDAPControl **controls, 829 Slapi_ComponentId *plugin_identity, 830 int operation_flags ) 831 { 832 slapi_int_connection_init_pb( pb, LDAP_REQ_ADD ); 833 slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e ); 834 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 835 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 836 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 837 slapi_int_set_operation_dn( pb ); 838 } 839 840 Slapi_PBlock * 841 slapi_add_entry_internal( 842 Slapi_Entry *e, 843 LDAPControl **controls, 844 int log_change ) 845 { 846 Slapi_PBlock *pb; 847 848 pb = slapi_pblock_new(); 849 850 slapi_add_entry_internal_set_pb( pb, e, controls, NULL, 0 ); 851 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 852 slapi_add_internal_pb( pb ); 853 854 return pb; 855 } 856 857 void 858 slapi_rename_internal_set_pb( Slapi_PBlock *pb, 859 const char *olddn, 860 const char *newrdn, 861 const char *newsuperior, 862 int deloldrdn, 863 LDAPControl **controls, 864 const char *uniqueid, 865 Slapi_ComponentId *plugin_identity, 866 int operation_flags ) 867 { 868 slapi_int_connection_init_pb( pb, LDAP_REQ_MODRDN ); 869 slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)olddn ); 870 slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn ); 871 slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR, (void *)newsuperior ); 872 slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)&deloldrdn ); 873 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 874 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid ); 875 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 876 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 877 slap_modrdn2mods( pb->pb_op, pb->pb_rs ); 878 slapi_int_set_operation_dn( pb ); 879 } 880 881 /* Function : slapi_modrdn_internal 882 * 883 * Description : Plugin functions call this routine to modify the rdn 884 * of an entry in the backend directly 885 * Return values : LDAP_SUCCESS 886 * LDAP_PARAM_ERROR 887 * LDAP_NO_MEMORY 888 * LDAP_OTHER 889 * LDAP_UNWILLING_TO_PERFORM 890 * 891 * NOTE: This function does not support the "newSuperior" option from LDAP V3. 892 */ 893 Slapi_PBlock * 894 slapi_modrdn_internal( 895 char *olddn, 896 char *lnewrdn, 897 int deloldrdn, 898 LDAPControl **controls, 899 int log_change ) 900 { 901 Slapi_PBlock *pb; 902 903 pb = slapi_pblock_new (); 904 905 slapi_rename_internal_set_pb( pb, olddn, lnewrdn, NULL, 906 deloldrdn, controls, NULL, NULL, 0 ); 907 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 908 slapi_modrdn_internal_pb( pb ); 909 910 return pb; 911 } 912 913 void 914 slapi_delete_internal_set_pb( Slapi_PBlock *pb, 915 const char *dn, 916 LDAPControl **controls, 917 const char *uniqueid, 918 Slapi_ComponentId *plugin_identity, 919 int operation_flags ) 920 { 921 slapi_int_connection_init_pb( pb, LDAP_REQ_DELETE ); 922 slapi_pblock_set( pb, SLAPI_TARGET_DN, (void *)dn ); 923 slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls ); 924 slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid ); 925 slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity ); 926 slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)&operation_flags ); 927 slapi_int_set_operation_dn( pb ); 928 } 929 930 /* Function : slapi_delete_internal 931 * 932 * Description : Plugin functions call this routine to delete an entry 933 * in the backend directly 934 * Return values : LDAP_SUCCESS 935 * LDAP_PARAM_ERROR 936 * LDAP_NO_MEMORY 937 * LDAP_OTHER 938 * LDAP_UNWILLING_TO_PERFORM 939 */ 940 Slapi_PBlock * 941 slapi_delete_internal( 942 char *ldn, 943 LDAPControl **controls, 944 int log_change ) 945 { 946 Slapi_PBlock *pb; 947 948 pb = slapi_pblock_new(); 949 950 slapi_delete_internal_set_pb( pb, ldn, controls, NULL, NULL, 0 ); 951 slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change ); 952 slapi_delete_internal_pb( pb ); 953 954 return pb; 955 } 956 957 #endif /* LDAP_SLAPI */ 958 959