summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/operation.c
diff options
context:
space:
mode:
authorcvsadm <cvsadm>2005-01-21 00:44:34 +0000
committercvsadm <cvsadm>2005-01-21 00:44:34 +0000
commitb2093e3016027d6b5cf06b3f91f30769bfc099e2 (patch)
treecf58939393a9032182c4fbc4441164a9456e82f8 /ldap/servers/slapd/operation.c
downloadds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.gz
ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.xz
ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.zip
Moving NSCP Directory Server from DirectoryBranch to TRUNK, initial drop. (foxworth)ldapserver7x
Diffstat (limited to 'ldap/servers/slapd/operation.c')
-rw-r--r--ldap/servers/slapd/operation.c410
1 files changed, 410 insertions, 0 deletions
diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
new file mode 100644
index 00000000..a049e382
--- /dev/null
+++ b/ldap/servers/slapd/operation.c
@@ -0,0 +1,410 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* operation.c - routines to deal with pending ldap operations */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#endif
+#include "slap.h"
+
+int
+slapi_op_abandoned( Slapi_PBlock *pb )
+{
+ int op_status;
+
+ op_status = pb->pb_op->o_status;
+
+ return( op_status == SLAPI_OP_STATUS_ABANDONED );
+}
+
+void
+operation_out_of_disk_space()
+{
+ LDAPDebug(LDAP_DEBUG_ANY, "*** DISK FULL ***\n", 0, 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "Attempting to shut down gracefully.\n", 0, 0, 0);
+ g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL );
+}
+
+/* Setting the flags on the operation allows more control to the plugin
+ * to disable and enable checks
+ * Flags that we support for setting in the operation from the plugin are
+ * SLAPI_OP_FLAG_NO_ACCESS_CHECK - do not check for access control
+ * This function can be extended to support other flag setting as well
+ */
+
+void slapi_operation_set_flag(Slapi_Operation *op, unsigned long flag)
+{
+
+ operation_set_flag(op, flag);
+
+}
+
+void slapi_operation_clear_flag(Slapi_Operation *op, unsigned long flag)
+{
+ operation_clear_flag(op, flag);
+
+}
+
+int slapi_operation_is_flag_set(Slapi_Operation *op, unsigned long flag)
+{
+ return operation_is_flag_set(op, flag);
+}
+
+
+
+static int operation_type = -1; /* The type number assigned by the Factory for 'Operation' */
+
+int
+get_operation_object_type()
+{
+ if(operation_type==-1)
+ {
+ /* The factory is given the name of the object type, in
+ * return for a type handle. Whenever the object is created
+ * or destroyed the factory is called with the handle so
+ * that it may call the constructors or destructors registered
+ * with it.
+ */
+ operation_type= factory_register_type(SLAPI_EXT_OPERATION,offsetof(Operation,o_extension));
+ }
+ return operation_type;
+}
+
+/*
+ * Allocate a new Slapi_Operation.
+ * The flag parameter indicates whether the the operation is
+ * external (from an LDAP Client), or internal (from a plugin).
+ */
+Slapi_Operation *
+operation_new(int flags)
+{
+ /* To improve performance, we allocate the Operation, BerElement and
+ * ber buffer in one block, instead of a separate malloc() for each.
+ * Subsequently, ber_special_free() frees them all; we're careful
+ * not to free the Operation separately, and the ber software knows
+ * not to free the buffer separately.
+ */
+ BerElement *ber = NULL;
+ Slapi_Operation *o;
+ if(flags & OP_FLAG_INTERNAL)
+ {
+ o = (Slapi_Operation *) slapi_ch_malloc(sizeof(Slapi_Operation));
+ }
+ else
+ {
+ o= (Slapi_Operation *) ber_special_alloc( sizeof(Slapi_Operation), &ber );
+ }
+ if (NULL != o)
+ {
+ memset(o,0,sizeof(Slapi_Operation));
+ o->o_ber = ber;
+ o->o_msgid = -1;
+ o->o_tag = LBER_DEFAULT;
+ o->o_status = SLAPI_OP_STATUS_PROCESSING;
+ slapi_sdn_init(&(o->o_sdn));
+ o->o_authtype = NULL;
+ o->o_isroot = 0;
+ o->o_time = current_time();
+ o->o_opid = 0;
+ o->o_connid = 0;
+ o->o_next = NULL;
+ o->o_flags= flags;
+ if ( config_get_accesslog_level() & LDAP_DEBUG_TIMING ) {
+ o->o_interval = PR_IntervalNow();
+ } else {
+ o->o_interval = (PRIntervalTime)0;
+ }
+ }
+ return o;
+}
+
+void
+operation_free( Slapi_Operation **op, Connection *conn )
+{
+ if(op!=NULL && *op!=NULL)
+ {
+ /* Call the plugin extension destructors */
+ factory_destroy_extension(get_operation_object_type(),*op,conn,&((*op)->o_extension));
+ slapi_sdn_done(&(*op)->o_sdn);
+ slapi_sdn_free(&(*op)->o_target_spec);
+ free( (*op)->o_authtype );
+ if ( (*op)->o_searchattrs != NULL ) {
+ cool_charray_free( (*op)->o_searchattrs );
+ }
+ if ( NULL != (*op)->o_params.request_controls ) {
+ ldap_controls_free( (*op)->o_params.request_controls );
+ }
+ if ( NULL != (*op)->o_results.result_controls ) {
+ ldap_controls_free( (*op)->o_results.result_controls );
+ }
+ if(operation_is_flag_set(*op, OP_FLAG_INTERNAL))
+ {
+ slapi_ch_free((void**)op);
+ }
+ else
+ {
+ ber_special_free( *op , (*op)->o_ber);
+ }
+ /* counters_to_errors_log("after operation"); */
+ }
+}
+
+void
+slapi_operation_set_csngen_handler ( Slapi_Operation *op, void *callback )
+{
+ op->o_csngen_handler = (csngen_handler) callback;
+}
+
+void
+slapi_operation_set_replica_attr_handler ( Slapi_Operation *op, void *callback )
+{
+ op->o_replica_attr_handler = (replica_attr_handler) callback;
+}
+
+int
+slapi_operation_get_replica_attr ( Slapi_PBlock *pb, Slapi_Operation *op, const char *type, void *value )
+{
+ int rc = -1;
+
+ if (op->o_replica_attr_handler)
+ {
+ rc = op->o_replica_attr_handler ( pb, type, value );
+ }
+
+ return rc;
+}
+
+CSN *
+operation_get_csn(Slapi_Operation *op)
+{
+ return op->o_params.csn;
+}
+
+void
+operation_set_csn(Slapi_Operation *op,CSN *csn)
+{
+ op->o_params.csn= csn;
+}
+
+unsigned long
+slapi_op_get_type(Slapi_Operation *op)
+{
+ return op->o_params.operation_type;
+}
+
+/* DEPRECATED : USE FUNCTION ABOVE FOR NEW DVLPT */
+unsigned long
+operation_get_type(Slapi_Operation *op)
+{
+ return op->o_params.operation_type;
+}
+
+void
+operation_set_type(Slapi_Operation *op, unsigned long type)
+{
+ op->o_params.operation_type= type;
+}
+
+void
+operation_set_flag(Slapi_Operation *op, int flag)
+{
+ op->o_flags|= flag;
+}
+
+void
+operation_clear_flag(Slapi_Operation *op, int flag)
+{
+ op->o_flags &= ~flag;
+}
+
+int
+operation_is_flag_set(Slapi_Operation *op, int flag)
+{
+ return op->o_flags & flag;
+}
+
+Slapi_DN*
+operation_get_target_spec (Slapi_Operation *op)
+{
+ return op->o_target_spec;
+}
+
+void
+operation_set_target_spec (Slapi_Operation *op, const Slapi_DN *target_spec)
+{
+ PR_ASSERT (op);
+ PR_ASSERT (target_spec);
+
+ op->o_target_spec = slapi_sdn_dup(target_spec);
+}
+
+void
+operation_set_target_spec_str (Slapi_Operation *op, const char *target_spec)
+{
+ PR_ASSERT (op);
+
+ op->o_target_spec = slapi_sdn_new_dn_byval (target_spec);
+}
+
+unsigned long operation_get_abandoned_op (const Slapi_Operation *op)
+{
+ PR_ASSERT (op);
+
+ return op->o_abandoned_op;
+}
+
+void operation_set_abandoned_op (Slapi_Operation *op, unsigned long abandoned_op)
+{
+ PR_ASSERT (op);
+
+ op->o_abandoned_op = abandoned_op;
+}
+
+/* slapi_operation_parameters manipulation functions */
+
+struct slapi_operation_parameters *operation_parameters_new()
+{
+ return (slapi_operation_parameters *)slapi_ch_calloc (1, sizeof (slapi_operation_parameters));
+}
+
+static LDAPMod **
+copy_mods(LDAPMod **orig_mods)
+{
+ LDAPMod **new_mods = NULL;
+ LDAPMod *mod;
+ Slapi_Mods smods_old;
+ Slapi_Mods smods_new;
+ slapi_mods_init_byref(&smods_old,orig_mods);
+ slapi_mods_init_passin(&smods_new,new_mods);
+ mod= slapi_mods_get_first_mod(&smods_old);
+ while(mod!=NULL)
+ {
+ slapi_mods_add_modbvps(&smods_new,mod->mod_op,mod->mod_type,mod->mod_bvalues);
+ mod= slapi_mods_get_next_mod(&smods_old);
+ }
+ new_mods= slapi_mods_get_ldapmods_passout(&smods_new);
+ slapi_mods_done(&smods_old);
+ slapi_mods_done(&smods_new);
+ return new_mods;
+}
+
+struct slapi_operation_parameters *
+operation_parameters_dup(struct slapi_operation_parameters *sop)
+{
+ struct slapi_operation_parameters *sop_new= (struct slapi_operation_parameters *)
+ slapi_ch_malloc(sizeof(struct slapi_operation_parameters));
+ memcpy(sop_new,sop,sizeof(struct slapi_operation_parameters));
+ if(sop->target_address.dn!=NULL)
+ {
+ sop_new->target_address.dn= slapi_ch_strdup(sop->target_address.dn);
+ }
+ if(sop->target_address.uniqueid!=NULL)
+ {
+ sop_new->target_address.uniqueid= slapi_ch_strdup(sop->target_address.uniqueid);
+ }
+
+ sop_new->csn= csn_dup(sop->csn);
+ switch(sop->operation_type)
+ {
+ case SLAPI_OPERATION_ADD:
+ sop_new->p.p_add.target_entry= slapi_entry_dup(sop->p.p_add.target_entry);
+ sop_new->p.p_add.parentuniqueid = slapi_ch_strdup(sop->p.p_add.parentuniqueid);
+ break;
+ case SLAPI_OPERATION_MODIFY:
+ sop_new->p.p_modify.modify_mods= NULL;
+ if (sop->p.p_modify.modify_mods!=NULL)
+ {
+ sop_new->p.p_modify.modify_mods = copy_mods(sop->p.p_modify.modify_mods);
+ }
+ break;
+ case SLAPI_OPERATION_MODRDN:
+ if(sop->p.p_modrdn.modrdn_newrdn!=NULL)
+ {
+ sop_new->p.p_modrdn.modrdn_newrdn= slapi_ch_strdup(sop->p.p_modrdn.modrdn_newrdn);
+ }
+ if(sop->p.p_modrdn.modrdn_newsuperior_address.dn!=NULL)
+ {
+ sop_new->p.p_modrdn.modrdn_newsuperior_address.dn =
+ slapi_ch_strdup(sop->p.p_modrdn.modrdn_newsuperior_address.dn);
+ }
+ if(sop->p.p_modrdn.modrdn_newsuperior_address.uniqueid!=NULL)
+ {
+ sop_new->p.p_modrdn.modrdn_newsuperior_address.uniqueid =
+ slapi_ch_strdup(sop->p.p_modrdn.modrdn_newsuperior_address.uniqueid);
+ }
+ sop_new->p.p_modrdn.modrdn_mods= NULL;
+ if (sop->p.p_modrdn.modrdn_mods!=NULL)
+ {
+ sop_new->p.p_modrdn.modrdn_mods = copy_mods(sop->p.p_modrdn.modrdn_mods);
+ }
+ break;
+ case SLAPI_OPERATION_DELETE:
+ /* Has no extra parameters. */
+ case SLAPI_OPERATION_BIND:
+ case SLAPI_OPERATION_COMPARE:
+ case SLAPI_OPERATION_SEARCH:
+ default:
+ /* We are not interested in these. */
+ break;
+ }
+ return sop_new;
+}
+
+void
+operation_parameters_done (struct slapi_operation_parameters *sop)
+{
+ if(sop!=NULL)
+ {
+ slapi_ch_free((void **)&sop->target_address.dn);
+ slapi_ch_free((void **)&sop->target_address.uniqueid);
+ csn_free(&sop->csn);
+
+ switch(sop->operation_type)
+ {
+ case SLAPI_OPERATION_ADD:
+ slapi_entry_free(sop->p.p_add.target_entry);
+ sop->p.p_add.target_entry= NULL;
+ slapi_ch_free((void **)&(sop->p.p_add.parentuniqueid));
+ break;
+ case SLAPI_OPERATION_MODIFY:
+ ldap_mods_free(sop->p.p_modify.modify_mods, 1 /* Free the Array and the Elements */);
+ sop->p.p_modify.modify_mods= NULL;
+ break;
+ case SLAPI_OPERATION_MODRDN:
+ slapi_ch_free((void **)&(sop->p.p_modrdn.modrdn_newrdn));
+ slapi_ch_free((void **)&(sop->p.p_modrdn.modrdn_newsuperior_address.dn));
+ slapi_ch_free((void **)&(sop->p.p_modrdn.modrdn_newsuperior_address.uniqueid));
+ ldap_mods_free(sop->p.p_modrdn.modrdn_mods, 1 /* Free the Array and the Elements */);
+ sop->p.p_modrdn.modrdn_mods= NULL;
+ break;
+ case SLAPI_OPERATION_DELETE:
+ /* Has no extra parameters. */
+ case SLAPI_OPERATION_BIND:
+ case SLAPI_OPERATION_COMPARE:
+ case SLAPI_OPERATION_SEARCH:
+ default:
+ /* We are not interested in these */
+ break;
+ }
+ }
+}
+
+void operation_parameters_free(struct slapi_operation_parameters **sop)
+{
+ if (sop)
+ {
+ operation_parameters_done (*sop);
+ slapi_ch_free ((void**)sop);
+ }
+}
+
+
+
+
+