openldap/servers/slapd/slapi/slapi_ops.c
Luke Howard 48d1046a35 Make slapi_pblock directly overlaid on operation/connection/slapreply
structures

This removes a lot of copying. It's still a bit tricky where the internal
slapd data types are different to those exposed via SLAPI (eg. modifications)
or the internal values are not allocated on the heap (eg. controls). Some
copying is necessary in these cases.
2005-07-25 04:19:33 +00:00

930 lines
23 KiB
C

/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2002-2005 The OpenLDAP Foundation.
* Portions Copyright 1997,2002-2003 IBM Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
* This work was initially developed by IBM Corporation for use in
* IBM products and subsequently ported to OpenLDAP Software by
* Steve Omrani. Additional significant contributors include:
* Luke Howard
*/
#include "portable.h"
#include <ac/string.h>
#include <ac/stdarg.h>
#include <ac/ctype.h>
#include <ac/unistd.h>
#include <slap.h>
#include <lber_pvt.h>
#include <slapi.h>
#ifdef LDAP_SLAPI
static struct slap_listener slapi_listener = {
BER_BVC("slapi://"),
BER_BVC("slapi://")
};
static LDAPControl **
slapi_int_dup_controls( LDAPControl **controls )
{
LDAPControl **c;
size_t i;
if ( controls == NULL )
return NULL;
for ( i = 0; controls[i] != NULL; i++ )
;
c = (LDAPControl **) slapi_ch_calloc( i + 1, sizeof(LDAPControl *) );
for ( i = 0; controls[i] != NULL; i++ ) {
c[i] = slapi_dup_control( controls[i] );
}
return c;
}
static int
slapi_int_result(
Operation *op,
SlapReply *rs )
{
Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
plugin_result_callback prc = NULL;
void *callback_data = NULL;
LDAPControl **ctrls = NULL;
assert( pb != NULL );
slapi_pblock_get( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void **)&prc );
slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
/* we need to duplicate controls because they might go out of scope */
ctrls = slapi_int_dup_controls( rs->sr_ctrls );
slapi_pblock_set( pb, SLAPI_RESCONTROLS, ctrls );
if ( prc != NULL ) {
(*prc)( rs->sr_err, callback_data );
}
return rs->sr_err;
}
static int
slapi_int_search_entry(
Operation *op,
SlapReply *rs )
{
Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
plugin_search_entry_callback psec = NULL;
void *callback_data = NULL;
int rc = LDAP_SUCCESS;
assert( pb != NULL );
slapi_pblock_get( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void **)&psec );
slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
if ( psec != NULL ) {
rc = (*psec)( rs->sr_entry, callback_data );
}
return rc;
}
static int
slapi_int_search_reference(
Operation *op,
SlapReply *rs )
{
int i, rc = LDAP_SUCCESS;
plugin_referral_entry_callback prec = NULL;
void *callback_data = NULL;
Slapi_PBlock *pb = SLAPI_OPERATION_PBLOCK( op );
assert( pb != NULL );
slapi_pblock_get( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void **)&prec );
slapi_pblock_get( pb, SLAPI_X_INTOP_CALLBACK_DATA, &callback_data );
if ( prec != NULL ) {
for ( i = 0; rs->sr_ref[i].bv_val != NULL; i++ ) {
rc = (*prec)( rs->sr_ref[i].bv_val, callback_data );
if ( rc != LDAP_SUCCESS ) {
break;
}
}
}
return rc;
}
int
slapi_int_response( Slapi_Operation *op, SlapReply *rs )
{
int rc;
switch ( rs->sr_type ) {
case REP_RESULT:
rc = slapi_int_result( op, rs );
break;
case REP_SEARCH:
rc = slapi_int_search_entry( op, rs );
break;
case REP_SEARCHREF:
rc = slapi_int_search_reference( op, rs );
break;
default:
rc = LDAP_OTHER;
break;
}
assert( rc != SLAP_CB_CONTINUE ); /* never try to send a wire response */
return rc;
}
static int
slapi_int_get_ctrls( Slapi_PBlock *pb )
{
LDAPControl **c;
int rc = LDAP_SUCCESS;
if ( pb->pop->o_ctrls != NULL ) {
for ( c = pb->pop->o_ctrls; *c != NULL; c++ ) {
rc = slap_parse_ctrl( pb->pop, &pb->rs, *c, &pb->rs.sr_text );
if ( rc != LDAP_SUCCESS )
break;
}
}
return rc;
}
void
slapi_int_connection_init_pb( Slapi_PBlock *pb, ber_tag_t OpType )
{
Connection *conn;
Operation *op;
ber_len_t max = sockbuf_max_incoming;
conn = (Connection *) slapi_ch_calloc( 1, sizeof(Connection) );
LDAP_STAILQ_INIT( &conn->c_pending_ops );
op = (Operation *) slapi_ch_calloc( 1, OPERATION_BUFFER_SIZE );
op->o_hdr = (Opheader *)(op + 1);
op->o_hdr->oh_extensions = NULL;
op->o_controls = (void **)(op->o_hdr + 1);
op->o_callback = (slap_callback *) slapi_ch_calloc( 1, sizeof(slap_callback) );
op->o_callback->sc_response = slapi_int_response;
op->o_callback->sc_cleanup = NULL;
op->o_callback->sc_private = pb;
op->o_callback->sc_next = NULL;
conn->c_pending_ops.stqh_first = op;
/* connection object authorization information */
conn->c_authtype = LDAP_AUTH_NONE;
BER_BVZERO( &conn->c_authmech );
BER_BVZERO( &conn->c_dn );
BER_BVZERO( &conn->c_ndn );
conn->c_listener = &slapi_listener;
ber_dupbv( &conn->c_peer_domain, (struct berval *)&slap_unknown_bv );
ber_dupbv( &conn->c_peer_name, (struct berval *)&slap_unknown_bv );
LDAP_STAILQ_INIT( &conn->c_ops );
BER_BVZERO( &conn->c_sasl_bind_mech );
conn->c_sasl_authctx = NULL;
conn->c_sasl_sockctx = NULL;
conn->c_sasl_extra = NULL;
conn->c_sb = ber_sockbuf_alloc();
ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
conn->c_currentber = NULL;
/* should check status of thread calls */
ldap_pvt_thread_mutex_init( &conn->c_mutex );
ldap_pvt_thread_mutex_init( &conn->c_write_mutex );
ldap_pvt_thread_cond_init( &conn->c_write_cv );
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
conn->c_n_ops_received = 0;
conn->c_n_ops_executing = 0;
conn->c_n_ops_pending = 0;
conn->c_n_ops_completed = 0;
conn->c_n_get = 0;
conn->c_n_read = 0;
conn->c_n_write = 0;
conn->c_protocol = LDAP_VERSION3;
conn->c_activitytime = conn->c_starttime = slap_get_time();
/*
* A real connection ID is required, because syncrepl associates
* pending CSNs with unique ( connection, operation ) tuples.
* Setting a fake connection ID will cause slap_get_commit_csn()
* to return a stale value.
*/
connection_assign_nextid( conn );
conn->c_conn_state = 0x01; /* SLAP_C_ACTIVE */
conn->c_struct_state = 0x02; /* SLAP_C_USED */
conn->c_ssf = conn->c_transport_ssf = 0;
conn->c_tls_ssf = 0;
backend_connection_init( conn );
conn->c_send_ldap_result = slap_send_ldap_result;
conn->c_send_search_entry = slap_send_search_entry;
conn->c_send_ldap_extended = slap_send_ldap_extended;
conn->c_send_search_reference = slap_send_search_reference;
/* operation object */
op->o_tag = OpType;
op->o_protocol = LDAP_VERSION3;
BER_BVZERO( &op->o_authmech );
op->o_time = slap_get_time();
op->o_do_not_cache = 1;
op->o_threadctx = ldap_pvt_thread_pool_context();
op->o_tmpmemctx = NULL;
op->o_tmpmfuncs = &ch_mfuncs;
op->o_conn = conn;
op->o_connid = conn->c_connid;
op->o_bd = frontendDB;
pb->pop = op;
pb->pconn = conn;
pb->internal_op = 1;
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
}
static void
slapi_int_set_operation_dn( Slapi_PBlock *pb )
{
Backend *be;
Operation *op = pb->pop;
if ( BER_BVISNULL( &op->o_ndn ) ) {
/* set to root DN */
be = select_backend( &op->o_req_ndn, 0, 0 );
assert( be != NULL );
ber_dupbv( &op->o_dn, &be->be_rootdn );
ber_dupbv( &op->o_ndn, &be->be_rootndn );
}
}
void
slapi_int_connection_done_pb( Slapi_PBlock *pb )
{
Connection *conn;
Operation *op;
PBLOCK_ASSERT_INTOP( pb, 0 );
conn = pb->pconn;
op = pb->pop;
/* free allocated DNs */
if ( !BER_BVISNULL( &op->o_dn ) )
op->o_tmpfree( op->o_dn.bv_val, op->o_tmpmemctx );
if ( !BER_BVISNULL( &op->o_ndn ) )
op->o_tmpfree( op->o_ndn.bv_val, op->o_tmpmemctx );
if ( !BER_BVISNULL( &op->o_req_dn ) )
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
if ( !BER_BVISNULL( &op->o_req_ndn ) )
op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
switch ( op->o_tag ) {
case LDAP_REQ_MODRDN:
if ( !BER_BVISNULL( &op->orr_newrdn ))
op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );
if ( !BER_BVISNULL( &op->orr_nnewrdn ))
op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );
if ( op->orr_newSup != NULL ) {
assert( !BER_BVISNULL( op->orr_newSup ) );
op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx );
op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
}
if ( op->orr_nnewSup != NULL ) {
assert( !BER_BVISNULL( op->orr_nnewSup ) );
op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx );
op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
}
break;
case LDAP_REQ_ADD:
slapi_int_mods_free( op->ora_modlist );
break;
case LDAP_REQ_MODIFY:
slapi_int_mods_free( op->orm_modlist );
break;
case LDAP_REQ_SEARCH:
if ( op->ors_attrs != NULL ) {
op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
op->ors_attrs = NULL;
}
break;
default:
break;
}
if ( conn->c_sb != NULL ) {
ber_sockbuf_free( conn->c_sb );
}
slapi_ch_free( (void **)&pb->pop->o_callback );
slapi_ch_free( (void **)&pb->pop );
slapi_ch_free( (void **)&pb->pconn );
}
static int
slapi_int_func_internal_pb( Slapi_PBlock *pb, slap_operation_t which )
{
BI_op_bind **func;
SlapReply *rs = &pb->rs;
PBLOCK_ASSERT_INTOP( pb, 0 );
rs->sr_err = slapi_int_get_ctrls( pb );
if ( rs->sr_err != LDAP_SUCCESS ) {
return rs->sr_err;
}
func = &pb->pop->o_bd->be_bind;
rs->sr_err = func[which]( pb->pop, &pb->rs );
return rs->sr_err;
}
int
slapi_delete_internal_pb( Slapi_PBlock *pb )
{
if ( pb == NULL ) {
return -1;
}
PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_DELETE );
slapi_int_func_internal_pb( pb, op_delete );
slap_graduate_commit_csn( pb->pop );
return 0;
}
int
slapi_add_internal_pb( Slapi_PBlock *pb )
{
SlapReply *rs;
Slapi_Entry *entry_orig = NULL;
if ( pb == NULL ) {
return -1;
}
PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_ADD );
rs = &pb->rs;
entry_orig = pb->pop->ora_e;
pb->pop->ora_e = NULL;
if ( entry_orig != NULL ) {
if ( pb->pop->ora_modlist != NULL || !BER_BVISNULL( &pb->pop->o_req_ndn )) {
rs->sr_err = LDAP_PARAM_ERROR;
goto cleanup;
}
assert( BER_BVISNULL( &pb->pop->o_req_dn ) ); /* shouldn't get set */
ber_dupbv( &pb->pop->o_req_dn, &entry_orig->e_name );
ber_dupbv( &pb->pop->o_req_ndn, &entry_orig->e_nname );
} else if ( pb->pop->ora_modlist == NULL || BER_BVISNULL( &pb->pop->o_req_ndn )) {
rs->sr_err = LDAP_PARAM_ERROR;
goto cleanup;
}
/*
* The caller can specify a new entry, or a target DN and set
* of modifications, but not both.
*/
pb->pop->ora_e = (Entry *)slapi_ch_calloc( 1, sizeof(Entry) );
ber_dupbv( &pb->pop->ora_e->e_name, &pb->pop->o_req_dn );
ber_dupbv( &pb->pop->ora_e->e_nname, &pb->pop->o_req_ndn );
if ( entry_orig != NULL ) {
assert( pb->pop->ora_modlist == NULL );
rs->sr_err = slap_entry2mods( entry_orig, &pb->pop->ora_modlist,
&rs->sr_text, pb->textbuf, sizeof( pb->textbuf ) );
if ( rs->sr_err != LDAP_SUCCESS ) {
goto cleanup;
}
} else {
assert( pb->pop->ora_modlist != NULL );
}
rs->sr_err = slap_mods_check( pb->pop->ora_modlist, &rs->sr_text,
pb->textbuf, sizeof( pb->textbuf ), NULL );
if ( rs->sr_err != LDAP_SUCCESS ) {
goto cleanup;
}
if ( slapi_int_func_internal_pb( pb, op_add ) == 0 ) {
if ( pb->pop->ora_e != NULL && pb->pop->o_private != NULL ) {
BackendDB *bd = pb->pop->o_bd;
/* could we use SLAPI_BACKEND instead? */
pb->pop->o_bd = (BackendDB *)pb->pop->o_private;
pb->pop->o_private = NULL;
be_entry_release_w( pb->pop, pb->pop->ora_e );
pb->pop->ora_e = NULL;
pb->pop->o_bd = bd;
pb->pop->o_private = NULL;
}
}
cleanup:
slap_graduate_commit_csn( pb->pop );
if ( pb->pop->ora_e != NULL ) {
slapi_entry_free( pb->pop->ora_e );
pb->pop->ora_e = NULL;
}
if ( entry_orig != NULL ) {
pb->pop->ora_e = entry_orig;
slapi_int_mods_free( pb->pop->ora_modlist );
pb->pop->ora_modlist = NULL;
}
return 0;
}
int
slapi_modrdn_internal_pb( Slapi_PBlock *pb )
{
if ( pb == NULL ) {
return -1;
}
PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODRDN );
if ( BER_BVISEMPTY( &pb->pop->o_req_ndn ) ) {
pb->rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
goto cleanup;
}
slapi_int_func_internal_pb( pb, op_modrdn );
cleanup:
slap_graduate_commit_csn( pb->pop );
return 0;
}
int
slapi_modify_internal_pb( Slapi_PBlock *pb )
{
SlapReply *rs;
if ( pb == NULL ) {
return -1;
}
PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_MODIFY );
rs = &pb->rs;
if ( pb->pop->orm_modlist == NULL ) {
rs->sr_err = LDAP_PARAM_ERROR;
goto cleanup;
}
if ( BER_BVISEMPTY( &pb->pop->o_req_ndn ) ) {
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
goto cleanup;
}
rs->sr_err = slap_mods_check( pb->pop->orm_modlist,
&rs->sr_text, pb->textbuf, sizeof( pb->textbuf ), NULL );
if ( rs->sr_err != LDAP_SUCCESS ) {
goto cleanup;
}
slapi_int_func_internal_pb( pb, op_modify );
cleanup:
slap_graduate_commit_csn( pb->pop );
return 0;
}
static int
slapi_int_search_entry_callback( Slapi_Entry *entry, void *callback_data )
{
int nentries = 0, i = 0;
Slapi_Entry **head = NULL, **tp;
Slapi_PBlock *pb = (Slapi_PBlock *)callback_data;
PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH );
entry = slapi_entry_dup( entry );
if ( entry == NULL ) {
return LDAP_NO_MEMORY;
}
slapi_pblock_get( pb, SLAPI_NENTRIES, &nentries );
slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );
i = nentries + 1;
if ( nentries == 0 ) {
tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );
if ( tp == NULL ) {
slapi_entry_free( entry );
return LDAP_NO_MEMORY;
}
tp[0] = entry;
} else {
tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,
sizeof(Slapi_Entry *) * ( i + 1 ) );
if ( tp == NULL ) {
slapi_entry_free( entry );
return LDAP_NO_MEMORY;
}
tp[i - 1] = entry;
}
tp[i] = NULL;
slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );
slapi_pblock_set( pb, SLAPI_NENTRIES, (void *)i );
return LDAP_SUCCESS;
}
int
slapi_search_internal_pb( Slapi_PBlock *pb )
{
return slapi_search_internal_callback_pb( pb,
(void *)pb,
NULL,
slapi_int_search_entry_callback,
NULL );
}
int
slapi_search_internal_callback_pb( Slapi_PBlock *pb,
void *callback_data,
plugin_result_callback prc,
plugin_search_entry_callback psec,
plugin_referral_entry_callback prec )
{
int free_filter = 0;
SlapReply *rs;
if ( pb == NULL ) {
return -1;
}
PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH );
rs = &pb->rs;
/* search callback and arguments */
slapi_pblock_set( pb, SLAPI_X_INTOP_RESULT_CALLBACK, (void *)prc );
slapi_pblock_set( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, (void *)psec );
slapi_pblock_set( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void *)prec );
slapi_pblock_set( pb, SLAPI_X_INTOP_CALLBACK_DATA, (void *)callback_data );
if ( BER_BVISEMPTY( &pb->pop->ors_filterstr )) {
rs->sr_err = LDAP_PARAM_ERROR;
goto cleanup;
}
if ( pb->pop->ors_filter == NULL ) {
pb->pop->ors_filter = slapi_str2filter( pb->pop->ors_filterstr.bv_val );
if ( pb->pop->ors_filter == NULL ) {
rs->sr_err = LDAP_PROTOCOL_ERROR;
goto cleanup;
}
free_filter = 1;
}
slapi_int_func_internal_pb( pb, op_search );
cleanup:
if ( free_filter ) {
slapi_filter_free( pb->pop->ors_filter, 1 );
pb->pop->ors_filter = NULL;
}
slapi_pblock_set( pb, SLAPI_X_INTOP_RESULT_CALLBACK, NULL );
slapi_pblock_set( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK, NULL );
slapi_pblock_set( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, NULL );
slapi_pblock_set( pb, SLAPI_X_INTOP_CALLBACK_DATA, NULL );
return 0;
}
/* Wrappers for old API */
void
slapi_search_internal_set_pb( Slapi_PBlock *pb,
const char *base,
int scope,
const char *filter,
char **attrs,
int attrsonly,
LDAPControl **controls,
const char *uniqueid,
Slapi_ComponentId *plugin_identity,
int operation_flags )
{
slapi_int_connection_init_pb( pb, LDAP_REQ_SEARCH );
slapi_pblock_set( pb, SLAPI_SEARCH_TARGET, (void *)base );
slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, (void *)scope );
slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, NULL );
slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, (void *)filter );
slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, (void *)attrs );
slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, (void *)attrsonly );
slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)operation_flags );
slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, (void *)0 );
slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, (void *)SLAP_NO_LIMIT );
slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, (void *)SLAP_NO_LIMIT );
slapi_int_set_operation_dn( pb );
}
Slapi_PBlock *
slapi_search_internal(
char *ldn,
int scope,
char *filStr,
LDAPControl **controls,
char **attrs,
int attrsonly )
{
Slapi_PBlock *pb;
pb = slapi_pblock_new();
slapi_search_internal_set_pb( pb, ldn, scope, filStr,
attrs, attrsonly,
controls, NULL, NULL, 0 );
slapi_search_internal_pb( pb );
return pb;
}
void
slapi_modify_internal_set_pb( Slapi_PBlock *pb,
const char *dn,
LDAPMod **mods,
LDAPControl **controls,
const char *uniqueid,
Slapi_ComponentId *plugin_identity,
int operation_flags )
{
slapi_int_connection_init_pb( pb, LDAP_REQ_MODIFY );
slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn );
slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)mods );
slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)operation_flags );
slapi_int_set_operation_dn( pb );
}
/* Function : slapi_modify_internal
*
* Description: Plugin functions call this routine to modify an entry
* in the backend directly
* Return values : LDAP_SUCCESS
* LDAP_PARAM_ERROR
* LDAP_NO_MEMORY
* LDAP_OTHER
* LDAP_UNWILLING_TO_PERFORM
*/
Slapi_PBlock *
slapi_modify_internal(
char *ldn,
LDAPMod **mods,
LDAPControl **controls,
int log_change )
{
Slapi_PBlock *pb;
pb = slapi_pblock_new();
slapi_modify_internal_set_pb( pb, ldn, mods, controls, NULL, NULL,
log_change ? SLAPI_OP_FLAG_LOG_CHANGE : 0 );
slapi_modify_internal_pb( pb );
return pb;
}
int
slapi_add_internal_set_pb( Slapi_PBlock *pb,
const char *dn,
LDAPMod **attrs,
LDAPControl **controls,
Slapi_ComponentId *plugin_identity,
int operation_flags )
{
slapi_int_connection_init_pb( pb, LDAP_REQ_ADD );
slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn );
slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)attrs );
slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)operation_flags );
slapi_int_set_operation_dn( pb );
return 0;
}
Slapi_PBlock *
slapi_add_internal(
char * dn,
LDAPMod **attrs,
LDAPControl **controls,
int log_changes )
{
Slapi_PBlock *pb;
pb = slapi_pblock_new();
slapi_add_internal_set_pb( pb, dn, attrs, controls, NULL,
log_changes ? SLAPI_OP_FLAG_LOG_CHANGE : 0 );
slapi_add_internal_pb( pb );
return pb;
}
void
slapi_add_entry_internal_set_pb( Slapi_PBlock *pb,
Slapi_Entry *e,
LDAPControl **controls,
Slapi_ComponentId *plugin_identity,
int operation_flags )
{
slapi_int_connection_init_pb( pb, LDAP_REQ_ADD );
slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e );
slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)operation_flags );
slapi_int_set_operation_dn( pb );
}
Slapi_PBlock *
slapi_add_entry_internal(
Slapi_Entry *e,
LDAPControl **controls,
int log_changes )
{
Slapi_PBlock *pb;
pb = slapi_pblock_new();
slapi_add_entry_internal_set_pb( pb, e, controls, NULL,
log_changes ? SLAPI_OP_FLAG_LOG_CHANGE : 0 );
slapi_add_internal_pb( pb );
return pb;
}
void
slapi_rename_internal_set_pb( Slapi_PBlock *pb,
const char *olddn,
const char *newrdn,
const char *newsuperior,
int deloldrdn,
LDAPControl **controls,
const char *uniqueid,
Slapi_ComponentId *plugin_identity,
int operation_flags )
{
slapi_int_connection_init_pb( pb, LDAP_REQ_MODRDN );
slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)olddn );
slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn );
slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR, (void *)newsuperior );
slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)deloldrdn );
slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)operation_flags );
slapi_int_set_operation_dn( pb );
}
/* Function : slapi_modrdn_internal
*
* Description : Plugin functions call this routine to modify the rdn
* of an entry in the backend directly
* Return values : LDAP_SUCCESS
* LDAP_PARAM_ERROR
* LDAP_NO_MEMORY
* LDAP_OTHER
* LDAP_UNWILLING_TO_PERFORM
*
* NOTE: This function does not support the "newSuperior" option from LDAP V3.
*/
Slapi_PBlock *
slapi_modrdn_internal(
char *olddn,
char *lnewrdn,
int deloldrdn,
LDAPControl **controls,
int log_change )
{
Slapi_PBlock *pb;
pb = slapi_pblock_new ();
slapi_rename_internal_set_pb( pb, olddn, lnewrdn, NULL,
deloldrdn, controls, NULL, NULL,
log_change ? SLAPI_OP_FLAG_LOG_CHANGE : 0 );
slapi_modrdn_internal_pb( pb );
return pb;
}
void
slapi_delete_internal_set_pb( Slapi_PBlock *pb,
const char *dn,
LDAPControl **controls,
const char *uniqueid,
Slapi_ComponentId *plugin_identity,
int operation_flags )
{
slapi_int_connection_init_pb( pb, LDAP_REQ_DELETE );
slapi_pblock_set( pb, SLAPI_TARGET_DN, (void *)dn );
slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)controls );
slapi_pblock_set( pb, SLAPI_TARGET_UNIQUEID, (void *)uniqueid );
slapi_pblock_set( pb, SLAPI_PLUGIN_IDENTITY, (void *)plugin_identity );
slapi_pblock_set( pb, SLAPI_X_INTOP_FLAGS, (void *)operation_flags );
slapi_int_set_operation_dn( pb );
}
/* Function : slapi_delete_internal
*
* Description : Plugin functions call this routine to delete an entry
* in the backend directly
* Return values : LDAP_SUCCESS
* LDAP_PARAM_ERROR
* LDAP_NO_MEMORY
* LDAP_OTHER
* LDAP_UNWILLING_TO_PERFORM
*/
Slapi_PBlock *
slapi_delete_internal(
char *ldn,
LDAPControl **controls,
int log_change )
{
Slapi_PBlock *pb;
pb = slapi_pblock_new();
slapi_delete_internal_set_pb( pb, ldn, controls, NULL, NULL,
log_change ? SLAPI_OP_FLAG_LOG_CHANGE : 0 );
slapi_delete_internal_pb( pb );
return pb;
}
#endif /* LDAP_SLAPI */