Back to index

openldap  2.4.31
slapi_ops.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 2002-2012 The OpenLDAP Foundation.
00005  * Portions Copyright 1997,2002-2003 IBM Corporation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* ACKNOWLEDGEMENTS:
00017  * This work was initially developed by IBM Corporation for use in
00018  * IBM products and subsequently ported to OpenLDAP Software by
00019  * Steve Omrani.  Additional significant contributors include:
00020  *   Luke Howard
00021  */
00022 
00023 #include "portable.h"
00024 
00025 #include <ac/string.h>
00026 #include <ac/stdarg.h>
00027 #include <ac/ctype.h>
00028 #include <ac/unistd.h>
00029 
00030 #include <slap.h>
00031 #include <lber_pvt.h>
00032 #include <slapi.h>
00033 
00034 #ifdef LDAP_SLAPI
00035 
00036 static struct Listener slapi_listener = {
00037        BER_BVC("slapi://"),
00038        BER_BVC("slapi://")
00039 };
00040 
00041 static LDAPControl **
00042 slapi_int_dup_controls( LDAPControl **controls )
00043 {
00044        LDAPControl **c;
00045        size_t i;
00046 
00047        if ( controls == NULL )
00048               return NULL;
00049 
00050        for ( i = 0; controls[i] != NULL; i++ )
00051               ;
00052 
00053        c = (LDAPControl **) slapi_ch_calloc( i + 1, sizeof(LDAPControl *) );
00054 
00055        for ( i = 0; controls[i] != NULL; i++ ) {
00056               c[i] = slapi_dup_control( controls[i] );
00057        }
00058 
00059        return c;
00060 }
00061 
00062 static int
00063 slapi_int_result(
00064        Operation     *op, 
00065        SlapReply     *rs )
00066 {
00067        Slapi_PBlock         *pb = SLAPI_OPERATION_PBLOCK( op );
00068        plugin_result_callback      prc = NULL;
00069        void                 *callback_data = NULL;
00070        LDAPControl          **ctrls = NULL;
00071 
00072        assert( pb != NULL );       
00073 
00074        slapi_pblock_get( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void **)&prc );
00075        slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA,   &callback_data );
00076 
00077        /* we need to duplicate controls because they might go out of scope */
00078        ctrls = slapi_int_dup_controls( rs->sr_ctrls );
00079        slapi_pblock_set( pb, SLAPI_RESCONTROLS, ctrls );
00080 
00081        if ( prc != NULL ) {
00082               (*prc)( rs->sr_err, callback_data );
00083        }
00084 
00085        return rs->sr_err;
00086 }
00087 
00088 static int
00089 slapi_int_search_entry(
00090        Operation     *op,
00091        SlapReply     *rs )
00092 {
00093        Slapi_PBlock                *pb = SLAPI_OPERATION_PBLOCK( op );
00094        plugin_search_entry_callback       psec = NULL;
00095        void                        *callback_data = NULL;
00096        int                         rc = LDAP_SUCCESS;
00097 
00098        assert( pb != NULL );
00099 
00100        slapi_pblock_get( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void **)&psec );
00101        slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA,         &callback_data );
00102 
00103        if ( psec != NULL ) {
00104               rc = (*psec)( rs->sr_entry, callback_data );
00105        }
00106 
00107        return rc;
00108 }
00109 
00110 static int
00111 slapi_int_search_reference(
00112        Operation     *op,   
00113        SlapReply     *rs )
00114 {
00115        int                         i, rc = LDAP_SUCCESS;
00116        plugin_referral_entry_callback     prec = NULL;
00117        void                        *callback_data = NULL;
00118        Slapi_PBlock                *pb = SLAPI_OPERATION_PBLOCK( op );
00119 
00120        assert( pb != NULL );
00121 
00122        slapi_pblock_get( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void **)&prec );
00123        slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA,           &callback_data );
00124 
00125        if ( prec != NULL ) {
00126               for ( i = 0; rs->sr_ref[i].bv_val != NULL; i++ ) {
00127                      rc = (*prec)( rs->sr_ref[i].bv_val, callback_data );
00128                      if ( rc != LDAP_SUCCESS ) {
00129                             break;
00130                      }
00131               }
00132        }
00133 
00134        return rc;
00135 }
00136 
00137 int
00138 slapi_int_response( Slapi_Operation *op, SlapReply *rs )
00139 {
00140        int                         rc;
00141 
00142        switch ( rs->sr_type ) {
00143        case REP_RESULT:
00144               rc = slapi_int_result( op, rs );
00145               break;
00146        case REP_SEARCH:
00147               rc = slapi_int_search_entry( op, rs );
00148               break;
00149        case REP_SEARCHREF:
00150               rc = slapi_int_search_reference( op, rs );
00151               break;
00152        default:
00153               rc = LDAP_OTHER;
00154               break;
00155        }
00156 
00157        assert( rc != SLAP_CB_CONTINUE ); /* never try to send a wire response */
00158 
00159        return rc;
00160 }
00161 
00162 static int
00163 slapi_int_get_ctrls( Slapi_PBlock *pb )
00164 {
00165        LDAPControl          **c;
00166        int                  rc = LDAP_SUCCESS;
00167 
00168        if ( pb->pb_op->o_ctrls != NULL ) {
00169               for ( c = pb->pb_op->o_ctrls; *c != NULL; c++ ) {
00170                      rc = slap_parse_ctrl( pb->pb_op, pb->pb_rs, *c, &pb->pb_rs->sr_text );
00171                      if ( rc != LDAP_SUCCESS )
00172                             break;
00173               }
00174        }
00175 
00176        return rc;
00177 }
00178 
00179 void
00180 slapi_int_connection_init_pb( Slapi_PBlock *pb, ber_tag_t tag )
00181 {
00182        Connection           *conn;
00183        Operation            *op;
00184        ber_len_t            max = sockbuf_max_incoming;
00185 
00186        conn = (Connection *) slapi_ch_calloc( 1, sizeof(Connection) );
00187 
00188        LDAP_STAILQ_INIT( &conn->c_pending_ops );
00189 
00190        op = (Operation *) slapi_ch_calloc( 1, sizeof(OperationBuffer) );
00191        op->o_hdr = &((OperationBuffer *) op)->ob_hdr;
00192        op->o_controls = ((OperationBuffer *) op)->ob_controls;
00193 
00194        op->o_callback = (slap_callback *) slapi_ch_calloc( 1, sizeof(slap_callback) );
00195        op->o_callback->sc_response = slapi_int_response;
00196        op->o_callback->sc_cleanup = NULL;
00197        op->o_callback->sc_private = pb;
00198        op->o_callback->sc_next = NULL;
00199 
00200        conn->c_pending_ops.stqh_first = op;
00201 
00202        /* connection object authorization information */
00203        conn->c_authtype = LDAP_AUTH_NONE;
00204        BER_BVZERO( &conn->c_authmech );
00205        BER_BVZERO( &conn->c_dn );
00206        BER_BVZERO( &conn->c_ndn );
00207 
00208        conn->c_listener = &slapi_listener;
00209        ber_dupbv( &conn->c_peer_domain, (struct berval *)&slap_unknown_bv );
00210        ber_dupbv( &conn->c_peer_name, (struct berval *)&slap_unknown_bv );
00211 
00212        LDAP_STAILQ_INIT( &conn->c_ops );
00213 
00214        BER_BVZERO( &conn->c_sasl_bind_mech );
00215        conn->c_sasl_authctx = NULL;
00216        conn->c_sasl_sockctx = NULL;
00217        conn->c_sasl_extra = NULL;
00218 
00219        conn->c_sb = ber_sockbuf_alloc();
00220 
00221        ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
00222 
00223        conn->c_currentber = NULL;
00224 
00225        /* should check status of thread calls */
00226        ldap_pvt_thread_mutex_init( &conn->c_mutex );
00227        ldap_pvt_thread_mutex_init( &conn->c_write1_mutex );
00228        ldap_pvt_thread_mutex_init( &conn->c_write2_mutex );
00229        ldap_pvt_thread_cond_init( &conn->c_write1_cv );
00230        ldap_pvt_thread_cond_init( &conn->c_write2_cv );
00231 
00232        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
00233 
00234        conn->c_n_ops_received = 0;
00235        conn->c_n_ops_executing = 0;
00236        conn->c_n_ops_pending = 0;
00237        conn->c_n_ops_completed = 0;
00238 
00239        conn->c_n_get = 0;
00240        conn->c_n_read = 0;
00241        conn->c_n_write = 0;
00242 
00243        conn->c_protocol = LDAP_VERSION3; 
00244 
00245        conn->c_activitytime = conn->c_starttime = slap_get_time();
00246 
00247        /*
00248         * A real connection ID is required, because syncrepl associates
00249         * pending CSNs with unique ( connection, operation ) tuples.
00250         * Setting a fake connection ID will cause slap_get_commit_csn()
00251         * to return a stale value.
00252         */
00253        connection_assign_nextid( conn );
00254 
00255        conn->c_conn_state  = 0x01; /* SLAP_C_ACTIVE */
00256        conn->c_struct_state = 0x02;       /* SLAP_C_USED */
00257 
00258        conn->c_ssf = conn->c_transport_ssf = local_ssf;
00259        conn->c_tls_ssf = 0;
00260 
00261        backend_connection_init( conn );
00262 
00263        conn->c_send_ldap_result = slap_send_ldap_result;
00264        conn->c_send_search_entry = slap_send_search_entry;
00265        conn->c_send_ldap_extended = slap_send_ldap_extended;
00266        conn->c_send_search_reference = slap_send_search_reference;
00267 
00268        /* operation object */
00269        op->o_tag = tag;
00270        op->o_protocol = LDAP_VERSION3; 
00271        BER_BVZERO( &op->o_authmech );
00272        op->o_time = slap_get_time();
00273        op->o_do_not_cache = 1;
00274        op->o_threadctx = ldap_pvt_thread_pool_context();
00275        op->o_tmpmemctx = NULL;
00276        op->o_tmpmfuncs = &ch_mfuncs;
00277        op->o_conn = conn;
00278        op->o_connid = conn->c_connid;
00279        op->o_bd = frontendDB;
00280 
00281        /* extensions */
00282        slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op );
00283        slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
00284 
00285        pb->pb_rs = (SlapReply *)slapi_ch_calloc( 1, sizeof(SlapReply) );
00286        pb->pb_op = op;
00287        pb->pb_conn = conn;
00288        pb->pb_intop = 1;
00289 
00290        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
00291 }
00292 
00293 static void
00294 slapi_int_set_operation_dn( Slapi_PBlock *pb )
00295 {
00296        Backend                     *be;
00297        Operation            *op = pb->pb_op;
00298 
00299        if ( BER_BVISNULL( &op->o_ndn ) ) {
00300               /* set to root DN */
00301               be = select_backend( &op->o_req_ndn, 1 );
00302               if ( be != NULL ) {
00303                      ber_dupbv( &op->o_dn, &be->be_rootdn );
00304                      ber_dupbv( &op->o_ndn, &be->be_rootndn );
00305               }
00306        }
00307 }
00308 
00309 void
00310 slapi_int_connection_done_pb( Slapi_PBlock *pb )
00311 {
00312        Connection           *conn;
00313        Operation            *op;
00314 
00315        PBLOCK_ASSERT_INTOP( pb, 0 );
00316 
00317        conn = pb->pb_conn;
00318        op = pb->pb_op;
00319 
00320        /* free allocated DNs */
00321        if ( !BER_BVISNULL( &op->o_dn ) )
00322               op->o_tmpfree( op->o_dn.bv_val, op->o_tmpmemctx );
00323        if ( !BER_BVISNULL( &op->o_ndn ) )
00324               op->o_tmpfree( op->o_ndn.bv_val, op->o_tmpmemctx );
00325 
00326        if ( !BER_BVISNULL( &op->o_req_dn ) )
00327               op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
00328        if ( !BER_BVISNULL( &op->o_req_ndn ) )
00329               op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
00330 
00331        switch ( op->o_tag ) {
00332        case LDAP_REQ_MODRDN:
00333               if ( !BER_BVISNULL( &op->orr_newrdn ))
00334                      op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );
00335               if ( !BER_BVISNULL( &op->orr_nnewrdn ))
00336                      op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );
00337               if ( op->orr_newSup != NULL ) {
00338                      assert( !BER_BVISNULL( op->orr_newSup ) );
00339                      op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx );
00340                      op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
00341               }
00342               if ( op->orr_nnewSup != NULL ) {
00343                      assert( !BER_BVISNULL( op->orr_nnewSup ) );
00344                      op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx );
00345                      op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
00346               }
00347               slap_mods_free( op->orr_modlist, 1 );
00348               break;
00349        case LDAP_REQ_ADD:
00350               slap_mods_free( op->ora_modlist, 0 );
00351               break;
00352        case LDAP_REQ_MODIFY:
00353               slap_mods_free( op->orm_modlist, 1 );
00354               break;
00355        case LDAP_REQ_SEARCH:
00356               if ( op->ors_attrs != NULL ) {
00357                      op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
00358                      op->ors_attrs = NULL;
00359               }
00360               break;
00361        default:
00362               break;
00363        }
00364 
00365        slapi_ch_free_string( &conn->c_authmech.bv_val );
00366        slapi_ch_free_string( &conn->c_dn.bv_val );
00367        slapi_ch_free_string( &conn->c_ndn.bv_val );
00368        slapi_ch_free_string( &conn->c_peer_domain.bv_val );
00369        slapi_ch_free_string( &conn->c_peer_name.bv_val );
00370 
00371        if ( conn->c_sb != NULL ) {
00372               ber_sockbuf_free( conn->c_sb );
00373        }
00374 
00375        slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, op );
00376        slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
00377 
00378        slapi_ch_free( (void **)&pb->pb_op->o_callback );
00379        slapi_ch_free( (void **)&pb->pb_op );
00380        slapi_ch_free( (void **)&pb->pb_conn );
00381        slapi_ch_free( (void **)&pb->pb_rs );
00382 }
00383 
00384 static int
00385 slapi_int_func_internal_pb( Slapi_PBlock *pb, slap_operation_t which )
00386 {
00387        BI_op_bind           **func;
00388        SlapReply            *rs = pb->pb_rs;
00389        int                  rc;
00390 
00391        PBLOCK_ASSERT_INTOP( pb, 0 );
00392 
00393        rc = slapi_int_get_ctrls( pb );
00394        if ( rc != LDAP_SUCCESS ) {
00395               rs->sr_err = rc;
00396               return rc;
00397        }
00398 
00399        pb->pb_op->o_bd = frontendDB;
00400        func = &frontendDB->be_bind;
00401 
00402        return func[which]( pb->pb_op, pb->pb_rs );
00403 }
00404 
00405 int
00406 slapi_delete_internal_pb( Slapi_PBlock *pb )
00407 {
00408        if ( pb == NULL ) {
00409               return -1;
00410        }
00411 
00412        PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_DELETE );
00413 
00414        slapi_int_func_internal_pb( pb, op_delete );
00415 
00416        return 0;
00417 }
00418 
00419 int
00420 slapi_add_internal_pb( Slapi_PBlock *pb )
00421 {
00422        SlapReply            *rs;
00423        Slapi_Entry          *entry_orig = NULL;
00424        OpExtraDB oex;
00425        int rc;
00426 
00427        if ( pb == NULL ) {
00428               return -1;
00429        }
00430 
00431        PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_ADD );
00432 
00433        rs = pb->pb_rs;
00434 
00435        entry_orig = pb->pb_op->ora_e;
00436        pb->pb_op->ora_e = NULL;
00437 
00438        /*
00439         * The caller can specify a new entry, or a target DN and set
00440         * of modifications, but not both.
00441         */
00442        if ( entry_orig != NULL ) {
00443               if ( pb->pb_op->ora_modlist != NULL || !BER_BVISNULL( &pb->pb_op->o_req_ndn )) {
00444                      rs->sr_err = LDAP_PARAM_ERROR;
00445                      goto cleanup;
00446               }
00447 
00448               assert( BER_BVISNULL( &pb->pb_op->o_req_dn ) ); /* shouldn't get set */
00449               ber_dupbv( &pb->pb_op->o_req_dn, &entry_orig->e_name );
00450               ber_dupbv( &pb->pb_op->o_req_ndn, &entry_orig->e_nname );
00451        } else if ( pb->pb_op->ora_modlist == NULL || BER_BVISNULL( &pb->pb_op->o_req_ndn )) {
00452               rs->sr_err = LDAP_PARAM_ERROR;
00453               goto cleanup;
00454        }
00455 
00456        pb->pb_op->ora_e = (Entry *)slapi_ch_calloc( 1, sizeof(Entry) );
00457        ber_dupbv( &pb->pb_op->ora_e->e_name,  &pb->pb_op->o_req_dn );
00458        ber_dupbv( &pb->pb_op->ora_e->e_nname, &pb->pb_op->o_req_ndn );
00459 
00460        if ( entry_orig != NULL ) {
00461               assert( pb->pb_op->ora_modlist == NULL );
00462 
00463               rs->sr_err = slap_entry2mods( entry_orig, &pb->pb_op->ora_modlist,
00464                      &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) );
00465               if ( rs->sr_err != LDAP_SUCCESS ) {
00466                      goto cleanup;
00467               }
00468        } else {
00469               assert( pb->pb_op->ora_modlist != NULL );
00470        }
00471 
00472        rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->ora_modlist, &rs->sr_text,
00473               pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL );
00474        if ( rs->sr_err != LDAP_SUCCESS ) {
00475                 goto cleanup;
00476         }
00477 
00478        /* Duplicate the values, because we may call slapi_entry_free() */
00479        rs->sr_err = slap_mods2entry( pb->pb_op->ora_modlist, &pb->pb_op->ora_e,
00480               1, 0, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) );
00481        if ( rs->sr_err != LDAP_SUCCESS ) {
00482               goto cleanup;
00483        }
00484 
00485        oex.oe.oe_key = (void *)do_add;
00486        oex.oe_db = NULL;
00487        LDAP_SLIST_INSERT_HEAD(&pb->pb_op->o_extra, &oex.oe, oe_next);
00488        rc = slapi_int_func_internal_pb( pb, op_add );
00489        LDAP_SLIST_REMOVE(&pb->pb_op->o_extra, &oex.oe, OpExtra, oe_next);
00490 
00491        if ( !rc ) {
00492               if ( pb->pb_op->ora_e != NULL && oex.oe_db != NULL ) {
00493                      BackendDB     *bd = pb->pb_op->o_bd;
00494 
00495                      pb->pb_op->o_bd = oex.oe_db;
00496                      be_entry_release_w( pb->pb_op, pb->pb_op->ora_e );
00497                      pb->pb_op->ora_e = NULL;
00498                      pb->pb_op->o_bd = bd;
00499               }
00500        }
00501 
00502 cleanup:
00503 
00504        if ( pb->pb_op->ora_e != NULL ) {
00505               slapi_entry_free( pb->pb_op->ora_e );
00506               pb->pb_op->ora_e = NULL;
00507        }
00508        if ( entry_orig != NULL ) {
00509               pb->pb_op->ora_e = entry_orig;
00510               slap_mods_free( pb->pb_op->ora_modlist, 1 );
00511               pb->pb_op->ora_modlist = NULL;
00512        }
00513 
00514        return 0;
00515 }
00516 
00517 int
00518 slapi_modrdn_internal_pb( Slapi_PBlock *pb )
00519 {
00520        if ( pb == NULL ) {
00521               return -1;
00522        }
00523 
00524        PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODRDN );
00525 
00526        if ( BER_BVISEMPTY( &pb->pb_op->o_req_ndn ) ) {
00527               pb->pb_rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
00528               goto cleanup;
00529        }
00530 
00531        slapi_int_func_internal_pb( pb, op_modrdn );
00532 
00533 cleanup:
00534 
00535        return 0;
00536 }
00537 
00538 int
00539 slapi_modify_internal_pb( Slapi_PBlock *pb )
00540 {
00541        SlapReply            *rs;
00542 
00543        if ( pb == NULL ) {
00544               return -1;
00545        }
00546 
00547        PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODIFY );
00548 
00549        rs = pb->pb_rs;
00550 
00551        if ( pb->pb_op->orm_modlist == NULL ) {
00552               rs->sr_err = LDAP_PARAM_ERROR;
00553               goto cleanup;
00554        }
00555 
00556        if ( BER_BVISEMPTY( &pb->pb_op->o_req_ndn ) ) {
00557               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
00558               goto cleanup;
00559        }
00560 
00561        rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->orm_modlist,
00562               &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL );
00563        if ( rs->sr_err != LDAP_SUCCESS ) {
00564                 goto cleanup;
00565         }
00566 
00567        slapi_int_func_internal_pb( pb, op_modify );
00568 
00569 cleanup:
00570 
00571        return 0;
00572 }
00573 
00574 static int
00575 slapi_int_search_entry_callback( Slapi_Entry *entry, void *callback_data )
00576 {
00577        int           nentries = 0, i = 0;
00578        Slapi_Entry   **head = NULL, **tp;
00579        Slapi_PBlock  *pb = (Slapi_PBlock *)callback_data;
00580 
00581        PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH );
00582 
00583        entry = slapi_entry_dup( entry );
00584        if ( entry == NULL ) {
00585               return LDAP_NO_MEMORY;
00586        }
00587 
00588        slapi_pblock_get( pb, SLAPI_NENTRIES, &nentries );
00589        slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );
00590        
00591        i = nentries + 1;
00592        if ( nentries == 0 ) {
00593               tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );
00594               if ( tp == NULL ) {
00595                      slapi_entry_free( entry );
00596                      return LDAP_NO_MEMORY;
00597               }
00598 
00599               tp[0] = entry;
00600        } else {
00601               tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,
00602                             sizeof(Slapi_Entry *) * ( i + 1 ) );
00603               if ( tp == NULL ) {
00604                      slapi_entry_free( entry );
00605                      return LDAP_NO_MEMORY;
00606               }
00607               tp[i - 1] = entry;
00608        }
00609        tp[i] = NULL;
00610                  
00611        slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );
00612        slapi_pblock_set( pb, SLAPI_NENTRIES, (void *)&i );
00613 
00614        return LDAP_SUCCESS;
00615 }
00616 
00617 int
00618 slapi_search_internal_pb( Slapi_PBlock *pb )
00619 {
00620        return slapi_search_internal_callback_pb( pb,
00621               (void *)pb,
00622               NULL,
00623               slapi_int_search_entry_callback,
00624               NULL );
00625 }
00626 
00627 int
00628 slapi_search_internal_callback_pb( Slapi_PBlock *pb,
00629        void *callback_data,
00630        plugin_result_callback prc,
00631        plugin_search_entry_callback psec,
00632        plugin_referral_entry_callback prec )
00633 {
00634        int                  free_filter = 0;
00635        SlapReply            *rs;
00636 
00637        if ( pb == NULL ) {
00638               return -1;
00639        }
00640 
00641        PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH );
00642 
00643        rs = pb->pb_rs;
00644 
00645        /* search callback and arguments */
00646        slapi_pblock_set( pb, SLAPI_X_INTOP_RESULT_CALLBACK,         (void *)prc );
00647        slapi_pblock_set( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK,   (void *)psec );
00648        slapi_pblock_set( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void *)prec );
00649        slapi_pblock_set( pb, SLAPI_X_INTOP_CALLBACK_DATA,           (void *)callback_data );
00650 
00651        if ( BER_BVISEMPTY( &pb->pb_op->ors_filterstr )) {
00652               rs->sr_err = LDAP_PARAM_ERROR;
00653               goto cleanup;
00654        }
00655 
00656        if ( pb->pb_op->ors_filter == NULL ) {
00657               pb->pb_op->ors_filter = slapi_str2filter( pb->pb_op->ors_filterstr.bv_val );
00658               if ( pb->pb_op->ors_filter == NULL ) {
00659                      rs->sr_err = LDAP_PROTOCOL_ERROR;
00660                      goto cleanup;
00661               }
00662 
00663               free_filter = 1;
00664        }
00665 
00666        slapi_int_func_internal_pb( pb, op_search );
00667 
00668 cleanup:
00669        if ( free_filter ) {
00670               slapi_filter_free( pb->pb_op->ors_filter, 1 );
00671               pb->pb_op->ors_filter = NULL;
00672        }
00673 
00674        slapi_pblock_delete_param( pb, SLAPI_X_INTOP_RESULT_CALLBACK );
00675        slapi_pblock_delete_param( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK );
00676        slapi_pblock_delete_param( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK );
00677        slapi_pblock_delete_param( pb, SLAPI_X_INTOP_CALLBACK_DATA );
00678 
00679        return 0;
00680 }
00681 
00682 /* Wrappers for old API */
00683 
00684 void
00685 slapi_search_internal_set_pb( Slapi_PBlock *pb,
00686        const char *base,
00687        int scope,
00688        const char *filter,
00689        char **attrs,
00690        int attrsonly,
00691        LDAPControl **controls,
00692        const char *uniqueid,
00693        Slapi_ComponentId *plugin_identity,
00694        int operation_flags )
00695 {
00696        int no_limit = SLAP_NO_LIMIT;
00697        int deref = LDAP_DEREF_NEVER;
00698 
00699        slapi_int_connection_init_pb( pb, LDAP_REQ_SEARCH );
00700        slapi_pblock_set( pb, SLAPI_SEARCH_TARGET,    (void *)base );
00701        slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE,     (void *)&scope );
00702        slapi_pblock_set( pb, SLAPI_SEARCH_FILTER,    (void *)0 );
00703        slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, (void *)filter );
00704        slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS,     (void *)attrs );
00705        slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, (void *)&attrsonly );
00706        slapi_pblock_set( pb, SLAPI_REQCONTROLS,      (void *)controls );
00707        slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID,  (void *)uniqueid );
00708        slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY,  (void *)plugin_identity );
00709        slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS,    (void *)&operation_flags );
00710        slapi_pblock_set( pb, SLAPI_SEARCH_DEREF,     (void *)&deref );
00711        slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, (void *)&no_limit );
00712        slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, (void *)&no_limit );
00713 
00714        slapi_int_set_operation_dn( pb );
00715 }
00716 
00717 Slapi_PBlock *
00718 slapi_search_internal(
00719        char *ldn, 
00720        int scope, 
00721        char *filStr, 
00722        LDAPControl **controls, 
00723        char **attrs, 
00724        int attrsonly ) 
00725 {
00726        Slapi_PBlock *pb;
00727 
00728        pb = slapi_pblock_new();
00729 
00730        slapi_search_internal_set_pb( pb, ldn, scope, filStr,
00731               attrs, attrsonly,
00732               controls, NULL, NULL, 0 );
00733 
00734        slapi_search_internal_pb( pb );
00735 
00736        return pb;
00737 }
00738 
00739 void
00740 slapi_modify_internal_set_pb( Slapi_PBlock *pb,
00741        const char *dn,
00742        LDAPMod **mods,
00743        LDAPControl **controls,
00744        const char *uniqueid,
00745        Slapi_ComponentId *plugin_identity,
00746        int operation_flags )
00747 {
00748        slapi_int_connection_init_pb( pb, LDAP_REQ_MODIFY );
00749        slapi_pblock_set( pb, SLAPI_MODIFY_TARGET,   (void *)dn );
00750        slapi_pblock_set( pb, SLAPI_MODIFY_MODS,     (void *)mods );
00751        slapi_pblock_set( pb, SLAPI_REQCONTROLS,     (void *)controls );
00752        slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
00753        slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
00754        slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS,   (void *)&operation_flags );
00755        slapi_int_set_operation_dn( pb );
00756 }
00757 
00758 /* Function : slapi_modify_internal
00759  *
00760  * Description:      Plugin functions call this routine to modify an entry 
00761  *                          in the backend directly
00762  * Return values : LDAP_SUCCESS
00763  *                 LDAP_PARAM_ERROR
00764  *                 LDAP_NO_MEMORY
00765  *                 LDAP_OTHER
00766  *                 LDAP_UNWILLING_TO_PERFORM
00767 */
00768 Slapi_PBlock *
00769 slapi_modify_internal(
00770        char *ldn,    
00771        LDAPMod **mods, 
00772        LDAPControl **controls, 
00773        int log_change )
00774 {
00775        Slapi_PBlock *pb;
00776 
00777        pb = slapi_pblock_new();
00778 
00779        slapi_modify_internal_set_pb( pb, ldn, mods, controls, NULL, NULL, 0 );
00780        slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
00781        slapi_modify_internal_pb( pb );
00782 
00783        return pb;
00784 }
00785 
00786 int
00787 slapi_add_internal_set_pb( Slapi_PBlock *pb,
00788        const char *dn,
00789        LDAPMod **attrs,
00790        LDAPControl **controls,
00791        Slapi_ComponentId *plugin_identity,
00792        int operation_flags )
00793 {
00794        slapi_int_connection_init_pb( pb, LDAP_REQ_ADD );
00795        slapi_pblock_set( pb, SLAPI_ADD_TARGET,      (void *)dn );
00796        slapi_pblock_set( pb, SLAPI_MODIFY_MODS,     (void *)attrs );
00797        slapi_pblock_set( pb, SLAPI_REQCONTROLS,     (void *)controls );
00798        slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
00799        slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS,   (void *)&operation_flags );
00800        slapi_int_set_operation_dn( pb );
00801 
00802        return 0;
00803 }
00804 
00805 Slapi_PBlock *
00806 slapi_add_internal(
00807        char * dn,
00808        LDAPMod **attrs,
00809        LDAPControl **controls,
00810        int log_change )
00811 {
00812        Slapi_PBlock *pb;
00813 
00814        pb = slapi_pblock_new();
00815 
00816        slapi_add_internal_set_pb( pb, dn, attrs, controls, NULL, 0);
00817        slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
00818        slapi_add_internal_pb( pb );
00819 
00820        return pb;
00821 }
00822 
00823 void
00824 slapi_add_entry_internal_set_pb( Slapi_PBlock *pb,
00825        Slapi_Entry *e,
00826        LDAPControl **controls,
00827        Slapi_ComponentId *plugin_identity,
00828        int operation_flags )
00829 {
00830        slapi_int_connection_init_pb( pb, LDAP_REQ_ADD );
00831        slapi_pblock_set( pb, SLAPI_ADD_ENTRY,       (void *)e );
00832        slapi_pblock_set( pb, SLAPI_REQCONTROLS,     (void *)controls );
00833        slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
00834        slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS,   (void *)&operation_flags );
00835        slapi_int_set_operation_dn( pb );
00836 }
00837 
00838 Slapi_PBlock * 
00839 slapi_add_entry_internal(
00840        Slapi_Entry *e, 
00841        LDAPControl **controls, 
00842        int log_change )
00843 {
00844        Slapi_PBlock *pb;
00845 
00846        pb = slapi_pblock_new();
00847 
00848        slapi_add_entry_internal_set_pb( pb, e, controls, NULL, 0 );
00849        slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
00850        slapi_add_internal_pb( pb );
00851 
00852        return pb;
00853 }
00854 
00855 void
00856 slapi_rename_internal_set_pb( Slapi_PBlock *pb,
00857        const char *olddn,
00858        const char *newrdn,
00859        const char *newsuperior,
00860        int deloldrdn,
00861        LDAPControl **controls,
00862        const char *uniqueid,
00863        Slapi_ComponentId *plugin_identity,
00864        int operation_flags )
00865 {
00866        slapi_int_connection_init_pb( pb, LDAP_REQ_MODRDN );
00867        slapi_pblock_set( pb, SLAPI_MODRDN_TARGET,      (void *)olddn );
00868        slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN,      (void *)newrdn );
00869        slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR, (void *)newsuperior );
00870        slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN,   (void *)&deloldrdn );
00871        slapi_pblock_set( pb, SLAPI_REQCONTROLS,        (void *)controls );
00872        slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID,    (void *)uniqueid );
00873        slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY,    (void *)plugin_identity );
00874        slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS,      (void *)&operation_flags );
00875        slap_modrdn2mods( pb->pb_op, pb->pb_rs );
00876        slapi_int_set_operation_dn( pb );
00877 }
00878 
00879 /* Function : slapi_modrdn_internal
00880  *
00881  * Description : Plugin functions call this routine to modify the rdn 
00882  *                           of an entry in the backend directly
00883  * Return values : LDAP_SUCCESS
00884  *                 LDAP_PARAM_ERROR
00885  *                 LDAP_NO_MEMORY
00886  *                 LDAP_OTHER
00887  *                 LDAP_UNWILLING_TO_PERFORM
00888  *
00889  * NOTE: This function does not support the "newSuperior" option from LDAP V3.
00890  */
00891 Slapi_PBlock *
00892 slapi_modrdn_internal(
00893        char *olddn, 
00894        char *lnewrdn, 
00895        int deloldrdn, 
00896        LDAPControl **controls, 
00897        int log_change )
00898 {
00899        Slapi_PBlock *pb;
00900 
00901        pb = slapi_pblock_new ();
00902 
00903        slapi_rename_internal_set_pb( pb, olddn, lnewrdn, NULL,
00904               deloldrdn, controls, NULL, NULL, 0 );
00905        slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
00906        slapi_modrdn_internal_pb( pb );
00907 
00908        return pb;
00909 }
00910 
00911 void
00912 slapi_delete_internal_set_pb( Slapi_PBlock *pb,
00913        const char *dn,
00914        LDAPControl **controls,
00915        const char *uniqueid,
00916        Slapi_ComponentId *plugin_identity,
00917        int operation_flags )
00918 {
00919        slapi_int_connection_init_pb( pb, LDAP_REQ_DELETE );
00920        slapi_pblock_set( pb, SLAPI_TARGET_DN,       (void *)dn );
00921        slapi_pblock_set( pb, SLAPI_REQCONTROLS,     (void *)controls );
00922        slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
00923        slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
00924        slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS,   (void *)&operation_flags );
00925        slapi_int_set_operation_dn( pb );
00926 }
00927 
00928 /* Function : slapi_delete_internal
00929  *
00930  * Description : Plugin functions call this routine to delete an entry 
00931  *               in the backend directly
00932  * Return values : LDAP_SUCCESS
00933  *                 LDAP_PARAM_ERROR
00934  *                 LDAP_NO_MEMORY
00935  *                 LDAP_OTHER
00936  *                 LDAP_UNWILLING_TO_PERFORM
00937 */
00938 Slapi_PBlock *
00939 slapi_delete_internal(
00940        char *ldn, 
00941        LDAPControl **controls, 
00942        int log_change )
00943 {
00944        Slapi_PBlock *pb;
00945 
00946        pb = slapi_pblock_new();
00947 
00948        slapi_delete_internal_set_pb( pb, ldn, controls, NULL, NULL, 0 );
00949        slapi_pblock_set( pb, SLAPI_LOG_OPERATION, (void *)&log_change );
00950        slapi_delete_internal_pb( pb );
00951 
00952        return pb;
00953 }
00954 
00955 #endif /* LDAP_SLAPI */
00956