]> git.sur5r.net Git - openldap/commitdiff
SLAPI - Netscape plugin API for slapd - based on patch contributed by Steve Omrani...
authorPierangelo Masarati <ando@openldap.org>
Sat, 7 Dec 2002 17:19:29 +0000 (17:19 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 7 Dec 2002 17:19:29 +0000 (17:19 +0000)
41 files changed:
configure.in
include/slapi-plugin.h [new file with mode: 0644]
servers/slapd/Makefile.in
servers/slapd/add.c
servers/slapd/backend.c
servers/slapd/bind.c
servers/slapd/compare.c
servers/slapd/config.c
servers/slapd/connection.c
servers/slapd/controls.c
servers/slapd/delete.c
servers/slapd/extended.c
servers/slapd/main.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/operation.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/root_dse.c
servers/slapd/search.c
servers/slapd/slap.h
servers/slapd/slapi/Makefile.in [new file with mode: 0644]
servers/slapd/slapi/README [new file with mode: 0644]
servers/slapd/slapi/ibm_pblock_params.h [new file with mode: 0644]
servers/slapd/slapi/plugin.c [new file with mode: 0644]
servers/slapd/slapi/plugin.h [new file with mode: 0644]
servers/slapd/slapi/printmsg.c [new file with mode: 0644]
servers/slapd/slapi/slapi-plugin.h [new file with mode: 0644]
servers/slapd/slapi/slapi.h [new file with mode: 0644]
servers/slapd/slapi/slapi_cl.h [new file with mode: 0644]
servers/slapd/slapi/slapi_common.h [new file with mode: 0644]
servers/slapd/slapi/slapi_ops.c [new file with mode: 0644]
servers/slapd/slapi/slapi_ops.c.all [new file with mode: 0644]
servers/slapd/slapi/slapi_ops.c.save [new file with mode: 0644]
servers/slapd/slapi/slapi_ops.h [new file with mode: 0644]
servers/slapd/slapi/slapi_pblock.c [new file with mode: 0644]
servers/slapd/slapi/slapi_pblock.h [new file with mode: 0644]
servers/slapd/slapi/slapi_utils.c [new file with mode: 0644]
servers/slapd/slapi/slapi_utils.h [new file with mode: 0644]
servers/slapd/tools/Makefile.in
servers/slapd/tools/mimic.c

index e0594ebed2e7a6079397cba709b64d8768e9b9a9..464d36f6d6befad000171cb3a07e5f487900d40a 100644 (file)
@@ -186,6 +186,8 @@ OL_ARG_ENABLE(rlookups,[    --enable-rlookups         enable reverse lookups of client
 OL_ARG_ENABLE(slp, [    --enable-slp          enable SLPv2 support], no)dnl     
 OL_ARG_ENABLE(wrappers,[    --enable-wrappers    enable tcp wrapper support], no)dnl
 
+OL_ARG_ENABLE(slapi,[    --enable-slapi   enable installation of slapi library], yes)dnl
+
 dnl SLAPD Backend options
 OL_ARG_ENABLE(bdb,[    --enable-bdb      enable Berkeley DB backend], yes)dnl
 OL_ARG_WITH(bdb_module,[    --with-bdb-module     module type static|dynamic], static,
@@ -247,6 +249,9 @@ dnl General "enable" options
 # validate options
 if test $ol_enable_slapd = no ; then
        dnl SLAPD was specificallly disabled
+       if test $ol_enable_slapi = yes ; then
+               AC_MSG_WARN([slapd disabled, ignoring --enable-slapi argument])
+       fi
        if test $ol_enable_bdb = yes ; then
                AC_MSG_WARN([slapd disabled, ignoring --enable-bdb argument])
        fi
@@ -351,6 +356,7 @@ if test $ol_enable_slapd = no ; then
        fi
 
        # force settings to no
+       ol_enable_slapi=no
        ol_enable_bdb=no
        ol_enable_dnssrv=no
        ol_enable_ldap=no
@@ -521,6 +527,9 @@ BUILD_SLURPD=no
 
 BUILD_THREAD=no
 
+BUILD_SLAPI=no
+SLAPD_SLAPI_DEPEND=
+
 BUILD_BDB=no
 BUILD_DNSSRV=no
 BUILD_LDAP=no
@@ -569,6 +578,7 @@ SASL_LIBS=
 TERMCAP_LIBS=
 TLS_LIBS=
 MODULES_LIBS=
+SLAPI_LIBS=
 AUTH_LIBS=
 
 SLAPD_SLP_LIBS=
@@ -2504,6 +2514,22 @@ OL_SYS_ERRLIST
 dnl ----------------------------------------------------------------
 dnl Sort out defines
 
+if test "$ol_enable_slapi" != no ; then
+       dnl This check is donel also if --enable-modules is used;
+       dnl it is duplicated here, 'cause it'd be cached anyway
+       AC_CHECK_HEADERS(ltdl.h)
+
+       if test $ac_cv_header_ltdl_h != yes ; then
+               AC_MSG_ERROR([could not locate <ltdl.h>])
+       fi
+       AC_CHECK_LIB(ltdl, lt_dlinit, [
+               SLAPI_LIBS=-lltdl
+               AC_DEFINE(HAVE_LIBLTDL,1,[define if you have libtool -ltdl])
+       ],[AC_MSG_ERROR([could not locate libtool -lltdl])])
+
+       AC_DEFINE(LDAP_SLAPI,1, [define this to add SLAPI code])
+fi
+
 if test "$ol_enable_debug" != no ; then
        AC_DEFINE(LDAP_DEBUG,1,
                [define this to add debugging code])
@@ -2764,6 +2790,12 @@ if test "$ol_enable_rewrite" != no ; then
        BUILD_REWRITE=yes
 fi
 
+if test "$ol_enable_slapi" != no ; then
+       AC_DEFINE(ENABLE_SLAPI,1,[define to enable slapi library])
+       BUILD_SLAPI=yes
+       SLAPD_SLAPI_DEPEND=libslapi.a
+fi
+
 dnl ----------------------------------------------------------------
 
 dnl
@@ -2789,6 +2821,8 @@ AC_SUBST(PLAT)
 AC_SUBST(BUILD_LIBS_DYNAMIC)
 
 AC_SUBST(BUILD_SLAPD)
+  AC_SUBST(BUILD_SLAPI)
+  AC_SUBST(SLAPD_SLAPI_DEPEND)
   AC_SUBST(BUILD_BDB)
   AC_SUBST(BUILD_DNSSRV)
   AC_SUBST(BUILD_LDAP)
@@ -2843,6 +2877,7 @@ AC_SUBST(SASL_LIBS)
 AC_SUBST(TERMCAP_LIBS)
 AC_SUBST(TLS_LIBS)
 AC_SUBST(MODULES_LIBS)
+AC_SUBST(SLAPI_LIBS)
 AC_SUBST(AUTH_LIBS)
 
 AC_SUBST(SLAPD_SLP_LIBS)
@@ -2896,6 +2931,7 @@ servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile
 servers/slapd/back-sql/Makefile:build/top.mk:servers/slapd/back-sql/Makefile.in:build/mod.mk \
 servers/slapd/back-tcl/Makefile:build/top.mk:servers/slapd/back-tcl/Makefile.in:build/mod.mk \
 servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk \
+servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk  \
 servers/slapd/tools/Makefile:build/top.mk:servers/slapd/tools/Makefile.in \
 servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk \
 tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk \
diff --git a/include/slapi-plugin.h b/include/slapi-plugin.h
new file mode 100644 (file)
index 0000000..cbded3a
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is
+ * given to IBM Corporation. This software is provided ``as is''
+ * without express or implied warranty.
+ */
+
+#ifndef _SLAPI_PLUGIN_H
+#define _SLAPI_PLUGIN_H
+
+#include "lber.h"
+#include "ldap.h"
+
+typedef struct slapi_pblock    Slapi_PBlock;
+typedef struct slapi_entry     Slapi_Entry;
+typedef struct slapi_attr      Slapi_Attr;
+typedef struct slapi_filter    Slapi_Filter;
+
+
+/* pblock routines */
+int slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value );
+int slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value );
+Slapi_PBlock *slapi_pblock_new();
+void slapi_pblock_destroy( Slapi_PBlock* );
+
+/*entry/attr/dn routines */
+Slapi_Entry *slapi_str2entry( char *s, int flags );
+char *slapi_entry2str( Slapi_Entry *e, int *len );
+char *slapi_entry_get_dn( Slapi_Entry *e );
+void slapi_entry_set_dn(Slapi_Entry *e, char *dn);
+Slapi_Entry *slapi_entry_dup(Slapi_Entry *e);
+int slapi_entry_attr_delete( Slapi_Entry *e, char *type );
+Slapi_Entry *slapi_entry_alloc();
+void slapi_entry_free( Slapi_Entry *e );
+int slapi_entry_attr_merge( Slapi_Entry *e, char *type, struct berval **vals );
+int slapi_entry_attr_find( Slapi_Entry *e, char *type, Slapi_Attr **attr );
+int slapi_attr_get_values( Slapi_Attr *attr, struct berval ***vals );
+char *slapi_dn_normalize( char *dn );
+char *slapi_dn_normalize_case( char *dn );
+int slapi_dn_issuffix( char *dn, char *suffix );
+char *slapi_dn_ignore_case( char *dn );
+
+/* char routines */
+char * slapi_ch_malloc( unsigned long size );
+void slapi_ch_free( void *ptr );
+char *slapi_ch_calloc( unsigned long nelem, unsigned long size );
+char *slapi_ch_realloc(char *block, unsigned long size );
+char *slapi_ch_strdup(char *s );
+
+
+/* LDAP V3 routines */
+int slapi_control_present( LDAPControl **controls, char *oid, struct berval **val, int *iscritical);
+void slapi_register_supported_control(char *controloid, unsigned long controlops);
+#define SLAPI_OPERATION_BIND            0x00000001L
+#define SLAPI_OPERATION_UNBIND          0x00000002L
+#define SLAPI_OPERATION_SEARCH          0x00000004L
+#define SLAPI_OPERATION_MODIFY          0x00000008L
+#define SLAPI_OPERATION_ADD             0x00000010L
+#define SLAPI_OPERATION_DELETE          0x00000020L
+#define SLAPI_OPERATION_MODDN           0x00000040L
+#define SLAPI_OPERATION_MODRDN          SLAPI_OPERATION_MODDN
+#define SLAPI_OPERATION_COMPARE         0x00000080L
+#define SLAPI_OPERATION_ABANDON         0x00000100L
+#define SLAPI_OPERATION_EXTENDED        0x00000200L
+#define SLAPI_OPERATION_ANY             0xFFFFFFFFL
+#define SLAPI_OPERATION_NONE            0x00000000L
+int slapi_get_supported_controls(char ***ctrloidsp, unsigned long **ctrlopsp);
+void slapi_register_supported_saslmechanism(char *mechanism);
+char **slapi_get_supported_saslmechanisms();
+char **slapi_get_supported_extended_ops(void);
+
+
+/* send ldap result back */
+void slapi_send_ldap_result( Slapi_PBlock *pb, int err, char *matched, char *text, 
+                                          int nentries, struct berval **urls );
+int slapi_send_ldap_search_entry( Slapi_PBlock *pb, Slapi_Entry *e, LDAPControl **ectrls,
+                                  char **attrs, int attrsonly );
+
+/* filter routines */
+Slapi_Filter *slapi_str2filter( char *str );
+void slapi_filter_free( Slapi_Filter *f, int recurse );
+int slapi_filter_get_choice( Slapi_Filter *f);
+int slapi_filter_get_ava( Slapi_Filter *f, char **type, struct berval **bval );
+Slapi_Filter *slapi_filter_list_first( Slapi_Filter *f );
+Slapi_Filter *slapi_filter_list_next( Slapi_Filter *f, Slapi_Filter *fprev );
+
+/* internal add/delete/search/modify routines */
+Slapi_PBlock *slapi_search_internal( char *base, int scope, char *filter, 
+       LDAPControl **controls, char **attrs, int attrsonly );
+Slapi_PBlock *slapi_modify_internal( char *dn, LDAPMod **mods,
+        LDAPControl **controls, int log_change);
+Slapi_PBlock *slapi_add_entry_internal( Slapi_Entry * e, LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_add_internal( char * dn, LDAPMod **attrs, LDAPControl **controls, int log_changes );
+Slapi_PBlock *slapi_add_entry_internal( Slapi_Entry * e, LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_delete_internal( char * dn,  LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_modrdn_internal( char * olddn, char * newrdn, char *newParent, int deloldrdn, LDAPControl **controls, int log_change);
+void slapi_free_search_results_internal(Slapi_PBlock *pb);
+
+/* connection related routines */
+int slapi_is_connection_ssl(Slapi_PBlock *pPB, int *isSSL);
+int slapi_get_client_port(Slapi_PBlock *pPB, int *fromPort);
+
+/* parameters currently supported */
+
+
+/* plugin types supported */
+
+#define SLAPI_PLUGIN_DATABASE           1
+#define SLAPI_PLUGIN_EXTENDEDOP         2
+#define SLAPI_PLUGIN_PREOPERATION       3
+#define SLAPI_PLUGIN_POSTOPERATION      4
+#define SLAPI_PLUGIN_AUDIT              7   
+
+/* misc params */
+
+#define SLAPI_BACKEND                          130
+#define SLAPI_CONNECTION                       131
+#define SLAPI_OPERATION                                132
+#define SLAPI_REQUESTOR_ISROOT                 133
+#define SLAPI_BE_MONITORDN                     134
+#define SLAPI_BE_TYPE                          135
+#define SLAPI_BE_READONLY                      136
+#define SLAPI_BE_LASTMOD                               137
+#define SLAPI_CONN_ID                          139
+
+/* operation params */
+#define SLAPI_OPINITIATED_TIME                 140
+#define SLAPI_REQUESTOR_DN                     141
+#define SLAPI_REQUESTOR_ISUPDATEDN             142
+
+/* connection  structure params*/
+#define SLAPI_CONN_DN                          143
+#define SLAPI_CONN_AUTHTYPE                            144
+
+/*  Authentication types */
+#define SLAPD_AUTH_NONE   "none"
+#define SLAPD_AUTH_SIMPLE "simple"
+#define SLAPD_AUTH_SSL    "SSL"
+#define SLAPD_AUTH_SASL   "SASL " 
+
+/* plugin configuration parmams */
+#define SLAPI_PLUGIN                           3
+#define SLAPI_PLUGIN_PRIVATE                   4
+#define SLAPI_PLUGIN_TYPE                      5
+#define SLAPI_PLUGIN_ARGV                      6
+#define SLAPI_PLUGIN_ARGC                      7
+#define SLAPI_PLUGIN_VERSION                   8
+#define SLAPI_PLUGIN_OPRETURN                  9
+#define SLAPI_PLUGIN_OBJECT                    10
+#define SLAPI_PLUGIN_DESTROY_FN                        11
+#define SLAPI_PLUGIN_DESCRIPTION               12
+
+/* internal opreations params */
+#define SLAPI_PLUGIN_INTOP_RESULT              15
+#define SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES      16
+#define SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS    17
+
+/* function pointer params for backends */
+#define SLAPI_PLUGIN_DB_BIND_FN                        200
+#define SLAPI_PLUGIN_DB_UNBIND_FN              201
+#define SLAPI_PLUGIN_DB_SEARCH_FN              202
+#define SLAPI_PLUGIN_DB_COMPARE_FN             203
+#define SLAPI_PLUGIN_DB_MODIFY_FN              204
+#define SLAPI_PLUGIN_DB_MODRDN_FN              205
+#define SLAPI_PLUGIN_DB_ADD_FN                 206
+#define SLAPI_PLUGIN_DB_DELETE_FN              207
+#define SLAPI_PLUGIN_DB_ABANDON_FN             208
+#define SLAPI_PLUGIN_DB_CONFIG_FN              209
+#define SLAPI_PLUGIN_CLOSE_FN                  210
+#define SLAPI_PLUGIN_DB_FLUSH_FN               211
+#define SLAPI_PLUGIN_START_FN                  212
+#define SLAPI_PLUGIN_DB_SEQ_FN                 213
+#define SLAPI_PLUGIN_DB_ENTRY_FN               214
+#define SLAPI_PLUGIN_DB_REFERRAL_FN            215
+#define SLAPI_PLUGIN_DB_RESULT_FN              216
+#define SLAPI_PLUGIN_DB_LDIF2DB_FN             217
+#define SLAPI_PLUGIN_DB_DB2LDIF_FN             218
+#define SLAPI_PLUGIN_DB_BEGIN_FN               219
+#define SLAPI_PLUGIN_DB_COMMIT_FN              220
+#define SLAPI_PLUGIN_DB_ABORT_FN               221
+#define SLAPI_PLUGIN_DB_ARCHIVE2DB_FN          222
+#define SLAPI_PLUGIN_DB_DB2ARCHIVE_FN          223
+#define SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN   224
+#define SLAPI_PLUGIN_DB_FREE_RESULT_SET_FN     225
+#define        SLAPI_PLUGIN_DB_SIZE_FN                 226
+#define        SLAPI_PLUGIN_DB_TEST_FN                 227
+
+
+/*  functions pointers for LDAP V3 extended ops */
+#define SLAPI_PLUGIN_EXT_OP_FN                 300
+#define SLAPI_PLUGIN_EXT_OP_OIDLIST            301
+
+/* functions for preoperation functions */
+#define SLAPI_PLUGIN_PRE_BIND_FN               401
+#define SLAPI_PLUGIN_PRE_UNBIND_FN             402
+#define SLAPI_PLUGIN_PRE_SEARCH_FN             403
+#define SLAPI_PLUGIN_PRE_COMPARE_FN            404
+#define SLAPI_PLUGIN_PRE_MODIFY_FN             405
+#define SLAPI_PLUGIN_PRE_MODRDN_FN             406
+#define SLAPI_PLUGIN_PRE_ADD_FN                        407
+#define SLAPI_PLUGIN_PRE_DELETE_FN             408
+#define SLAPI_PLUGIN_PRE_ABANDON_FN            409
+#define SLAPI_PLUGIN_PRE_ENTRY_FN              410
+#define SLAPI_PLUGIN_PRE_REFERRAL_FN           411
+#define SLAPI_PLUGIN_PRE_RESULT_FN             412
+
+/*  functions for postoperation functions*/
+#define SLAPI_PLUGIN_POST_BIND_FN              501
+#define SLAPI_PLUGIN_POST_UNBIND_FN            502
+#define SLAPI_PLUGIN_POST_SEARCH_FN            503
+#define SLAPI_PLUGIN_POST_COMPARE_FN           504
+#define SLAPI_PLUGIN_POST_MODIFY_FN            505
+#define SLAPI_PLUGIN_POST_MODRDN_FN            506
+#define SLAPI_PLUGIN_POST_ADD_FN               507
+#define SLAPI_PLUGIN_POST_DELETE_FN            508
+#define SLAPI_PLUGIN_POST_ABANDON_FN           509
+#define SLAPI_PLUGIN_POST_ENTRY_FN             510
+#define SLAPI_PLUGIN_POST_REFERRAL_FN          511
+#define SLAPI_PLUGIN_POST_RESULT_FN            512
+
+/* audit plugin defines */
+#define SLAPI_PLUGIN_AUDIT_DATA                1100
+#define SLAPI_PLUGIN_AUDIT_FN                  1101
+
+/* managedsait control */
+#define SLAPI_MANAGEDSAIT                      1000
+
+/* config stuff */
+#define SLAPI_CONFIG_FILENAME                  40
+#define SLAPI_CONFIG_LINENO                    41
+#define SLAPI_CONFIG_ARGC                      42
+#define SLAPI_CONFIG_ARGV                      43
+
+/*  operational params */
+#define SLAPI_TARGET_DN                                50
+#define SLAPI_REQCONTROLS                      51
+
+/* server LDAPv3 controls  */
+#define SLAPI_RESCONTROLS                      55
+#define SLAPI_ADD_RESCONTROL                   56      
+
+/* add params */
+#define SLAPI_ADD_TARGET                       SLAPI_TARGET_DN
+#define SLAPI_ADD_ENTRY                                60
+
+/* bind params */
+#define SLAPI_BIND_TARGET                      SLAPI_TARGET_DN
+#define SLAPI_BIND_METHOD                      70
+#define SLAPI_BIND_CREDENTIALS                 71      
+#define SLAPI_BIND_SASLMECHANISM               72      
+#define SLAPI_BIND_RET_SASLCREDS               73      
+
+/* compare params */
+#define SLAPI_COMPARE_TARGET                   SLAPI_TARGET_DN
+#define SLAPI_COMPARE_TYPE                     80
+#define SLAPI_COMPARE_VALUE                    81
+
+/* delete params */
+#define SLAPI_DELETE_TARGET                    SLAPI_TARGET_DN
+
+/* modify params */
+#define SLAPI_MODIFY_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_MODIFY_MODS                      90
+
+/* modrdn params */
+#define SLAPI_MODRDN_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_MODRDN_NEWRDN                    100
+#define SLAPI_MODRDN_DELOLDRDN                 101
+#define SLAPI_MODRDN_NEWSUPERIOR               102     /* v3 only */
+
+/* search params */
+#define SLAPI_SEARCH_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_SEARCH_SCOPE                     110
+#define SLAPI_SEARCH_DEREF                     111
+#define SLAPI_SEARCH_SIZELIMIT                 112
+#define SLAPI_SEARCH_TIMELIMIT                 113
+#define SLAPI_SEARCH_FILTER                    114
+#define SLAPI_SEARCH_STRFILTER                 115
+#define SLAPI_SEARCH_ATTRS                     116
+#define SLAPI_SEARCH_ATTRSONLY                 117
+
+/* abandon params */
+#define SLAPI_ABANDON_MSGID                    120
+
+/* extended operation params */
+#define SLAPI_EXT_OP_REQ_OID                   160
+#define SLAPI_EXT_OP_REQ_VALUE         161     
+
+/* extended operation return codes */
+#define SLAPI_EXT_OP_RET_OID                   162     
+#define SLAPI_EXT_OP_RET_VALUE         163     
+
+#define SLAPI_PLUGIN_EXTENDED_SENT_RESULT      -1
+
+/* Search result params */
+#define SLAPI_SEARCH_RESULT_SET                        193
+#define        SLAPI_SEARCH_RESULT_ENTRY               194
+#define        SLAPI_NENTRIES                          195
+#define SLAPI_SEARCH_REFERRALS                 196
+
+
+/* filter types */
+#ifndef LDAP_FILTER_AND
+#define LDAP_FILTER_AND         0xa0L
+#endif
+#ifndef LDAP_FILTER_OR
+#define LDAP_FILTER_OR          0xa1L
+#endif
+#ifndef LDAP_FILTER_NOT
+#define LDAP_FILTER_NOT         0xa2L
+#endif
+#ifndef LDAP_FILTER_EQUALITY
+#define LDAP_FILTER_EQUALITY    0xa3L
+#endif
+#ifndef LDAP_FILTER_SUBSTRINGS
+#define LDAP_FILTER_SUBSTRINGS  0xa4L
+#endif
+#ifndef LDAP_FILTER_GE
+#define LDAP_FILTER_GE          0xa5L
+#endif
+#ifndef LDAP_FILTER_LE
+#define LDAP_FILTER_LE          0xa6L
+#endif
+#ifndef LDAP_FILTER_PRESENT
+#define LDAP_FILTER_PRESENT     0x87L
+#endif
+#ifndef LDAP_FILTER_APPROX
+#define LDAP_FILTER_APPROX      0xa8L
+#endif
+#ifndef LDAP_FILTER_EXT_MATCH
+#define LDAP_FILTER_EXT_MATCH   0xa9L
+#endif
+
+int slapi_log_error( int severity, char *subsystem, char *fmt, ... );
+#define SLAPI_LOG_FATAL                 0
+#define SLAPI_LOG_TRACE                 1
+#define SLAPI_LOG_PACKETS               2
+#define SLAPI_LOG_ARGS                  3
+#define SLAPI_LOG_CONNS                 4
+#define SLAPI_LOG_BER                   5
+#define SLAPI_LOG_FILTER                6
+#define SLAPI_LOG_CONFIG                7
+#define SLAPI_LOG_ACL                   8
+#define SLAPI_LOG_SHELL                 9
+#define SLAPI_LOG_PARSE                 10
+#define SLAPI_LOG_HOUSE                 11
+#define SLAPI_LOG_REPL                  12
+#define SLAPI_LOG_CACHE                 13
+#define SLAPI_LOG_PLUGIN                14
+#define SLAPI_LOG_TIMING                15
+
+#define SLAPI_PLUGIN_DESCRIPTION       12
+typedef struct slapi_plugindesc {
+        char    *spd_id;
+        char    *spd_vendor;
+        char    *spd_version;
+        char    *spd_description;
+} Slapi_PluginDesc;
+
+#define SLAPI_PLUGIN_VERSION_01         "01"
+#define SLAPI_PLUGIN_VERSION_02         "02"
+#define SLAPI_PLUGIN_VERSION_03         "03"
+#define SLAPI_PLUGIN_CURRENT_VERSION    SLAPI_PLUGIN_VERSION_03
+
+#endif
index 717b91dc7050bdc08269440676b9e01c0c938937..4bc2c7314241f495a271a496f06d05e9f0260748 100644 (file)
@@ -35,11 +35,11 @@ OBJS        = main.o daemon.o connection.o search.o filter.o add.o cr.o \
                limits.o backglue.o operational.o matchedValues.o \
                $(@PLAT@_OBJS)
 
-LDAP_INCDIR= ../../include
+LDAP_INCDIR= ../../include -Islapi
 LDAP_LIBDIR= ../../libraries
 
 SLAP_DIR=
-SLAPD_STATIC_DEPENDS=@SLAPD_NO_STATIC@ libbackends.a
+SLAPD_STATIC_DEPENDS=@SLAPD_SLAPI_DEPEND@ @SLAPD_NO_STATIC@ libbackends.a
 SLAPD_STATIC_BACKENDS=@SLAPD_STATIC_BACKENDS@
 SLAPD_DYNAMIC_BACKENDS=@SLAPD_DYNAMIC_BACKENDS@
 
@@ -48,7 +48,7 @@ XLDFLAGS = $(MODULES_LDFLAGS)
 
 XLIBS = $(SLAPD_STATIC_DEPENDS) $(SLAPD_L)
 XXLIBS = $(LDBM_LIBS) $(SLAPD_LIBS) $(SECURITY_LIBS) $(LDIF_LIBS) $(LUTIL_LIBS)
-XXXLIBS = $(LTHREAD_LIBS) $(MODULES_LIBS)
+XXXLIBS = $(LTHREAD_LIBS) $(MODULES_LIBS) $(SLAPI_LIBS)
 
 BUILD_OPT = "--enable-slapd"
 BUILD_SRV = @BUILD_SLAPD@
@@ -224,8 +224,17 @@ slapd.exp: libslapd.a
        dlltool --dllname slapd.exe --input-def slapd.def \
                --base-file slapd.base --output-exp $@
 
+.slapi: FORCE
+       (cd slapi; $(MAKE) $(MFLAGS) all)
+
+libslapi.a: .slapi
+       $(AR) ruv slapi/libtmpslapd.a $(OBJS)
+       cp slapi/.libs/libslapi.a .
+
 slapd: $(SLAPD_DEPENDS)
-       $(LTLINK) -o $@ $(SLAPD_OBJECTS) $(LIBS) $(WRAP_LIBS)
+       $(LTLINK) -o $@ $(SLAPD_OBJECTS) $(LIBS) \
+               libslapi.a slapi/libtmpslapd.a \
+               $(WRAP_LIBS)
 
 sslapd: version.o
        $(LTLINK) -static -o $@ $(OBJS) version.o $(LIBS) $(WRAP_LIBS)
@@ -280,7 +289,7 @@ version.c: $(OBJS) $(SLAPD_LIBDEPEND)
        $(MKVERSION) -s -n Versionstr slapd > $@
 
 depend-local-srv: FORCE
-       @for i in back-* shell-backends tools; do \
+       @for i in back-* shell-backends slapi tools; do \
                if test -d $$i -a -f $$i/Makefile ; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) depend"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) depend ); \
@@ -293,7 +302,7 @@ clean-local:
        rm -f *.exp *.def *.base *.a *.objs symdummy.c
 
 clean-local-srv: FORCE
-       @for i in back-* shell-backends tools; do \
+       @for i in back-* shell-backends slapi tools; do \
                if test -d $$i -a -f $$i/Makefile ; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) clean"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) clean ); \
@@ -303,7 +312,7 @@ clean-local-srv: FORCE
        rm -f *.tmp all-cffiles
 
 veryclean-local-srv: FORCE
-       @for i in back-* shell-backends tools; do \
+       @for i in back-* shell-backends slapi tools; do \
                if test -d $$i -a -f $$i/Makefile ; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) clean"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) veryclean ); \
@@ -317,7 +326,7 @@ install-slapd: FORCE
        -$(MKDIR) $(DESTDIR)$(localstatedir)
        $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 \
                slapd$(EXEEXT) $(DESTDIR)$(libexecdir)
-       @for i in back-* shell-backends tools; do \
+       @for i in back-* shell-backends slapi tools; do \
            if test -d $$i -a -f $$i/Makefile ; then \
                echo; echo "  cd $$i; $(MAKE) $(MFLAGS) install"; \
                ( cd $$i; $(MAKE) $(MFLAGS) install ); \
index 85e6f7ca50012614f79f411d4612bcf235fa5baa..35a686f09359daa5afd3cdbb1b0e7a894fb33c97 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 #include <ac/string.h>
 
 #include "ldap_pvt.h"
 #include "slap.h"
-
-static int slap_mods2entry(
-       Modifications *mods,
-       Entry **e,
-       int repl_user,
-       const char **text,
-       char *textbuf, size_t textlen );
+#include "slapi.h"
 
 int
 do_add( Connection *conn, Operation *op )
@@ -49,6 +44,8 @@ do_add( Connection *conn, Operation *op )
        int                     rc = LDAP_SUCCESS;
        int     manageDSAit;
 
+       Slapi_PBlock *pb = op->o_pb;
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_add: conn %d enter\n", conn->c_connid,0,0 );
 #else
@@ -228,6 +225,31 @@ do_add( Connection *conn, Operation *op )
                goto done;
        }
 
+#if defined( LDAP_SLAPI )
+       slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
+       slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
+       slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
+       slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e );
+       slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
+       slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_ADD_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no preOp (add) plugins
+                * or a plugin failed. Just log it
+                * 
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_add: add preOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " add preOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        /*
         * do the add if 1 && (2 || 3)
         * 1) there is an add function implemented in this backend;
@@ -314,6 +336,23 @@ do_add( Connection *conn, Operation *op )
                              NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_ADD_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no postOp (Add) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_add: Add postOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " Add postOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 done:
        if( modlist != NULL ) {
                slap_mods_free( modlist );
@@ -325,7 +364,8 @@ done:
        return rc;
 }
 
-static int slap_mods2entry(
+int
+slap_mods2entry(
        Modifications *mods,
        Entry **e,
        int repl_user,
index 124ec7c42274eea6f3849fb79cd1eb35bde903c9..fb1272b4b7d05aac0b92709cc11ec0157a575071 100644 (file)
@@ -7,6 +7,7 @@
 
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -16,6 +17,7 @@
 #include <sys/stat.h>
 
 #include "slap.h"
+#include "slapi.h"
 #include "lutil.h"
 #include "lber_pvt.h"
 
@@ -686,12 +688,56 @@ backend_unbind(
        Operation    *op
 )
 {
-       int     i;
+       int             i;
+       int     rc;
+       Slapi_PBlock *pb = op->o_pb;
+
+#if defined( LDAP_SLAPI )
+       slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
+       slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
+#endif /* defined( LDAP_SLAPI ) */
 
        for ( i = 0; i < nbackends; i++ ) {
+#if defined( LDAP_SLAPI )
+               slapi_pblock_set( pb, SLAPI_BACKEND, (void *)&backends[i] );
+               rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN,
+                               (Slapi_PBlock *)pb );
+               if ( rc != 0 && rc != LDAP_OTHER ) {
+                       /*
+                        * either there is no preOp (unbind) plugins
+                        * or a plugin failed. Just log it.
+                        *
+                        * FIXME: is this correct?
+                        */
+#ifdef NEW_LOGGING
+                       LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_bind: Unbind preOps failed\n"));
+#else
+                       Debug (LDAP_DEBUG_TRACE, " Unbind preOps failed.\n", 0, 0, 0);
+#endif
+               }
+#endif /* defined( LDAP_SLAPI ) */
+
                if ( backends[i].be_unbind ) {
                        (*backends[i].be_unbind)( &backends[i], conn, op );
                }
+
+#if defined( LDAP_SLAPI )
+               rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN,
+                               (Slapi_PBlock *)pb );
+               if ( rc != 0 && rc != LDAP_OTHER ) {
+                       /*
+                        * either there is no postOp (unbind) plugins
+                        * or a plugin failed. Just log it.
+                        *
+                        * FIXME: is this correct?
+                        */
+#ifdef NEW_LOGGING
+                       LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_unbind: Unbind postOps failed\n"));
+#else
+                       Debug (LDAP_DEBUG_TRACE, " Unbind postOps failed.\n", 0, 0, 0);
+#endif
+               }
+#endif /* defined( LDAP_SLAPI ) */
        }
 
        return 0;
index 1b3220c2c39080bd13a8a0a9b2d226d568eaed07..f5062ba5cf0d7694f01a901e000ebc0e630b5bab 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -26,6 +27,7 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#include "slapi.h"
 
 int
 do_bind(
@@ -47,6 +49,8 @@ do_bind(
        struct berval cred = { 0, NULL };
        Backend *be = NULL;
 
+       Slapi_PBlock *pb = op->o_pb;
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", conn->c_connid, 0, 0 );
 #else
@@ -526,6 +530,30 @@ do_bind(
                goto cleanup;
        }
 
+#if defined( LDAP_SLAPI )
+       slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
+       slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
+       slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
+       slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no preOp (bind) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_bind: Bind preOps  failed\n"));
+#else
+               Debug(LDAP_DEBUG_TRACE, " Bind preOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        if ( be->be_bind ) {
                int ret;
 
@@ -592,6 +620,23 @@ do_bind(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_BIND_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no pretOp (bind) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_bind: Bind postOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " Bind postOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        conn->c_sasl_bindop = NULL;
 
index 81e3e9f54e206783b54226bbe957f3b67fe4b4fa..ab0546ffc9c2be4c89bb785ed3528001c5547c1f 100644 (file)
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 #include <ac/socket.h>
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#include "slapi.h"
 
 static int compare_entry(
        Connection *conn,
@@ -48,6 +50,8 @@ do_compare(
        const char *text = NULL;
        int manageDSAit;
 
+       Slapi_PBlock *pb = op->o_pb;
+
        ava.aa_desc = NULL;
 
 #ifdef NEW_LOGGING
@@ -267,6 +271,32 @@ do_compare(
        /* deref suffix alias if appropriate */
        suffix_alias( be, &ndn );
 
+#if defined( LDAP_SLAPI )
+       slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
+       slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
+       slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
+       slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
+       slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
+       slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, (void *)desc.bv_val );
+       slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, (void *)&value );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_COMPARE_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no preOp (compare) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_compare: compare preOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " compare preOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        if ( be->be_compare ) {
                (*be->be_compare)( be, conn, op, &pdn, &ndn, &ava );
        } else {
@@ -275,6 +305,23 @@ do_compare(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_COMPARE_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no postOp (compare) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_compare: compare postOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " compare postOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        free( pdn.bv_val );
        free( ndn.bv_val );
index 45616ae406ea836326da9f3be0b7982cea3968af..d87bf6f4327278ebc83633597d2cc0fbf71ce055 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -18,6 +19,7 @@
 #include "lutil.h"
 #include "ldap_pvt.h"
 #include "slap.h"
+#include "slapi.h"
 
 #define ARGS_STEP      512
 
@@ -2311,6 +2313,49 @@ read_config( const char *fname, int depth )
 #endif
 #endif /* !SLAPD_RLOOKUPS */
 
+               /* Netscape plugins */
+               } else if ( strcasecmp( cargv[0], "plugin" ) == 0 ) {
+#if defined( LDAP_SLAPI )
+
+                       /*
+                        * a "plugin" line must be inside a database
+                        * definition, since we implement pre-,post- 
+                        * and extended operation plugins
+                        */
+                       if ( be == NULL ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, INFO, 
+                                       "%s: line %d: plugin line must appear "
+                                       "inside a database definition.\n",
+                                       fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: plugin "
+                                   "line must appear inside a database "
+                                   "definition\n", fname, lineno, 0 );
+#endif
+                               return( 1 );
+                       }
+
+                       if ( netscape_plugin( be, fname, lineno, cargc, cargv ) 
+                                       != LDAP_SUCCESS ) {
+                               return( 1 );
+                       }
+
+#else /* !defined( LDAP_SLAPI ) */
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, INFO, 
+                               "%s: line %d: SLAPI not supported.\n",
+                               fname, lineno, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI "
+                           "not supported.\n", fname, lineno, 0 );
+#endif
+                       return( 1 );
+                       
+#endif /* !defined( LDAP_SLAPI ) */
+
+
+
                /* pass anything else to the current backend info/db config routine */
                } else {
                        if ( bi != NULL ) {
index aeed4237b8da68fc7fdef23307db4d29c1b00e7c..8dbf0e63d7522d1ef93108993acec5a7e46e0b00 100644 (file)
@@ -395,22 +395,28 @@ long connection_init(
        if( c == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( CONNECTION, INFO, 
-                          "connection_init: skt %d      connection table full (%d/%d)\n",
-                          s, i, dtblsize );
+                          "connection_init: skt %d connection table full "
+                          "(%d/%d)\n", s, i, dtblsize );
 #else
                Debug( LDAP_DEBUG_ANY,
-                               "connection_init(%d): connection table full (%d/%d)\n",
-                               s, i, dtblsize);
+                               "connection_init(%d): connection table full "
+                               "(%d/%d)\n", s, i, dtblsize);
 #endif
            ldap_pvt_thread_mutex_unlock( &connections_mutex );
            return -1;
        }
-    }
+       }
 #endif
 
-    assert( c != NULL );
+       assert( c != NULL );
 
        if( c->c_struct_state == SLAP_C_UNINITIALIZED ) {
+               c->c_send_ldap_result = slap_send_ldap_result;
+               c->c_send_search_entry = slap_send_search_entry;
+               c->c_send_search_result = slap_send_search_result;
+               c->c_send_search_reference = slap_send_search_reference;
+               c->c_send_ldap_extended = slap_send_ldap_extended;
+
                c->c_authmech.bv_val = NULL;
                c->c_authmech.bv_len = 0;
                c->c_dn.bv_val = NULL;
index cf8fdd246999db0d70d4b489813597e7c5a3dfd7..465884c412efec812a27f9b1e7a386050581e084 100644 (file)
@@ -106,6 +106,12 @@ get_supported_ctrl(int index)
        return supportedControls[index].sc_oid;
 }
 
+slap_mask_t
+get_supported_ctrl_mask(int index)
+{
+       return supportedControls[index].sc_mask;
+}
+
 static struct slap_control *
 find_ctrl( const char *oid )
 {
index 97f073e1b9c4e0aceec34ba0283252949f192a22..849a494bc775f6f16ed3a54775a0bbc980f31a78 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -24,6 +25,7 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#include "slapi.h"
 
 int
 do_delete(
@@ -39,6 +41,8 @@ do_delete(
        int rc;
        int manageDSAit;
 
+       Slapi_PBlock *pb = op->o_pb;
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, 
                "do_delete: conn %d\n", conn->c_connid, 0, 0 );
@@ -153,6 +157,30 @@ do_delete(
        /* deref suffix alias if appropriate */
        suffix_alias( be, &ndn );
 
+#if defined( LDAP_SLAPI )
+       slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
+       slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
+       slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
+       slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
+       slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_DELETE_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no preOp (delete) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: delete preOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " delete preOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        /*
         * do the delete if 1 && (2 || 3)
         * 1) there is a delete function implemented in this backend;
@@ -193,6 +221,23 @@ do_delete(
                        NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_DELETE_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no postOp (delete) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: delete postOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " delete postOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        free( pdn.bv_val );
        free( ndn.bv_val );
index dfff66d4d79b9cdb63eb8ad717aab55dd62b209d..84d8698d5a1d1e0c015e964280c9007967b4a028 100644 (file)
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 #include <ac/socket.h>
 #include <ac/string.h>
 
 #include "slap.h"
+#include "slapi.h"
 #include "lber_pvt.h"
 
+#define UNSUPPORTED_EXTENDEDOP "unsupported extended operation"
+
 static struct extop_list {
        struct extop_list *next;
        struct berval oid;
@@ -102,6 +106,12 @@ do_extended(
        struct berval *rspdata;
        LDAPControl **rspctrls;
 
+       Slapi_PBlock    *pb = op->o_pb;
+       SLAPI_FUNC      funcAddr = NULL;
+       int             extop_rc;
+       int             msg_sent=FALSE;
+       char            *result_msg="";
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_extended: conn %d\n", conn->c_connid, 0, 0 );
 #else
@@ -136,7 +146,10 @@ do_extended(
                goto done;
        }
 
-       if( !(ext = find_extop(supp_ext_list, &reqoid)) ) {
+       /* Netscape extended operation */
+       getPluginFunc( &reqoid, &funcAddr );
+
+       if( !(ext = find_extop(supp_ext_list, &reqoid)) && !(funcAddr) ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, ERR, 
                        "do_extended: conn %d  unsupported operation \"%s\"\n",
@@ -202,29 +215,72 @@ do_extended(
        text = NULL;
        refs = NULL;
 
-       rc = (ext->ext_main)( conn, op,
-               reqoid.bv_val, reqdata.bv_val ? &reqdata : NULL,
-               &rspoid, &rspdata, &rspctrls, &text, &refs );
+       if (ext != NULL) { /* OpenLDAP extended operation */
+               rc = (ext->ext_main)( conn, op,
+                         reqoid.bv_val, reqdata.bv_val ? &reqdata : NULL,
+                         &rspoid, &rspdata, &rspctrls, &text, &refs );
+
+               if( rc != SLAPD_ABANDON ) {
+                       if ( rc == LDAP_REFERRAL && refs == NULL ) {
+                               refs = referral_rewrite( default_referral,
+                                       NULL, NULL, LDAP_SCOPE_DEFAULT );
+                       }
 
-       if( rc != SLAPD_ABANDON ) {
-               if ( rc == LDAP_REFERRAL && refs == NULL ) {
-                       refs = referral_rewrite( default_referral,
-                               NULL, NULL, LDAP_SCOPE_DEFAULT );
+                       send_ldap_extended( conn, op, rc, NULL, text, refs,
+                               rspoid, rspdata, rspctrls );
+
+                       ber_bvarray_free( refs );
                }
 
-               send_ldap_extended( conn, op, rc, NULL, text, refs,
-                       rspoid, rspdata, rspctrls );
+               if ( rspoid != NULL ) {
+                       free( rspoid );
+               }
 
-               ber_bvarray_free( refs );
+               if ( rspdata != NULL ) {
+                       ber_bvfree( rspdata );
+               }
+#if !defined( LDAP_SLAPI )
        }
+#else /* defined( LDAP_SLAPI ) */
+               goto done;  /* end of OpenLDAP extended operation */
+
+       } else { /* start of Netscape extended operation */
+               if ( ( rc = slapi_pblock_set( pb, SLAPI_EXT_OP_REQ_OID,(void *)reqoid.bv_val) ) == 0 &&
+                               ( rc = slapi_pblock_set( pb, SLAPI_EXT_OP_REQ_VALUE,(void *)&reqdata) ) == 0 &&
+                               ( rc = slapi_pblock_set( pb, SLAPI_CONNECTION,(void *)conn) ) == 0  &&
+                               ( rc = slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op) ) == 0) {
+                       extop_rc = (*funcAddr)( pb );
+                       if ( extop_rc == SLAPI_PLUGIN_EXTENDED_SENT_RESULT ) {
+                               msg_sent = TRUE;
+                       } else if ( extop_rc == SLAPI_PLUGIN_EXTENDED_NOT_HANDLED ) {
+                               rc = LDAP_PROTOCOL_ERROR;
+                               result_msg = UNSUPPORTED_EXTENDEDOP;
+                       } else {
+                               if ( ( rc = slapi_pblock_get(pb, SLAPI_EXT_OP_RET_OID,&rspoid) ) == 0 &&
+                                                 ( rc = slapi_pblock_get(pb, SLAPI_EXT_OP_RET_VALUE,&rspdata) ) == 0 ) {
+                                       send_ldap_extended( conn, op, extop_rc, NULL, text, refs,
+                                                        rspoid, rspdata, rspctrls );
+                                       msg_sent = TRUE;
+                               } else {
+                                       rc = LDAP_OPERATIONS_ERROR;
+                               }
+                       }
+               } else {
+                       rc = LDAP_OPERATIONS_ERROR;
+               }
 
-       if ( rspoid != NULL ) {
-               free( rspoid );
-       }
+               if ( rc != LDAP_SUCCESS && msg_sent == FALSE ) {
+                       send_ldap_result( conn, op, rc, NULL, result_msg, NULL, NULL );
+               }
+               if ( rspoid != NULL ) {
+                       free( rspoid );
+               }
+               if ( rspdata != NULL ) {
+                       ber_bvfree( rspdata );
+               }
 
-       if ( rspdata != NULL ) {
-               ber_bvfree( rspdata );
-       }
+       } /* end of Netscape extended operation */
+#endif /* defined( LDAP_SLAPI ) */
 
 done:
        return rc;
index 1dc199c838d8910bc5d9cdb46ff1c6899725bd8d..40a036ce8928174ac48e5ae7c1836c922dd9d8b4 100644 (file)
@@ -4,6 +4,7 @@
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -16,7 +17,9 @@
 
 #include "ldap_pvt.h"
 
+
 #include "slap.h"
+#include "slapi.h"
 #include "lutil.h"
 #include "ldif.h"
 
@@ -405,6 +408,20 @@ int main( int argc, char **argv )
        (void) ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &rc );
 #endif
 
+#ifdef LDAP_SLAPI
+       if ( slapi_init() != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, CRIT, "main: slapi initialization error\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ANY,
+                   "slapi initialization error\n",
+                   0, 0, 0 );
+#endif
+
+               goto destroy;
+       }
+#endif /* LDAP_SLAPI */
+
        if ( read_config( configfile, 0 ) != 0 ) {
                rc = 1;
                SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
index 0f0c716375f167e6de35b1ba47d6d786746912de..e9c7bd72b7332365930fb0b91ca65de910e4267c 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -27,6 +28,7 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#include "slapi.h"
 
 int
 do_modify(
@@ -49,6 +51,8 @@ do_modify(
        const char      *text;
        int manageDSAit;
 
+       Slapi_PBlock *pb = op->o_pb;
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_modify: enter\n", 0, 0, 0 );
 #else
@@ -303,6 +307,30 @@ do_modify(
        /* deref suffix alias if appropriate */
        suffix_alias( be, &ndn );
 
+#if defined( LDAP_SLAPI )
+       slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
+       slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
+       slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
+       slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODIFY_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no preOp (modify) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_modify: modify preOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " modify preOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        /*
         * do the modify if 1 && (2 || 3)
         * 1) there is a modify function implemented in this backend;
@@ -380,6 +408,23 @@ do_modify(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_MODIFY_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no postOp (modify) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_modify: modify postOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " modify postOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        free( pdn.bv_val );
        free( ndn.bv_val );
index 372f0a33e8a15b19a581a1486cd52731edbd1ba4..a4dc8010386b1fb1685f59aaf9cd84ed0150462f 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -37,6 +38,7 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#include "slapi.h"
 
 int
 do_modrdn(
@@ -64,6 +66,8 @@ do_modrdn(
        const char *text;
        int manageDSAit;
 
+       Slapi_PBlock *pb = op->o_pb;
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 );
 #else
@@ -324,6 +328,34 @@ do_modrdn(
        /* deref suffix alias if appropriate */
        suffix_alias( be, &ndn );
 
+#if defined( LDAP_SLAPI )
+       slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
+       slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
+       slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
+       slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR,
+                       (void *)newSuperior.bv_val );
+       slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)deloldrdn );
+       slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODRDN_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no preOp (modrdn) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_modrdn: modrdn preOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " modrdn preOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        /*
         * do the add if 1 && (2 || 3)
         * 1) there is an add function implemented in this backend;
@@ -370,6 +402,23 @@ do_modrdn(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_MODRDN_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no postOp (modrdn) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_modrdn: modrdn postOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " modrdn postOps failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        free( pdn.bv_val );
        free( ndn.bv_val );
index 59fc1b9cd7e7c494388081a8406c3fc05fc79b9c..4745076706df80f14c9b254fda7f9097a6cf0ace 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -13,6 +14,7 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "slapi.h"
 
 
 void
@@ -42,6 +44,12 @@ slap_op_free( Operation *op )
        }
 #endif /* LDAP_CLIENT_UPDATE */
 
+#if defined( LDAP_SLAPI )
+       if ( op->o_pb != NULL ) {
+               slapi_pblock_destroy( (Slapi_PBlock *)op->o_pb );
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        free( (char *) op );
 }
 
@@ -64,5 +72,9 @@ slap_op_alloc(
        op->o_time = slap_get_time();
        op->o_opid = id;
 
+#if defined( LDAP_SLAPI )
+       op->o_pb = slapi_pblock_new();
+#endif /* defined( LDAP_SLAPI ) */
+
        return( op );
 }
index 0085f5f8d6a00b2e3784a3837220292497c13986..f00570c60d03a7538e2492162cf946c41afda8d8 100644 (file)
@@ -84,7 +84,13 @@ LDAP_SLAPD_F (AttributeDescription *) ad_find_lang LDAP_P((
 
 LDAP_SLAPD_F (AttributeName *) str2anlist LDAP_P(( AttributeName *an,
        char *str, const char *brkstr ));
-LDAP_SLAPD_F (int) an_find LDAP_P(( AttributeName *a, struct berval *s ));     
+LDAP_SLAPD_F (int) an_find LDAP_P(( AttributeName *a, struct berval *s ));
+
+/*
+ * add.c
+ */
+LDAP_SLAPD_F (int) slap_mods2entry LDAP_P(( Modifications *mods, Entry **e,
+       int repl_user, const char **text, char *textbuf, size_t textlen ));
 
 /*
  * at.c
@@ -271,6 +277,8 @@ LDAP_SLAPD_F (int) get_ctrls LDAP_P((
 
 LDAP_SLAPD_F (char *) get_supported_ctrl LDAP_P((int index));
 
+LDAP_SLAPD_F (slap_mask_t) get_supported_ctrl_mask LDAP_P((int index));
+
 /*
  * config.c
  */
@@ -773,7 +781,7 @@ LDAP_SLAPD_F (void) replog LDAP_P(( Backend *be, Operation *op,
 /*
  * result.c
  */
-LDAP_SLAPD_F (void) send_ldap_result LDAP_P((
+LDAP_SLAPD_F (void) slap_send_ldap_result LDAP_P((
        Connection *conn, Operation *op,
        ber_int_t err, const char *matched, const char *text,
        BerVarray refs,
@@ -791,7 +799,7 @@ LDAP_SLAPD_F (void) send_ldap_disconnect LDAP_P((
        Connection *conn, Operation *op,
        ber_int_t err, const char *text ));
 
-LDAP_SLAPD_F (void) send_ldap_extended LDAP_P((
+LDAP_SLAPD_F (void) slap_send_ldap_extended LDAP_P((
        Connection *conn, Operation *op,
        ber_int_t err, const char *matched,
        const char *text, BerVarray refs,
@@ -803,20 +811,20 @@ LDAP_SLAPD_F (void) send_ldap_partial LDAP_P((
        const char *rspoid, struct berval *rspdata,
        LDAPControl **ctrls ));
 
-LDAP_SLAPD_F (void) send_search_result LDAP_P((
+LDAP_SLAPD_F (void) slap_send_search_result LDAP_P((
        Connection *conn, Operation *op,
        ber_int_t err, const char *matched, const char *text,
        BerVarray refs,
        LDAPControl **ctrls,
        int nentries ));
 
-LDAP_SLAPD_F (int) send_search_reference LDAP_P((
+LDAP_SLAPD_F (int) slap_send_search_reference LDAP_P((
        Backend *be, Connection *conn, Operation *op,
        Entry *e, BerVarray refs,
        LDAPControl **ctrls,
        BerVarray *v2refs ));
 
-LDAP_SLAPD_F (int) send_search_entry LDAP_P((
+LDAP_SLAPD_F (int) slap_send_search_entry LDAP_P((
        Backend *be, Connection *conn, Operation *op,
        Entry *e, AttributeName *attrs, int attrsonly,
        LDAPControl **ctrls ));
index 7f87db28d4ef90c5011eba59a2242863a0f4f8f2..d26573bb3bf2536132588609e4c4c1601650e5c2 100644 (file)
@@ -429,7 +429,7 @@ send_ldap_disconnect(
 }
 
 void
-send_ldap_result(
+slap_send_ldap_result(
     Connection *conn,
     Operation  *op,
     ber_int_t  err,
@@ -545,7 +545,7 @@ send_ldap_sasl(
 }
 
 void
-send_ldap_extended(
+slap_send_ldap_extended(
     Connection *conn,
     Operation  *op,
     ber_int_t  err,
@@ -583,7 +583,7 @@ send_ldap_extended(
 
 
 void
-send_search_result(
+slap_send_search_result(
     Connection *conn,
     Operation  *op,
     ber_int_t  err,
@@ -661,7 +661,7 @@ send_search_result(
 }
 
 int
-send_search_entry(
+slap_send_search_entry(
     Backend    *be,
     Connection *conn,
     Operation  *op,
@@ -1214,7 +1214,7 @@ error_return:;
 }
 
 int
-send_search_reference(
+slap_send_search_reference(
     Backend    *be,
     Connection *conn,
     Operation  *op,
index 312052605ba2cc4458c2073b0b1be220b12929c1..86777acfaed502efc10f7f5c0f8de6033c158880 100644 (file)
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 #include <ac/string.h>
 
 #include "slap.h"
+#include "slapi.h"
 #include <ldif.h>
 #include "lber_pvt.h"
+#include "slapi/slapi_utils.h"
+
+struct berval *ns_get_supported_extop (int);
 
 static struct berval supportedFeatures[] = {
        BER_BVC(LDAP_FEATURE_ALL_OPERATIONAL_ATTRS), /* all Operational Attributes ("+") */
@@ -134,6 +139,14 @@ root_dse_info(
                        return LDAP_OTHER;
        }
 
+#if defined( LDAP_SLAPI )
+       /* netscape supportedExtension */
+       for ( i = 0; (bv = ns_get_supported_extop(i)) != NULL; i++ ) {
+               vals[0] = *bv;
+               attr_merge( e, ad_supportedExtension, vals );
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        /* supportedFeatures */
        if( attr_merge( e, ad_supportedFeatures, supportedFeatures ) )
                return LDAP_OTHER;
index 4699633403c4bc08a846577bab2b3e535aaefb2a..3260f8ab3489078958f6914dbc64fac831e08c65 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "portable.h"
+#include "slapi_common.h"
 
 #include <stdio.h>
 
@@ -24,6 +25,7 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#include "slapi.h"
 
 int
 do_search(
@@ -44,6 +46,8 @@ do_search(
        const char      *text;
        int                     manageDSAit;
 
+       Slapi_PBlock *pb = op->o_pb;
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_search: conn %d\n", conn->c_connid, 0, 0 );
 #else
@@ -310,6 +314,37 @@ do_search(
        /* deref the base if needed */
        suffix_alias( be, &nbase );
 
+#if defined( LDAP_SLAPI )
+       slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
+       slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
+       slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
+       slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)base.bv_val );
+       slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, (void *)scope );
+       slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, (void *)deref );
+       slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, (void *)sizelimit );
+       slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, (void *)timelimit );
+       slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, (void *)filter );
+       slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, (void *)fstr.bv_val );
+       slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, (void *)attrsonly );
+       slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_SEARCH_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no preOp (search) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_search: search preOps failed\n"));
+#else
+               Debug(LDAP_DEBUG_TRACE, "search preOps failed.\n", 0, 0, 0);
+#endif
+    }
+#endif /* defined( LDAP_SLAPI ) */
+
        /* actually do the search and send the result(s) */
        if ( be->be_search ) {
                (*be->be_search)( be, conn, op, &pbase, &nbase,
@@ -321,6 +356,23 @@ do_search(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_SEARCH_FN, pb );
+       if ( rc != 0 && rc != LDAP_OTHER ) {
+               /*
+                * either there is no postOp (search) plugins
+                * or a plugin failed. Just log it
+                *
+                * FIXME: is this correct?
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_search: search postOps failed\n"));
+#else
+               Debug (LDAP_DEBUG_TRACE, " search postOps failed.\n", 0, 0, 0);
+#endif
+    }
+#endif /* defined( LDAP_SLAPI ) */
+
 return_results:;
 #ifdef LDAP_CLIENT_UPDATE
        if ( !( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
index 1e611159c10a3b830e35b02fb73a4136945d8694..a763f6c4ee5214e9a62b3c35a8fcd9a16adeffec 100644 (file)
@@ -1327,6 +1327,8 @@ struct slap_backend_db {
        BerVarray       be_update_refs; /* where to refer modifying clients to */
        char    *be_realm;
        void    *be_private;    /* anything the backend database needs     */
+
+       void    *be_pb;         /* Netscape plugin */
 };
 
 struct slap_conn;
@@ -1689,6 +1691,9 @@ typedef struct slap_op {
 
        LDAP_STAILQ_ENTRY(slap_op)      o_next; /* next operation in list         */
        ValuesReturnFilter *vrFilter; /* Structure represents ValuesReturnFilter */
+
+       void    *o_pb;                  /* Netscape plugin */
+
 } Operation;
 
 #define get_manageDSAit(op)                            ((int)(op)->o_managedsait)
@@ -1697,6 +1702,80 @@ typedef struct slap_op {
 #define get_pagedresults(op)                   ((int)(op)->o_pagedresults)
 
 
+
+typedef void (*SEND_LDAP_RESULT)(
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               ber_int_t err,
+                               const char *matched,
+                               const char *text,
+                               BerVarray ref,
+                               LDAPControl **ctrls
+                               );
+
+#define send_ldap_result( conn, op, err, matched, text, ref, ctrls  ) \
+(*conn->c_send_ldap_result)( conn, op, err, matched, text, ref, ctrls )
+
+
+typedef int (*SEND_SEARCH_ENTRY)(
+                               struct slap_backend_db *be,
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               struct slap_entry *e,
+                               AttributeName *attrs,
+                               int attrsonly,
+                               LDAPControl **ctrls
+                               );
+
+#define send_search_entry( be, conn, op, e, attrs, attrsonly, ctrls) \
+(*conn->c_send_search_entry)( be, conn, op, e, attrs, attrsonly, ctrls)
+
+
+typedef void (*SEND_SEARCH_RESULT)(
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               ber_int_t err,
+                               const char *matched,
+                               const char *text,
+                               BerVarray   refs,
+                               LDAPControl **ctrls,
+                               int nentries
+                               );
+
+#define send_search_result( conn, op, err, matched, text, refs, ctrls, nentries ) \
+(*conn->c_send_search_result)( conn, op, err, matched, text, refs, ctrls, nentries )
+
+
+typedef int (*SEND_SEARCH_REFERENCE)(
+                               struct slap_backend_db *be,
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               struct slap_entry *e,
+                               BerVarray refs,
+                               LDAPControl **ctrls,
+                               BerVarray *v2refs
+                               );
+
+#define send_search_reference( be, conn, op, e,  refs, ctrls, v2refs ) \
+(*conn->c_send_search_reference)( be, conn, op, e,  refs, ctrls, v2refs )
+
+
+typedef void (*SEND_LDAP_EXTENDED)(
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               ber_int_t   err,
+                               const char  *matched,
+                               const char  *text,
+                               BerVarray   refs,
+                               const char      *rspoid,
+                               struct berval *rspdata,
+                               LDAPControl **ctrls
+                               );
+
+#define send_ldap_extended( conn, op, err, matched, text, refs, rspoid, rspdata, ctrls) \
+(*conn->c_send_ldap_extended)( conn, op, err, matched, text, refs, rspoid, rspdata, ctrls )
+
+
 /*
  * Caches the result of a backend_group check for ACL evaluation
  */
@@ -1777,6 +1856,20 @@ typedef struct slap_conn {
        long    c_n_get;                /* num of get calls */
        long    c_n_read;               /* num of read calls */
        long    c_n_write;              /* num of write calls */
+
+       void    *c_pb;                  /* Netscape plugin */
+
+    /*
+        * These are the "callbacks" that are available for back-ends to
+        * supply data back to connected clients that are connected
+        * through the "front-end".
+       */
+       SEND_LDAP_RESULT c_send_ldap_result;
+       SEND_SEARCH_ENTRY c_send_search_entry;
+       SEND_SEARCH_RESULT c_send_search_result;
+       SEND_SEARCH_REFERENCE c_send_search_reference;
+       SEND_LDAP_EXTENDED c_send_ldap_extended;
+       
 } Connection;
 
 #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG)
diff --git a/servers/slapd/slapi/Makefile.in b/servers/slapd/slapi/Makefile.in
new file mode 100644 (file)
index 0000000..f66c2cf
--- /dev/null
@@ -0,0 +1,45 @@
+## Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+
+## (C) Copyright IBM Corp. 1997,2002
+## Redistribution and use in source and binary forms are permitted
+## provided that this notice is preserved and that due credit is 
+## given to IBM Corporation. This software is provided ``as is'' 
+## without express or implied warranty.
+
+
+LIBRARY = libslapi.la
+XLIBRARY = libtmpslapd.a
+
+#all-common: $(LIBRARY) $(PROGRAMS)
+#      @touch plugin.c slapi_pblock.c slapi_utils.c slapi_ops.c
+
+NT_SRCS = nt_err.c
+NT_OBJS = nt_err.lo
+
+LIB_DEFS = -DSLAPI_LIBRARY
+
+SRCS=  plugin.c slapi_pblock.c slapi_utils.c printmsg.c slapi_ops.c  $(@PLAT@_SRCS)
+OBJS=  plugin.lo slapi_pblock.lo slapi_utils.lo printmsg.lo slapi_ops.lo $(@PLAT@_SRCS)
+
+XSRCS= version.c
+
+LDAP_INCDIR= ../../../include -I.. -I.       
+LDAP_LIBDIR= ../../../libraries       
+
+XLIBS = $(LIBRARY)
+XXLIBS = 
+NT_LINK_LIBS = $(AC_LIBS)
+
+XDEFS = $(MODULES_CPPFLAGS)
+
+UNIX_LINK_LIBS = ./libtmpslapd.a ../libbackends.a ../../../libraries/libavl/libavl.a ../../../libraries/liblber/.libs/liblber.a ../../../libraries/libldbm/libldbm.a ../../../libraries/libldif/libldif.a ../../../libraries/liblutil/liblutil.a ../../../libraries/liblunicode/liblunicode.a ../../../libraries/libldap_r/.libs/libldap_r.a ./libtmpslapd.a
+
+BUILD_MOD = @BUILD_SLAPI@
+
+install-local: FORCE
+       if test "$(BUILD_MOD)" = "yes"; then \
+               $(MKDIR) $(DESTDIR)$(libdir); \
+               $(LTINSTALL) $(INSTALLFLAGS) -m 644 $(LIBRARY) $(DESTDIR)$(libdir); \
+       fi
+
diff --git a/servers/slapd/slapi/README b/servers/slapd/slapi/README
new file mode 100644 (file)
index 0000000..5edb84e
--- /dev/null
@@ -0,0 +1,55 @@
+Files included in this patch:
+
+I. Modified OpenLDAP files
+---------------------------------
+
+1.  top level configure.in                             
+2.  slap.h                                             
+3.  back-ldbm/Makefile.in                              
+4.  back-ldbm/config.c                                 
+5.  back-bdb/Makefile.in                                       
+6.  back-bdb/config.c                                  
+7.  slapd/tools/Makefile.in
+8.  ldap/include/Makefile.in                           
+9.  slapd/Makefile.in                                  
+10. operation.c                                                
+11. root_dse.c                                         
+12. extended.c                                         
+13. bind.c                                             
+14. backend.c                                          
+15. add.c                                              
+16. delete.c                                           
+17. compare.c                                          
+18. moddify.c
+19. modrdn.c                                           
+20. search.c                                           
+21. result.c
+22. mimic.c
+
+
+II. New files 
+-------------------------------
+
+1. slapd/slapi/Makefile.in                             
+2. slapd/slapi/ldapload.h                              
+3. slapd/slapi/ldapload.c                              
+4. slapd/slapi/plugin.h                                        
+5. slapd/slapi/plugin.c                                        
+6. slapd/slapi/printmsg.c                                
+7. slapd/slapi/slapi_pblock.h                          
+8. slapd/slapi/slapi_pblock.c                            
+9. slapd/slapi/slapi_ops.h                             
+10.slapd/slapi/slapi_utils.h                           
+11.slapd/slapi/slapi_utils.c                           
+12.slapd/slapi/ibm_pblock_params.h                       
+13.slapd/slapi/slapi_common.h                          
+14.slapd/slapi/slapi.h                                 
+15.slapd/slapi/slapi_cl.h                                
+16.ldap/include/slapi-plugin.h                           
+
+III. General procedure
+
+The directory ldap/servers/slapd/slapi should be created and
+files 1-15, section II above should be placed in that directory. 
+The file slapi-plugin.h (16 above) should also be copied into 
+the ldap/include directory.
diff --git a/servers/slapd/slapi/ibm_pblock_params.h b/servers/slapd/slapi/ibm_pblock_params.h
new file mode 100644 (file)
index 0000000..13be5fd
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#ifndef _ibm_pblock_params_H
+#define _ibm_pblock_params_H
+
+#define FIRST_PARAM -1
+#define LAST_IBM_PARAM -48
+#define NETSCAPE_RESERVED(p) (p >= 280) && (p <= 299)
+#define IBM_RESERVED(p) (p >= LAST_IBM_PARAM) && (p <= FIRST_PARAM)
+
+#define SLAPI_IBM_THREAD_CONTROL                                       (FIRST_PARAM - 1)
+#define SLAPI_IBM_PBLOCK                                                       (FIRST_PARAM - 2)
+#define SLAPI_IBM_CONNECTION_PTR                                       (FIRST_PARAM - 3)
+#define SLAPI_IBM_BACKENDS                                                     (FIRST_PARAM - 4)
+#define SLAPI_PRE_BIND_ALL                                                     (FIRST_PARAM - 5)
+#define SLAPI_POST_BIND_ALL                                                    (FIRST_PARAM - 6)
+#define SLAPI_IBM_ADMIN_DN                                                     (FIRST_PARAM - 7)
+#define SLAPI_CONFIG_STATE                                                     (FIRST_PARAM - 8)
+#define SLAPI_PLUGIN_DB_REGISTER_SERVICE_FN                    (FIRST_PARAM - 9)   
+#define SLAPI_PLUGIN_DB_INSERT_REPL_ENTRIES_FN         (FIRST_PARAM - 10)
+#define SLAPI_PLUGIN_DB_GET_REPL_ENTRIES_FN                    (FIRST_PARAM - 11)
+#define SLAPI_PLUGIN_DB_REPLICA_DONE_FN                                (FIRST_PARAM - 12)
+#define SLAPI_PLUGIN_DB_INIT_REPL_LIST_FN                      (FIRST_PARAM - 13)
+#define SLAPI_PLUGIN_DB_THREAD_INITIALIZE_FN           (FIRST_PARAM - 14)
+#define SLAPI_PLUGIN_DB_THREAD_TERMINATE_FN                    (FIRST_PARAM - 15)
+#define SLAPI_PLUGIN_DB_SCHEMA_MODIFY_ATTRTYPE_FN      (FIRST_PARAM - 16)
+#define SLAPI_PLUGIN_DB_SCHEMA_MODIFY_OBJCLASS_FN      (FIRST_PARAM - 17)
+#define SLAPI_PLUGIN_DB_INIT_FN                                                (FIRST_PARAM - 18)
+#define SLAPI_IBM_EXTENDED_OPS                                         (FIRST_PARAM - 19)
+#define SLAPI_IBM_CONTROLS                                                     (FIRST_PARAM - 20)
+#define SLAPI_IBM_SASLMECHANISMS                                       (FIRST_PARAM - 21)
+#define SLAPI_IBM_BROADCAST_BE                                         (FIRST_PARAM - 22)
+#define SLAPI_IBM_NOTIFY_BIND_FN                                       (FIRST_PARAM - 23)
+#define SLAPI_IBM_SECRET                                                       (FIRST_PARAM - 24)
+#define SLAPI_IBM_CL_START_FN                                          (FIRST_PARAM - 25)
+#define SLAPI_IBM_REPLICATE                                                    (FIRST_PARAM - 26)
+#define SLAPI_IBM_CL_CLASS                                                     (FIRST_PARAM - 27)
+#define SLAPI_IBM_CL_SUFFIX                                                    (FIRST_PARAM - 28)
+#define SLAPI_IBM_CL_MAX_ENTRIES                                       (FIRST_PARAM - 29)
+#define SLAPI_IBM_CONNINFO                                                     (FIRST_PARAM - 30)
+#define SLAPI_IBM_CL_FIRST_ENTRY                                       (FIRST_PARAM - 31)
+#define SLAPI_IBM_CL_LAST_ENTRY                                                (FIRST_PARAM - 32)
+#define SLAPI_IBM_CONN_DN_ALT                                          (FIRST_PARAM - 33)
+#define SLAPI_IBM_GSSAPI_CONTEXT                                       (FIRST_PARAM - 34)
+#define SLAPI_IBM_ADD_ENTRY                                                    (FIRST_PARAM - 35)
+#define SLAPI_IBM_DELETE_ENTRY                                         (FIRST_PARAM - 36)
+#define SLAPI_IBM_MODIFY_ENTRY                                         (FIRST_PARAM - 37)
+#define SLAPI_IBM_MODIFY_MODS                                          (FIRST_PARAM - 38)
+#define SLAPI_IBM_MODRDN_ENTRY                                         (FIRST_PARAM - 39)
+#define SLAPI_IBM_MODRDN_NEWDN                                         (FIRST_PARAM - 40)
+#define SLAPI_IBM_EVENT_ENABLED                                                (FIRST_PARAM - 41)
+#define SLAPI_IBM_EVENT_MAXREG                                         (FIRST_PARAM - 42)
+#define SLAPI_IBM_EVENT_REGPERCONN                                     (FIRST_PARAM - 43)
+#define SLAPI_IBM_EVENT_CURREG                                         (FIRST_PARAM - 44)
+#define SLAPI_IBM_EVENT_SENTREG                                                (FIRST_PARAM - 45)
+#define SLAPI_IBM_CONN_DN_ORIG                                         (FIRST_PARAM - 46)
+#define SLAPI_PLUGIN_DB_DELETE_PROGRESS_FN                     (FIRST_PARAM - 47) 
+#endif
diff --git a/servers/slapd/slapi/plugin.c b/servers/slapd/slapi/plugin.c
new file mode 100644 (file)
index 0000000..858cbeb
--- /dev/null
@@ -0,0 +1,679 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#include "portable.h"
+#include "slapi_common.h"
+#include <ldap_pvt_thread.h>
+#include <slap.h>
+#include <slapi.h>
+
+/*
+ * Note: if ltdl.h is not available, slapi should not be compiled
+ */
+#include <ltdl.h>
+
+static int loadPlugin( Slapi_PBlock *, const char *, const char *, int, 
+       SLAPI_FUNC *, lt_dlhandle * );
+
+/* pointer to link list of extended objects */
+static ExtendedOp *pGExtendedOps = NULL;
+
+/*********************************************************************
+ * Function Name:      newPlugin
+ *
+ * Description:        This routine creates a new Slapi_PBlock structure,
+ *                     loads in the plugin module and executes the init
+ *                     function provided by the module.
+ *
+ * Input:              type - type of the plugin, such as SASL, database, etc.
+ *                     path - the loadpath to load the module in
+ *                     initfunc - name of the plugin function to execute first
+ *                     argc - number of arguements
+ *                     argv[] - an array of char pointers point to
+ *                              the arguments passed in via
+ *                              the configuration file.
+ *
+ * Output:             
+ *
+ * Return Values:      a pointer to a newly created Slapi_PBlock structrue or
+ *                     NULL - function failed 
+ *
+ * Messages:           None
+ *********************************************************************/
+
+Slapi_PBlock *
+newPlugin(
+       int type, 
+       const char *path, 
+       const char *initfunc, 
+       int argc, 
+       char *argv[] ) 
+{
+       Slapi_PBlock    *pPlugin = NULL; 
+       lt_dlhandle     hdLoadHandle;
+       int             rc;
+
+       pPlugin = slapi_pblock_new();
+       if ( pPlugin == NULL ) {
+               rc = LDAP_NO_MEMORY;
+               goto done;
+       }
+
+       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)type );
+       if ( rc != LDAP_SUCCESS ) {
+               goto done;
+       }
+
+       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, (void *)argc );
+       if ( rc != LDAP_SUCCESS ) {
+               goto done;
+       }
+
+       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGV, (void *)argv );
+       if ( rc != LDAP_SUCCESS ) { 
+               goto done;
+       }
+
+       rc = loadPlugin( pPlugin, path, initfunc, TRUE, NULL, &hdLoadHandle );
+
+done:
+       if ( rc != LDAP_SUCCESS && pPlugin != NULL ) {
+               slapi_pblock_destroy( pPlugin );
+               pPlugin = NULL;
+       }
+
+       return pPlugin;
+} 
+
+/*********************************************************************
+ * Function Name:      insertPlugin
+ *
+ * Description:        insert the slapi_pblock structure to the end of the plugin
+ *                     list 
+ *
+ * Input:              a pointer to a plugin slapi_pblock structure to be added to 
+ *                     the list
+ *
+ * Output:             none
+ *
+ * Return Values:      LDAP_SUCCESS - successfully inserted.
+ *                     LDAP_LOCAL_ERROR.
+ *
+ * Messages:           None
+ *********************************************************************/
+int 
+insertPlugin(
+       Backend *be, 
+       Slapi_PBlock *pPB )
+{ 
+       Slapi_PBlock *pTmpPB;
+       Slapi_PBlock *pSavePB;
+       int    rc = LDAP_SUCCESS;
+
+       pTmpPB = (Slapi_PBlock *)(be->be_pb);
+       
+       if ( pTmpPB == NULL ) {
+               be->be_pb = (void *)pPB;
+       } else {
+               while ( pTmpPB != NULL && rc == LDAP_SUCCESS ) {
+                       pSavePB = pTmpPB;
+                       rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK,
+                                       &pTmpPB );
+                       if ( rc != LDAP_SUCCESS ) {
+                               rc = LDAP_OTHER;
+                       }
+               }
+
+               if ( rc == LDAP_SUCCESS ) { 
+                       rc = slapi_pblock_set( pSavePB, SLAPI_IBM_PBLOCK,
+                                       (void *)pPB ); 
+                       if ( rc != LDAP_SUCCESS ) {
+                               rc = LDAP_OTHER;
+                       }
+               }
+       }
+     
+       return rc;
+}
+       
+/*********************************************************************
+ * Function Name:      getAllPluginFuncs
+ *
+ * Description:        get the desired type of function pointers defined 
+ *                     in all the plugins 
+ *
+ * Input:              the type of the functions to get, such as pre-operation,etc.
+ *
+ * Output:             none
+ *
+ * Return Values:      this routine returns a pointer to an array of function
+ *                     pointers
+ *
+ * Messages:           None
+ *********************************************************************/
+int 
+getAllPluginFuncs(
+       Backend *be,            
+       int functype, 
+       SLAPI_FUNC **ppFuncPtrs )
+{
+       Slapi_PBlock    *pCurrentPB; 
+       SLAPI_FUNC      FuncPtr;
+       SLAPI_FUNC      *pTmpFuncPtr;
+       int             numPB = 0;
+       int             rc = LDAP_SUCCESS;
+
+       assert( be );
+       assert( ppFuncPtrs );
+
+       pCurrentPB = (Slapi_PBlock *)(be->be_pb);
+     
+       if ( pCurrentPB == NULL ) { 
+               /*
+                * LDAP_OTHER is returned if no plugins are installed
+                */
+               rc = LDAP_OTHER;
+               goto done;
+       }
+
+       while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
+               rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
+               if ( rc == LDAP_SUCCESS ) {
+                       if ( FuncPtr != NULL )  {
+                               numPB++;
+                       }
+                       rc = slapi_pblock_get( pCurrentPB,
+                                       SLAPI_IBM_PBLOCK, &pCurrentPB );
+               }
+       }
+
+       if ( rc != LDAP_SUCCESS ) {
+               goto done;
+       }
+
+       if ( numPB == 0 ) {
+               *ppFuncPtrs = NULL;
+               rc = LDAP_SUCCESS;
+               goto done;
+       }
+
+       *ppFuncPtrs = pTmpFuncPtr = 
+               (SLAPI_FUNC *)ch_malloc( ( numPB + 1 ) * sizeof(SLAPI_FUNC) ); 
+       if ( ppFuncPtrs == NULL ) {
+               rc = LDAP_NO_MEMORY;
+               goto done;
+       }
+
+       pCurrentPB = (Slapi_PBlock *)(be->be_pb);
+       while ( pCurrentPB != NULL && rc == LDAP_SUCCESS )  {
+               rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
+               if ( rc == LDAP_SUCCESS ) {
+                       if ( FuncPtr != NULL )  {
+                               *pTmpFuncPtr = FuncPtr;
+                               pTmpFuncPtr++;
+                       } 
+                       rc = slapi_pblock_get( pCurrentPB,
+                                       SLAPI_IBM_PBLOCK, &pCurrentPB );
+               }
+       }
+       *pTmpFuncPtr = NULL ;
+
+done:
+       if ( rc != LDAP_SUCCESS && *ppFuncPtrs != NULL ) {
+               ch_free( *ppFuncPtrs );
+               *ppFuncPtrs = NULL;
+       }
+
+       return rc;
+}
+              
+/*********************************************************************
+ * Function Name:      createExtendedOp
+ *
+ * Description: Creates an extended operation structure and
+ *              initializes the fields
+ *
+ * Return value: A newly allocated structure or NULL
+ ********************************************************************/
+ExtendedOp *
+createExtendedOp()
+{
+       ExtendedOp *ret;
+
+       ret = (ExtendedOp *)ch_malloc(sizeof(ExtendedOp));
+       if ( ret != NULL ) {
+               ret->ext_oid.bv_val = NULL;
+               ret->ext_oid.bv_len = 0;
+               ret->ext_func = NULL;
+               ret->ext_be = NULL;
+               ret->ext_next = NULL;
+       }
+
+       return ret;
+}
+
+
+/*********************************************************************
+ * Function Name:      removeExtendedOp
+ *
+ * Description:        This routine removes the ExtendedOp structures 
+ *                                        asscoiated with a particular extended operation 
+ *                                        plugin.
+ *
+ * Input:              pBE - pointer to a backend structure
+ *                     opList - pointer to a linked list of extended
+ *                              operation structures
+ *                     pPB - pointer to a slapi parameter block
+ *
+ * Output:
+ *
+ * Return Value:       none
+ *
+ * Messages:           None
+ *********************************************************************/
+void
+removeExtendedOp(
+       Backend *pBE, 
+       ExtendedOp **opList, 
+       Slapi_PBlock *pPB )
+{
+       ExtendedOp      *pTmpExtOp, *backExtOp;
+       char            **pTmpOIDs;
+       int             i;
+
+#if 0
+       assert( pBE != NULL); /* unused */
+#endif /* 0 */
+       assert( opList != NULL );
+       assert( pPB != NULL );
+
+       if ( *opList == NULL ) {
+               return;
+       }
+
+       slapi_pblock_get( pPB, SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
+       if ( pTmpOIDs == NULL ) {
+               return;
+       }
+
+       for ( i = 0; pTmpOIDs[i] != NULL; i++ ) {
+               backExtOp = NULL;
+               pTmpExtOp = *opList;
+               for ( ; pTmpExtOp != NULL; pTmpExtOp = pTmpExtOp->ext_next) {
+                       int     rc;
+                       rc = strcasecmp( pTmpExtOp->ext_oid.bv_val,
+                                       pTmpOIDs[ i ] );
+                       if ( rc == 0 ) {
+                               if ( backExtOp == NULL ) {
+                                       *opList = pTmpExtOp->ext_next;
+                               } else {
+                                       backExtOp->ext_next
+                                               = pTmpExtOp->ext_next;
+                               }
+
+                               ch_free( pTmpExtOp );
+                               break;
+                       }
+                       backExtOp = pTmpExtOp;
+               }
+       }
+}
+
+
+/*********************************************************************
+ * Function Name:      newExtendedOp
+ *
+ * Description:        This routine creates a new ExtendedOp structure, loads
+ *                     in the extended op module and put the extended op function address
+ *                     in the structure. The function will not be executed in
+ *                     this routine.
+ *
+ * Input:              pBE - pointer to a backend structure
+ *                     opList - pointer to a linked list of extended
+ *                              operation structures
+ *                     pPB - pointer to a slapi parameter block
+ *
+ * Output:
+ *
+ * Return Value:       an LDAP return code
+ *
+ * Messages:           None
+ *********************************************************************/
+int 
+newExtendedOp(
+       Backend *pBE,   
+       ExtendedOp **opList, 
+       Slapi_PBlock *pPB )
+{
+       ExtendedOp      *pTmpExtOp = NULL;
+       SLAPI_FUNC      tmpFunc;
+       char            **pTmpOIDs;
+       int             rc = LDAP_OTHER;
+       int             i;
+
+       if ( (*opList) == NULL ) { 
+               *opList = createExtendedOp();
+               if ( (*opList) == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+                       goto error_return;
+               }
+               pTmpExtOp = *opList;
+               
+       } else {                        /* Find the end of the list */
+               for ( pTmpExtOp = *opList; pTmpExtOp->ext_next != NULL;
+                               pTmpExtOp = pTmpExtOp->ext_next )
+                       ; /* EMPTY */
+               pTmpExtOp->ext_next = createExtendedOp();
+               if ( pTmpExtOp->ext_next == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+                       goto error_return;
+               }
+               pTmpExtOp = pTmpExtOp->ext_next;
+       }
+
+       rc = slapi_pblock_get( pPB,SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
+       if ( rc != LDAP_SUCCESS ) {
+               rc = LDAP_OTHER;
+               goto error_return;
+       }
+
+       rc = slapi_pblock_get(pPB,SLAPI_PLUGIN_EXT_OP_FN, &tmpFunc);
+       if ( rc != 0 ) {
+               rc = LDAP_OTHER;
+               goto error_return;
+       }
+
+       if ( (pTmpOIDs == NULL) || (tmpFunc == NULL) ) {
+               rc = LDAP_OTHER;
+               goto error_return;
+       }
+
+       for ( i = 0; pTmpOIDs[i] != NULL; i++ ) {
+               pTmpExtOp->ext_oid.bv_val = pTmpOIDs[i];
+               pTmpExtOp->ext_oid.bv_len = strlen( pTmpOIDs[i] );
+               pTmpExtOp->ext_func = tmpFunc;
+               pTmpExtOp->ext_be = pBE;
+               if ( pTmpOIDs[i + 1] != NULL ) {
+                       pTmpExtOp->ext_next = createExtendedOp();
+                       if ( pTmpExtOp->ext_next == NULL ) {
+                               rc = LDAP_NO_MEMORY;
+                               break;
+                       }
+                       pTmpExtOp = pTmpExtOp->ext_next;
+               }
+       }
+
+error_return:
+       return rc;
+}
+
+/*********************************************************************
+ * Function Name:      getPluginFunc
+ *
+ * Description:        This routine gets the function address for a given function
+ *                     name.
+ *
+ * Input:
+ *                     funcName - name of the extended op function, ie. an OID.
+ *
+ * Output:             pFuncAddr - the function address of the requested function name.
+ *
+ * Return Values:      a pointer to a newly created ExtendOp structrue or
+ *                     NULL - function failed
+ *
+ * Messages:           None
+ *********************************************************************/
+int 
+getPluginFunc(
+       struct berval *reqoid,          
+       SLAPI_FUNC *pFuncAddr ) 
+{
+       ExtendedOp      *pTmpExtOp;
+
+       assert( reqoid != NULL );
+       assert( pFuncAddr != NULL );
+
+       *pFuncAddr = NULL;
+
+       if ( pGExtendedOps == NULL ) {
+               return LDAP_OTHER;
+       }
+
+       pTmpExtOp = pGExtendedOps;
+       while ( pTmpExtOp != NULL ) {
+               int     rc;
+               
+               rc = strcasecmp( reqoid->bv_val, pTmpExtOp->ext_oid.bv_val );
+               if ( rc == 0 ) {
+                       *pFuncAddr = pTmpExtOp->ext_func;
+                       break;
+               }
+               pTmpExtOp = pTmpExtOp->ext_next;
+       }
+
+       return ( *pFuncAddr == NULL ? 1 : 0 );
+}
+
+/***************************************************************************
+ * This function is similar to getPluginFunc above. except it returns one OID
+ * per call. It is called from root_dse_info (root_dse.c).
+ * The function is a modified version of get_supported_extop (file extended.c).
+ ***************************************************************************/
+struct berval *
+ns_get_supported_extop( int index )
+{
+        ExtendedOp     *ext;
+
+        for ( ext = pGExtendedOps ; ext != NULL && --index >= 0;
+                       ext = ext->ext_next) {
+                ; /* empty */
+        }
+
+        if ( ext == NULL ) {
+               return NULL;
+       }
+
+        return &ext->ext_oid ;
+}
+
+/*********************************************************************
+ * Function Name:      loadPlugin
+ *
+ * Description:        This routine loads the specified DLL, gets and executes the init function
+ *                     if requested.
+ *
+ * Input:
+ *                     pPlugin - a pointer to a Slapi_PBlock struct which will be passed to
+ *                               the DLL init function.
+ *                     path - path name of the DLL to be load.
+ *                     initfunc - either the DLL initialization function or an OID of the
+ *                                loaded extended operation.
+ *                     doInit - if it is TRUE, execute the init function, otherwise, save the
+ *                              function address but not execute it.
+ *
+ * Output:             pInitFunc - the function address of the loaded function. This param
+ *                                 should be not be null if doInit is FALSE.
+ *                     pLdHandle - handle returned by lt_dlopen()
+ *
+ * Return Values:      LDAP_SUCCESS, LDAP_LOCAL_ERROR
+ *
+ * Messages:           None
+ *********************************************************************/
+
+static int 
+loadPlugin(
+       Slapi_PBlock    *pPlugin,
+       const char      *path,
+       const char      *initfunc, 
+       int             doInit,
+       SLAPI_FUNC      *pInitFunc,
+       lt_dlhandle     *pLdHandle ) 
+{
+       int             rc = LDAP_SUCCESS;
+       SLAPI_FUNC      fpInitFunc = NULL;
+
+       assert( pLdHandle );
+
+       if ( lt_dlinit() ) {
+               return LDAP_LOCAL_ERROR;
+       }
+
+       /* load in the module */
+       *pLdHandle = lt_dlopen( path );
+       if ( *pLdHandle == NULL ) {
+               return LDAP_LOCAL_ERROR;
+       }
+
+       fpInitFunc = (SLAPI_FUNC)lt_dlsym( *pLdHandle, initfunc );
+       if ( fpInitFunc == NULL ) {
+               lt_dlclose( *pLdHandle );
+               return LDAP_LOCAL_ERROR;
+       }
+
+       if ( doInit == TRUE ) {
+               rc = ( *fpInitFunc )( pPlugin );
+               if ( rc != LDAP_SUCCESS ) {
+                       lt_dlclose( *pLdHandle );
+               }
+
+       } else {
+               *pInitFunc = fpInitFunc;
+       }
+
+       return rc;
+}
+
+
+int 
+doPluginFNs(
+       Backend         *be,    
+       int             funcType, 
+       Slapi_PBlock    *pPB )
+{
+
+       int rc = LDAP_SUCCESS;
+       SLAPI_FUNC *pGetPlugin = NULL, *tmpPlugin = NULL; 
+
+       rc = getAllPluginFuncs(be, funcType, &tmpPlugin );
+       if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
+               return rc;
+       }
+
+       for ( pGetPlugin = tmpPlugin ; *pGetPlugin != NULL; pGetPlugin++ ) {
+               /*
+                * FIXME: operation stops at first non-success
+                *
+                * FIXME: we should provide here a sort of sandbox,
+                * to protect from plugin faults; e.g. trap signals
+                * and longjump here, marking the plugin as unsafe for
+                * later executions ...
+                */
+               rc = (*pGetPlugin)(pPB);
+
+               if ( rc != LDAP_SUCCESS ) {
+                       break;
+               }
+       }
+
+       ch_free( tmpPlugin );
+
+       return rc;
+}
+
+int
+netscape_plugin(
+       Backend         *be,            
+       const char      *fname, 
+       int             lineno, 
+       int             argc, 
+       char            **argv )
+{
+       int             iType = -1;
+       int             numPluginArgc = 0;
+       char            **ppPluginArgv = NULL;
+
+       if ( argc < 4 ) {
+               fprintf( stderr,
+                       "%s: line %d: missing arguments "
+                       "in \"plugin <plugin_type> <lib_path> "
+                       "<init_function> [<arguments>]\" line\n",
+                       fname, lineno );
+               return 1;
+       }
+       
+       if ( strcasecmp( argv[1], "preoperation" ) == 0 ) {
+               iType = SLAPI_PLUGIN_PREOPERATION;
+       } else if ( strcasecmp( argv[1], "postoperation" ) == 0 ) {
+               iType = SLAPI_PLUGIN_POSTOPERATION;
+       } else if ( strcasecmp( argv[1], "extendedop" ) == 0 ) {
+               iType = SLAPI_PLUGIN_EXTENDEDOP;
+       } else {
+               fprintf( stderr, "%s: line %d: invalid plugin type \"%s\".\n",
+                               fname, lineno, argv[1] );
+               return 1;
+       }
+       
+       numPluginArgc = argc - 4;
+       if ( numPluginArgc > 0 ) {
+               ppPluginArgv = &argv[4];
+       } else {
+               ppPluginArgv = NULL;
+       }
+
+       if ( iType == SLAPI_PLUGIN_PREOPERATION ||
+                       iType == SLAPI_PLUGIN_EXTENDEDOP ||
+                       iType == SLAPI_PLUGIN_POSTOPERATION ) {
+               int rc;
+               Slapi_PBlock *pPlugin;
+
+               pPlugin = newPlugin( iType, argv[2], argv[3], 
+                                       numPluginArgc, ppPluginArgv );
+               if (pPlugin == NULL) {
+                       return 1;
+               }
+
+               if (iType == SLAPI_PLUGIN_EXTENDEDOP) {
+                       rc = newExtendedOp(be, &pGExtendedOps, pPlugin);
+                       if ( rc != LDAP_SUCCESS ) {
+                               slapi_pblock_destroy( pPlugin );
+                               return 1;
+                       }
+               }
+
+               rc = insertPlugin( be, pPlugin );
+               if ( rc != LDAP_SUCCESS ) {
+                       if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {
+                               removeExtendedOp( be, &pGExtendedOps, pPlugin );
+                       }
+                       slapi_pblock_destroy( pPlugin );
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+int
+slapi_init(void)
+{
+       if ( ldap_pvt_thread_mutex_init( &slapi_hn_mutex ) ) {
+               return -1;
+       }
+       
+       if ( ldap_pvt_thread_mutex_init( &slapi_time_mutex ) ) {
+               return -1;
+       }
+
+       return 0;
+}
+
diff --git a/servers/slapd/slapi/plugin.h b/servers/slapd/slapi/plugin.h
new file mode 100644 (file)
index 0000000..7aaa20e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#ifndef _PLUGIN_H_ 
+#define _PLUGIN_H_ 
+
+Slapi_PBlock *newPlugin ( int type, const char *path, const char *initfunc,
+               int argc, char *argv[] );
+int insertPlugin(Backend *be, Slapi_PBlock *pPB);
+int doPluginFNs(Backend *be, int funcType, Slapi_PBlock * pPB);
+int getAllPluginFuncs(Backend *be, int functype, SLAPI_FUNC **ppFuncPtrs);
+int newExtendedOp(Backend *pBE, ExtendedOp **opList, Slapi_PBlock *pPB);
+int getPluginFunc(struct berval  *reqoid, SLAPI_FUNC *pFuncAddr );
+int netscape_plugin(Backend *be, const char *fname, int lineno,
+               int argc, char **argv );
+int slapi_init(void);
+
+#endif /* _PLUGIN_H_ */
+
diff --git a/servers/slapd/slapi/printmsg.c b/servers/slapd/slapi/printmsg.c
new file mode 100644 (file)
index 0000000..6ecdadc
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#include <portable.h>
+#include <slapi_common.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <ldap.h>
+#include <ldap_config.h>
+#include <slap.h>
+#include <slapi.h>
+
+#include <ldap_pvt_thread.h>
+
+/* Single threads access to routine */
+static ldap_pvt_thread_mutex_t PrintMessage_mutex; 
+static int PrintMessage_mutex_inited = 0;
+
+static void
+InitMutex () 
+{
+       if (PrintMessage_mutex_inited == 0) {
+               PrintMessage_mutex_inited = 1;
+               ldap_pvt_thread_mutex_init(&PrintMessage_mutex);
+       }
+}
+
+int 
+vLogError(
+       int level,      
+       char *subsystem, 
+       char *fmt, 
+       va_list arglist ) 
+{
+       int rc = 0;
+       char *tmpFmt;
+       FILE * fp = NULL;
+       char *p, *sval;
+       int ival;
+
+       char timeStr[100];
+       struct tm *ltm;
+       time_t currentTime;
+
+       tmpFmt = fmt;
+       fmt = (char*)ch_calloc(strlen(subsystem) + strlen(tmpFmt) + 3, 1);
+       sprintf(fmt, "%s: %s", subsystem, tmpFmt);
+
+       InitMutex() ;
+       ldap_pvt_thread_mutex_lock( &PrintMessage_mutex ) ;
+
+       /* for now, we log all severities */
+       if ( 1 ) {
+               fp = fopen( LDAP_RUNDIR LDAP_DIRSEP "errors", "a" );
+               if (fp == NULL) 
+                       fp = fopen( "errors", "a" );
+                       
+               if ( fp != NULL) {
+                       while ( lockf(fileno(fp), F_LOCK, 0 ) != 0 ) {}
+
+                       time (&currentTime);
+                       ltm = localtime( &currentTime );
+                       strftime( timeStr, sizeof(timeStr), "%x %X ", ltm );
+                       fprintf(fp, timeStr);
+                       for (p = fmt; *p; p++) {
+                               if (*p != '%') {
+                                       fprintf(fp, "%c", *p);
+                                       continue;
+                               }
+                               switch(*++p) {
+                               case 'd':
+                                       ival = va_arg( arglist, int);
+                                       fprintf(fp, "%d", ival);
+                                       break;
+                               case 's':
+                                       for (sval = va_arg(arglist, char *); *sval; sval++)
+                                               fprintf(fp, "%c", *sval);
+                                       break;
+                               default:
+                                       fprintf(fp, "%c", *p);
+                                       break;
+                               
+                               }
+                       }
+       
+                       fflush(fp);
+
+                       lockf( fileno(fp), F_ULOCK, 0 );
+
+                       fclose(fp);
+               } else {
+#if 0 /* unused */
+                       int save_errno = (int)errno;
+#endif /* unused */
+                       rc = ( -1);
+               }
+       } else {
+               rc = ( -1);
+       }
+
+       ldap_pvt_thread_mutex_unlock( &PrintMessage_mutex );
+       ch_free(fmt);
+
+       return (rc);
+}
diff --git a/servers/slapd/slapi/slapi-plugin.h b/servers/slapd/slapi/slapi-plugin.h
new file mode 100644 (file)
index 0000000..824e1db
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is
+ * given to IBM Corporation. This software is provided ``as is''
+ * without express or implied warranty.
+ */
+
+#ifndef _SLAPI_PLUGIN_H
+#define _SLAPI_PLUGIN_H
+
+#include "lber.h"
+#include "ldap.h"
+
+typedef struct slapi_pblock    Slapi_PBlock;
+typedef struct slapi_entry     Slapi_Entry;
+typedef struct slapi_attr      Slapi_Attr;
+typedef struct slapi_filter    Slapi_Filter;
+
+
+/* pblock routines */
+int slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value );
+int slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value );
+Slapi_PBlock *slapi_pblock_new();
+void slapi_pblock_destroy( Slapi_PBlock* );
+
+/* entry/attr/dn routines */
+Slapi_Entry *slapi_str2entry( char *s, int flags );
+char *slapi_entry2str( Slapi_Entry *e, int *len );
+char *slapi_entry_get_dn( Slapi_Entry *e );
+void slapi_entry_set_dn( Slapi_Entry *e, char *dn );
+Slapi_Entry *slapi_entry_dup( Slapi_Entry *e );
+int slapi_entry_attr_delete( Slapi_Entry *e, char *type );
+Slapi_Entry *slapi_entry_alloc();
+void slapi_entry_free( Slapi_Entry *e );
+int slapi_entry_attr_merge( Slapi_Entry *e, char *type, struct berval **vals );
+int slapi_entry_attr_find( Slapi_Entry *e, char *type, Slapi_Attr **attr );
+int slapi_attr_get_values( Slapi_Attr *attr, struct berval ***vals );
+char *slapi_dn_normalize( char *dn );
+char *slapi_dn_normalize_case( char *dn );
+int slapi_dn_issuffix( char *dn, char *suffix );
+char *slapi_dn_ignore_case( char *dn );
+
+/* char routines */
+char *slapi_ch_malloc( unsigned long size );
+void slapi_ch_free( void *ptr );
+char *slapi_ch_calloc( unsigned long nelem, unsigned long size );
+char *slapi_ch_realloc( char *block, unsigned long size );
+char *slapi_ch_strdup( char *s );
+
+
+/* LDAP V3 routines */
+int slapi_control_present( LDAPControl **controls, char *oid,
+       struct berval **val, int *iscritical);
+void slapi_register_supported_control(char *controloid,
+       unsigned long controlops);
+#define SLAPI_OPERATION_BIND            0x00000001L
+#define SLAPI_OPERATION_UNBIND          0x00000002L
+#define SLAPI_OPERATION_SEARCH          0x00000004L
+#define SLAPI_OPERATION_MODIFY          0x00000008L
+#define SLAPI_OPERATION_ADD             0x00000010L
+#define SLAPI_OPERATION_DELETE          0x00000020L
+#define SLAPI_OPERATION_MODDN           0x00000040L
+#define SLAPI_OPERATION_MODRDN          SLAPI_OPERATION_MODDN
+#define SLAPI_OPERATION_COMPARE         0x00000080L
+#define SLAPI_OPERATION_ABANDON         0x00000100L
+#define SLAPI_OPERATION_EXTENDED        0x00000200L
+#define SLAPI_OPERATION_ANY             0xFFFFFFFFL
+#define SLAPI_OPERATION_NONE            0x00000000L
+int slapi_get_supported_controls(char ***ctrloidsp, unsigned long **ctrlopsp);
+void slapi_register_supported_saslmechanism(char *mechanism);
+char **slapi_get_supported_saslmechanisms();
+char **slapi_get_supported_extended_ops(void);
+
+
+/* send ldap result back */
+void slapi_send_ldap_result( Slapi_PBlock *pb, int err, char *matched,
+       char *text, int nentries, struct berval **urls );
+int slapi_send_ldap_search_entry( Slapi_PBlock *pb, Slapi_Entry *e,
+       LDAPControl **ectrls, char **attrs, int attrsonly );
+
+/* filter routines */
+Slapi_Filter *slapi_str2filter( char *str );
+void slapi_filter_free( Slapi_Filter *f, int recurse );
+int slapi_filter_get_choice( Slapi_Filter *f);
+int slapi_filter_get_ava( Slapi_Filter *f, char **type, struct berval **bval );
+Slapi_Filter *slapi_filter_list_first( Slapi_Filter *f );
+Slapi_Filter *slapi_filter_list_next( Slapi_Filter *f, Slapi_Filter *fprev );
+
+/* internal add/delete/search/modify routines */
+Slapi_PBlock *slapi_search_internal( char *base, int scope, char *filter, 
+       LDAPControl **controls, char **attrs, int attrsonly );
+Slapi_PBlock *slapi_modify_internal( char *dn, LDAPMod **mods,
+        LDAPControl **controls, int log_change);
+Slapi_PBlock *slapi_add_entry_internal( Slapi_Entry * e,
+       LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_add_internal( char * dn, LDAPMod **attrs,
+       LDAPControl **controls, int log_changes );
+Slapi_PBlock *slapi_add_entry_internal( Slapi_Entry * e,
+       LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_delete_internal( char * dn,  LDAPControl **controls,
+       int log_change );
+Slapi_PBlock *slapi_modrdn_internal( char * olddn, char * newrdn,
+       char *newParent, int deloldrdn, LDAPControl **controls,
+       int log_change);
+void slapi_free_search_results_internal(Slapi_PBlock *pb);
+
+/* connection related routines */
+int slapi_is_connection_ssl(Slapi_PBlock *pPB, int *isSSL);
+int slapi_get_client_port(Slapi_PBlock *pPB, int *fromPort);
+
+/* parameters currently supported */
+
+
+/* plugin types supported */
+
+#define SLAPI_PLUGIN_DATABASE           1
+#define SLAPI_PLUGIN_EXTENDEDOP         2
+#define SLAPI_PLUGIN_PREOPERATION       3
+#define SLAPI_PLUGIN_POSTOPERATION      4
+#define SLAPI_PLUGIN_AUDIT              7   
+
+/* misc params */
+
+#define SLAPI_BACKEND                          130
+#define SLAPI_CONNECTION                       131
+#define SLAPI_OPERATION                                132
+#define SLAPI_REQUESTOR_ISROOT                 133
+#define SLAPI_BE_MONITORDN                     134
+#define SLAPI_BE_TYPE                          135
+#define SLAPI_BE_READONLY                      136
+#define SLAPI_BE_LASTMOD                               137
+#define SLAPI_CONN_ID                          139
+
+/* operation params */
+#define SLAPI_OPINITIATED_TIME                 140
+#define SLAPI_REQUESTOR_DN                     141
+#define SLAPI_REQUESTOR_ISUPDATEDN             142
+
+/* connection  structure params*/
+#define SLAPI_CONN_DN                          143
+#define SLAPI_CONN_AUTHTYPE                            144
+
+/*  Authentication types */
+#define SLAPD_AUTH_NONE   "none"
+#define SLAPD_AUTH_SIMPLE "simple"
+#define SLAPD_AUTH_SSL    "SSL"
+#define SLAPD_AUTH_SASL   "SASL " 
+
+/* plugin configuration parmams */
+#define SLAPI_PLUGIN                           3
+#define SLAPI_PLUGIN_PRIVATE                   4
+#define SLAPI_PLUGIN_TYPE                      5
+#define SLAPI_PLUGIN_ARGV                      6
+#define SLAPI_PLUGIN_ARGC                      7
+#define SLAPI_PLUGIN_VERSION                   8
+#define SLAPI_PLUGIN_OPRETURN                  9
+#define SLAPI_PLUGIN_OBJECT                    10
+#define SLAPI_PLUGIN_DESTROY_FN                        11
+#define SLAPI_PLUGIN_DESCRIPTION               12
+
+/* internal opreations params */
+#define SLAPI_PLUGIN_INTOP_RESULT              15
+#define SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES      16
+#define SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS    17
+
+/* function pointer params for backends */
+#define SLAPI_PLUGIN_DB_BIND_FN                        200
+#define SLAPI_PLUGIN_DB_UNBIND_FN              201
+#define SLAPI_PLUGIN_DB_SEARCH_FN              202
+#define SLAPI_PLUGIN_DB_COMPARE_FN             203
+#define SLAPI_PLUGIN_DB_MODIFY_FN              204
+#define SLAPI_PLUGIN_DB_MODRDN_FN              205
+#define SLAPI_PLUGIN_DB_ADD_FN                 206
+#define SLAPI_PLUGIN_DB_DELETE_FN              207
+#define SLAPI_PLUGIN_DB_ABANDON_FN             208
+#define SLAPI_PLUGIN_DB_CONFIG_FN              209
+#define SLAPI_PLUGIN_CLOSE_FN                  210
+#define SLAPI_PLUGIN_DB_FLUSH_FN               211
+#define SLAPI_PLUGIN_START_FN                  212
+#define SLAPI_PLUGIN_DB_SEQ_FN                 213
+#define SLAPI_PLUGIN_DB_ENTRY_FN               214
+#define SLAPI_PLUGIN_DB_REFERRAL_FN            215
+#define SLAPI_PLUGIN_DB_RESULT_FN              216
+#define SLAPI_PLUGIN_DB_LDIF2DB_FN             217
+#define SLAPI_PLUGIN_DB_DB2LDIF_FN             218
+#define SLAPI_PLUGIN_DB_BEGIN_FN               219
+#define SLAPI_PLUGIN_DB_COMMIT_FN              220
+#define SLAPI_PLUGIN_DB_ABORT_FN               221
+#define SLAPI_PLUGIN_DB_ARCHIVE2DB_FN          222
+#define SLAPI_PLUGIN_DB_DB2ARCHIVE_FN          223
+#define SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN   224
+#define SLAPI_PLUGIN_DB_FREE_RESULT_SET_FN     225
+#define        SLAPI_PLUGIN_DB_SIZE_FN                 226
+#define        SLAPI_PLUGIN_DB_TEST_FN                 227
+
+
+/*  functions pointers for LDAP V3 extended ops */
+#define SLAPI_PLUGIN_EXT_OP_FN                 300
+#define SLAPI_PLUGIN_EXT_OP_OIDLIST            301
+
+/* functions for preoperation functions */
+#define SLAPI_PLUGIN_PRE_BIND_FN               401
+#define SLAPI_PLUGIN_PRE_UNBIND_FN             402
+#define SLAPI_PLUGIN_PRE_SEARCH_FN             403
+#define SLAPI_PLUGIN_PRE_COMPARE_FN            404
+#define SLAPI_PLUGIN_PRE_MODIFY_FN             405
+#define SLAPI_PLUGIN_PRE_MODRDN_FN             406
+#define SLAPI_PLUGIN_PRE_ADD_FN                        407
+#define SLAPI_PLUGIN_PRE_DELETE_FN             408
+#define SLAPI_PLUGIN_PRE_ABANDON_FN            409
+#define SLAPI_PLUGIN_PRE_ENTRY_FN              410
+#define SLAPI_PLUGIN_PRE_REFERRAL_FN           411
+#define SLAPI_PLUGIN_PRE_RESULT_FN             412
+
+/*  functions for postoperation functions*/
+#define SLAPI_PLUGIN_POST_BIND_FN              501
+#define SLAPI_PLUGIN_POST_UNBIND_FN            502
+#define SLAPI_PLUGIN_POST_SEARCH_FN            503
+#define SLAPI_PLUGIN_POST_COMPARE_FN           504
+#define SLAPI_PLUGIN_POST_MODIFY_FN            505
+#define SLAPI_PLUGIN_POST_MODRDN_FN            506
+#define SLAPI_PLUGIN_POST_ADD_FN               507
+#define SLAPI_PLUGIN_POST_DELETE_FN            508
+#define SLAPI_PLUGIN_POST_ABANDON_FN           509
+#define SLAPI_PLUGIN_POST_ENTRY_FN             510
+#define SLAPI_PLUGIN_POST_REFERRAL_FN          511
+#define SLAPI_PLUGIN_POST_RESULT_FN            512
+
+/* audit plugin defines */
+#define SLAPI_PLUGIN_AUDIT_DATA                1100
+#define SLAPI_PLUGIN_AUDIT_FN                  1101
+
+/* managedsait control */
+#define SLAPI_MANAGEDSAIT                      1000
+
+/* config stuff */
+#define SLAPI_CONFIG_FILENAME                  40
+#define SLAPI_CONFIG_LINENO                    41
+#define SLAPI_CONFIG_ARGC                      42
+#define SLAPI_CONFIG_ARGV                      43
+
+/*  operational params */
+#define SLAPI_TARGET_DN                                50
+#define SLAPI_REQCONTROLS                      51
+
+/* server LDAPv3 controls  */
+#define SLAPI_RESCONTROLS                      55
+#define SLAPI_ADD_RESCONTROL                   56      
+
+/* add params */
+#define SLAPI_ADD_TARGET                       SLAPI_TARGET_DN
+#define SLAPI_ADD_ENTRY                                60
+
+/* bind params */
+#define SLAPI_BIND_TARGET                      SLAPI_TARGET_DN
+#define SLAPI_BIND_METHOD                      70
+#define SLAPI_BIND_CREDENTIALS                 71      
+#define SLAPI_BIND_SASLMECHANISM               72      
+#define SLAPI_BIND_RET_SASLCREDS               73      
+
+/* compare params */
+#define SLAPI_COMPARE_TARGET                   SLAPI_TARGET_DN
+#define SLAPI_COMPARE_TYPE                     80
+#define SLAPI_COMPARE_VALUE                    81
+
+/* delete params */
+#define SLAPI_DELETE_TARGET                    SLAPI_TARGET_DN
+
+/* modify params */
+#define SLAPI_MODIFY_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_MODIFY_MODS                      90
+
+/* modrdn params */
+#define SLAPI_MODRDN_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_MODRDN_NEWRDN                    100
+#define SLAPI_MODRDN_DELOLDRDN                 101
+#define SLAPI_MODRDN_NEWSUPERIOR               102     /* v3 only */
+
+/* search params */
+#define SLAPI_SEARCH_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_SEARCH_SCOPE                     110
+#define SLAPI_SEARCH_DEREF                     111
+#define SLAPI_SEARCH_SIZELIMIT                 112
+#define SLAPI_SEARCH_TIMELIMIT                 113
+#define SLAPI_SEARCH_FILTER                    114
+#define SLAPI_SEARCH_STRFILTER                 115
+#define SLAPI_SEARCH_ATTRS                     116
+#define SLAPI_SEARCH_ATTRSONLY                 117
+
+/* abandon params */
+#define SLAPI_ABANDON_MSGID                    120
+
+/* extended operation params */
+#define SLAPI_EXT_OP_REQ_OID                   160
+#define SLAPI_EXT_OP_REQ_VALUE         161     
+
+/* extended operation return codes */
+#define SLAPI_EXT_OP_RET_OID                   162     
+#define SLAPI_EXT_OP_RET_VALUE         163     
+
+#define SLAPI_PLUGIN_EXTENDED_SENT_RESULT      -1
+
+/* Search result params */
+#define SLAPI_SEARCH_RESULT_SET                        193
+#define        SLAPI_SEARCH_RESULT_ENTRY               194
+#define        SLAPI_NENTRIES                          195
+#define SLAPI_SEARCH_REFERRALS                 196
+
+
+/* filter types */
+#ifndef LDAP_FILTER_AND
+#define LDAP_FILTER_AND         0xa0L
+#endif
+#ifndef LDAP_FILTER_OR
+#define LDAP_FILTER_OR          0xa1L
+#endif
+#ifndef LDAP_FILTER_NOT
+#define LDAP_FILTER_NOT         0xa2L
+#endif
+#ifndef LDAP_FILTER_EQUALITY
+#define LDAP_FILTER_EQUALITY    0xa3L
+#endif
+#ifndef LDAP_FILTER_SUBSTRINGS
+#define LDAP_FILTER_SUBSTRINGS  0xa4L
+#endif
+#ifndef LDAP_FILTER_GE
+#define LDAP_FILTER_GE          0xa5L
+#endif
+#ifndef LDAP_FILTER_LE
+#define LDAP_FILTER_LE          0xa6L
+#endif
+#ifndef LDAP_FILTER_PRESENT
+#define LDAP_FILTER_PRESENT     0x87L
+#endif
+#ifndef LDAP_FILTER_APPROX
+#define LDAP_FILTER_APPROX      0xa8L
+#endif
+#ifndef LDAP_FILTER_EXT_MATCH
+#define LDAP_FILTER_EXT_MATCH   0xa9L
+#endif
+
+int slapi_log_error( int severity, char *subsystem, char *fmt, ... );
+#define SLAPI_LOG_FATAL                 0
+#define SLAPI_LOG_TRACE                 1
+#define SLAPI_LOG_PACKETS               2
+#define SLAPI_LOG_ARGS                  3
+#define SLAPI_LOG_CONNS                 4
+#define SLAPI_LOG_BER                   5
+#define SLAPI_LOG_FILTER                6
+#define SLAPI_LOG_CONFIG                7
+#define SLAPI_LOG_ACL                   8
+#define SLAPI_LOG_SHELL                 9
+#define SLAPI_LOG_PARSE                 10
+#define SLAPI_LOG_HOUSE                 11
+#define SLAPI_LOG_REPL                  12
+#define SLAPI_LOG_CACHE                 13
+#define SLAPI_LOG_PLUGIN                14
+#define SLAPI_LOG_TIMING                15
+
+#define SLAPI_PLUGIN_DESCRIPTION       12
+typedef struct slapi_plugindesc {
+        char    *spd_id;
+        char    *spd_vendor;
+        char    *spd_version;
+        char    *spd_description;
+} Slapi_PluginDesc;
+
+#define SLAPI_PLUGIN_VERSION_01         "01"
+#define SLAPI_PLUGIN_VERSION_02         "02"
+#define SLAPI_PLUGIN_VERSION_03         "03"
+#define SLAPI_PLUGIN_CURRENT_VERSION    SLAPI_PLUGIN_VERSION_03
+
+#endif /* _SLAPI_PLUGIN_H */
+
diff --git a/servers/slapd/slapi/slapi.h b/servers/slapd/slapi/slapi.h
new file mode 100644 (file)
index 0000000..e46f6c4
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#ifndef _SLAPI_H
+#define _SLAPI_H
+
+#include <ibm_pblock_params.h> 
+
+typedef struct slapi_pblock    Slapi_PBlock;
+typedef struct slap_entry      Slapi_Entry;
+typedef struct slap_attr       Slapi_Attr;
+typedef Filter                 Slapi_Filter;
+
+#include <slapi_utils.h>
+#ifndef NO_PBLOCK_CLASS
+#include <slapi_pblock.h>
+#endif /* NO_PBLOCK_CLASS */
+#include <plugin.h>
+#include <slapi_ops.h>
+#include <slapi_cl.h>
+
+/*
+ * types of plugins
+ */
+#define SLAPI_PLUGIN_DATABASE           1
+#define SLAPI_PLUGIN_EXTENDEDOP         2
+#define SLAPI_PLUGIN_PREOPERATION       3
+#define SLAPI_PLUGIN_POSTOPERATION      4
+#define SLAPI_PLUGIN_MATCHINGRULE       5
+#define SLAPI_PLUGIN_SYNTAX             6
+#define SLAPI_PLUGIN_AUDIT              7
+
+#define SLAPI_PLUGIN_EXTENDED_SENT_RESULT       -1
+#define SLAPI_PLUGIN_EXTENDED_NOT_HANDLED       -2
+
+#define SLAPI_BACKEND                          130
+#define SLAPI_CONNECTION                       131
+#define SLAPI_OPERATION                                132
+#define SLAPI_REQUESTOR_ISROOT                 133
+#define SLAPI_BE_MONITORDN                     134
+#define SLAPI_BE_TYPE                          135
+#define SLAPI_BE_READONLY                      136
+#define SLAPI_BE_LASTMOD                               137
+#define SLAPI_CONN_ID                          139
+
+#define SLAPI_OPINITIATED_TIME                 140
+#define SLAPI_REQUESTOR_DN                     141
+#define SLAPI_REQUESTOR_ISUPDATEDN             142
+#define SLAPI_CONN_DN                          143
+#define SLAPI_CONN_AUTHTYPE                            144
+
+#define SLAPD_AUTH_NONE   "none"
+#define SLAPD_AUTH_SIMPLE "simple"
+#define SLAPD_AUTH_SSL    "SSL"
+#define SLAPD_AUTH_SASL   "SASL "
+
+#define SLAPI_PLUGIN                           3
+#define SLAPI_PLUGIN_PRIVATE                   4
+#define SLAPI_PLUGIN_TYPE                      5
+#define SLAPI_PLUGIN_ARGV                      6
+#define SLAPI_PLUGIN_ARGC                      7
+#define SLAPI_PLUGIN_VERSION                   8
+
+#define SLAPI_PLUGIN_OPRETURN                  9
+#define SLAPI_PLUGIN_OBJECT                    10
+#define SLAPI_PLUGIN_DESTROY_FN                        11
+
+#define SLAPI_PLUGIN_DESCRIPTION               12
+
+#define SLAPI_PLUGIN_INTOP_RESULT              15
+#define SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES      16
+#define SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS    17
+
+#define SLAPI_PLUGIN_DB_BIND_FN                        200
+#define SLAPI_PLUGIN_DB_UNBIND_FN              201
+#define SLAPI_PLUGIN_DB_SEARCH_FN              202
+#define SLAPI_PLUGIN_DB_COMPARE_FN             203
+#define SLAPI_PLUGIN_DB_MODIFY_FN              204
+#define SLAPI_PLUGIN_DB_MODRDN_FN              205
+#define SLAPI_PLUGIN_DB_ADD_FN                 206
+#define SLAPI_PLUGIN_DB_DELETE_FN              207
+#define SLAPI_PLUGIN_DB_ABANDON_FN             208
+#define SLAPI_PLUGIN_DB_CONFIG_FN              209
+#define SLAPI_PLUGIN_CLOSE_FN                  210
+#define SLAPI_PLUGIN_DB_FLUSH_FN               211
+#define SLAPI_PLUGIN_START_FN                  212
+#define SLAPI_PLUGIN_DB_SEQ_FN                 213
+#define SLAPI_PLUGIN_DB_ENTRY_FN               214
+#define SLAPI_PLUGIN_DB_REFERRAL_FN            215
+#define SLAPI_PLUGIN_DB_RESULT_FN              216
+#define SLAPI_PLUGIN_DB_LDIF2DB_FN             217
+#define SLAPI_PLUGIN_DB_DB2LDIF_FN             218
+#define SLAPI_PLUGIN_DB_BEGIN_FN               219
+#define SLAPI_PLUGIN_DB_COMMIT_FN              220
+#define SLAPI_PLUGIN_DB_ABORT_FN               221
+#define SLAPI_PLUGIN_DB_ARCHIVE2DB_FN          222
+#define SLAPI_PLUGIN_DB_DB2ARCHIVE_FN          223
+#define SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN   224
+#define SLAPI_PLUGIN_DB_FREE_RESULT_SET_FN     225
+#define        SLAPI_PLUGIN_DB_SIZE_FN                 226
+#define        SLAPI_PLUGIN_DB_TEST_FN                 227
+#define SLAPI_PLUGIN_DB_NO_ACL                 250
+
+#define SLAPI_PLUGIN_EXT_OP_FN                 300
+#define SLAPI_PLUGIN_EXT_OP_OIDLIST            301
+#define SLAPI_PLUGIN_PRE_BIND_FN               401
+#define SLAPI_PLUGIN_PRE_UNBIND_FN             402
+#define SLAPI_PLUGIN_PRE_SEARCH_FN             403
+#define SLAPI_PLUGIN_PRE_COMPARE_FN            404
+#define SLAPI_PLUGIN_PRE_MODIFY_FN             405
+#define SLAPI_PLUGIN_PRE_MODRDN_FN             406
+#define SLAPI_PLUGIN_PRE_ADD_FN                        407
+#define SLAPI_PLUGIN_PRE_DELETE_FN             408
+#define SLAPI_PLUGIN_PRE_ABANDON_FN            409
+#define SLAPI_PLUGIN_PRE_ENTRY_FN              410
+#define SLAPI_PLUGIN_PRE_REFERRAL_FN           411
+#define SLAPI_PLUGIN_PRE_RESULT_FN             412
+#define SLAPI_PLUGIN_POST_BIND_FN              501
+#define SLAPI_PLUGIN_POST_UNBIND_FN            502
+#define SLAPI_PLUGIN_POST_SEARCH_FN            503
+#define SLAPI_PLUGIN_POST_COMPARE_FN           504
+#define SLAPI_PLUGIN_POST_MODIFY_FN            505
+#define SLAPI_PLUGIN_POST_MODRDN_FN            506
+#define SLAPI_PLUGIN_POST_ADD_FN               507
+#define SLAPI_PLUGIN_POST_DELETE_FN            508
+#define SLAPI_PLUGIN_POST_ABANDON_FN           509
+#define SLAPI_PLUGIN_POST_ENTRY_FN             510
+#define SLAPI_PLUGIN_POST_REFERRAL_FN          511
+#define SLAPI_PLUGIN_POST_RESULT_FN            512
+
+#define SLAPI_PLUGIN_MR_FILTER_CREATE_FN       600
+#define SLAPI_PLUGIN_MR_INDEXER_CREATE_FN      601
+#define SLAPI_PLUGIN_MR_FILTER_MATCH_FN                602
+#define SLAPI_PLUGIN_MR_FILTER_INDEX_FN                603
+#define SLAPI_PLUGIN_MR_FILTER_RESET_FN                604
+#define SLAPI_PLUGIN_MR_INDEX_FN               605
+#define SLAPI_PLUGIN_MR_OID                    610
+#define SLAPI_PLUGIN_MR_TYPE                   611
+#define SLAPI_PLUGIN_MR_VALUE                  612
+#define SLAPI_PLUGIN_MR_VALUES                 613
+#define SLAPI_PLUGIN_MR_KEYS                   614
+#define SLAPI_PLUGIN_MR_FILTER_REUSABLE                615
+#define SLAPI_PLUGIN_MR_QUERY_OPERATOR         616
+#define SLAPI_PLUGIN_MR_USAGE                  617
+
+#define SLAPI_OP_LESS                                  1
+#define SLAPI_OP_LESS_OR_EQUAL                         2
+#define SLAPI_OP_EQUAL                                 3
+#define SLAPI_OP_GREATER_OR_EQUAL                      4
+#define SLAPI_OP_GREATER                               5
+#define SLAPI_OP_SUBSTRING                             6
+
+#define SLAPI_PLUGIN_MR_USAGE_INDEX            0
+#define SLAPI_PLUGIN_MR_USAGE_SORT             1
+
+#define SLAPI_PLUGIN_SYNTAX_FILTER_AVA         700
+#define SLAPI_PLUGIN_SYNTAX_FILTER_SUB         701
+#define SLAPI_PLUGIN_SYNTAX_VALUES2KEYS                702
+#define SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA 703
+#define SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB 704
+#define SLAPI_PLUGIN_SYNTAX_NAMES              705
+#define SLAPI_PLUGIN_SYNTAX_OID                        706
+#define SLAPI_PLUGIN_SYNTAX_FLAGS              707
+#define SLAPI_PLUGIN_SYNTAX_COMPARE            708
+
+#define SLAPI_PLUGIN_SYNTAX_FLAG_ORKEYS                        1
+#define SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING              2
+
+#define SLAPI_PLUGIN_AUDIT_DATA                 1100
+#define SLAPI_PLUGIN_AUDIT_FN                   1101
+
+#define SLAPI_MANAGEDSAIT                      1000
+
+#define SLAPI_CONFIG_FILENAME                  40
+#define SLAPI_CONFIG_LINENO                    41
+#define SLAPI_CONFIG_ARGC                      42
+#define SLAPI_CONFIG_ARGV                      43
+
+#define SLAPI_TARGET_DN                                50
+#define SLAPI_REQCONTROLS                      51
+
+#define        SLAPI_ENTRY_PRE_OP                      52
+#define        SLAPI_ENTRY_POST_OP                     53
+
+#define SLAPI_RESCONTROLS                      55
+#define SLAPI_ADD_RESCONTROL                   56
+
+#define SLAPI_ADD_TARGET                       SLAPI_TARGET_DN
+#define SLAPI_ADD_ENTRY                                60
+
+#define SLAPI_BIND_TARGET                      SLAPI_TARGET_DN
+#define SLAPI_BIND_METHOD                      70
+#define SLAPI_BIND_CREDENTIALS                 71
+#define SLAPI_BIND_SASLMECHANISM               72
+#define SLAPI_BIND_RET_SASLCREDS               73
+
+#define SLAPI_COMPARE_TARGET                   SLAPI_TARGET_DN
+#define SLAPI_COMPARE_TYPE                     80
+#define SLAPI_COMPARE_VALUE                    81
+
+#define SLAPI_DELETE_TARGET                    SLAPI_TARGET_DN
+
+#define SLAPI_MODIFY_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_MODIFY_MODS                      90
+
+#define SLAPI_MODRDN_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_MODRDN_NEWRDN                    100
+#define SLAPI_MODRDN_DELOLDRDN                 101
+#define SLAPI_MODRDN_NEWSUPERIOR               102
+
+#define SLAPI_SEARCH_TARGET                    SLAPI_TARGET_DN
+#define SLAPI_SEARCH_SCOPE                     110
+#define SLAPI_SEARCH_DEREF                     111
+#define SLAPI_SEARCH_SIZELIMIT                 112
+#define SLAPI_SEARCH_TIMELIMIT                 113
+#define SLAPI_SEARCH_FILTER                    114
+#define SLAPI_SEARCH_STRFILTER                 115
+#define SLAPI_SEARCH_ATTRS                     116
+#define SLAPI_SEARCH_ATTRSONLY                 117
+
+#define SLAPI_ABANDON_MSGID                    120
+
+#define SLAPI_SEQ_TYPE                         150
+#define SLAPI_SEQ_ATTRNAME                     151
+#define SLAPI_SEQ_VAL                          152
+
+#define SLAPI_EXT_OP_REQ_OID                   160
+#define SLAPI_EXT_OP_REQ_VALUE                 161
+#define SLAPI_EXT_OP_RET_OID                   162
+#define SLAPI_EXT_OP_RET_VALUE                 163
+
+#define SLAPI_MR_FILTER_ENTRY                  170     
+#define SLAPI_MR_FILTER_TYPE                   171
+#define SLAPI_MR_FILTER_VALUE                  172
+#define SLAPI_MR_FILTER_OID                    173
+#define SLAPI_MR_FILTER_DNATTRS                        174
+
+#define SLAPI_LDIF2DB_FILE                     180
+#define SLAPI_LDIF2DB_REMOVEDUPVALS            185
+
+#define SLAPI_DB2LDIF_PRINTKEY                 183
+
+#define SLAPI_PARENT_TXN                       190
+#define SLAPI_TXN                              191
+
+#define SLAPI_SEARCH_RESULT_SET                        193
+#define        SLAPI_SEARCH_RESULT_ENTRY               194
+#define        SLAPI_NENTRIES                          195
+#define SLAPI_SEARCH_REFERRALS                 196
+
+#define        SLAPI_CHANGENUMBER                      197
+#define        SLAPI_LOG_OPERATION                     198
+
+#define SLAPI_DBSIZE                           199
+
+#define SLAPI_LOG_FATAL                        0
+#define SLAPI_LOG_TRACE                                1
+#define SLAPI_LOG_PACKETS                      2
+#define SLAPI_LOG_ARGS                         3
+#define SLAPI_LOG_CONNS                                4
+#define SLAPI_LOG_BER                          5
+#define SLAPI_LOG_FILTER                       6
+#define SLAPI_LOG_CONFIG                       7
+#define SLAPI_LOG_ACL                          8
+#define SLAPI_LOG_SHELL                                9
+#define SLAPI_LOG_PARSE                                10
+#define SLAPI_LOG_HOUSE                                11
+#define SLAPI_LOG_REPL                         12
+#define SLAPI_LOG_CACHE                                13
+#define SLAPI_LOG_PLUGIN                       14
+
+#define SLAPI_OPERATION_BIND                   0x00000001L
+#define SLAPI_OPERATION_UNBIND                 0x00000002L
+#define SLAPI_OPERATION_SEARCH                 0x00000004L
+#define SLAPI_OPERATION_MODIFY                 0x00000008L
+#define SLAPI_OPERATION_ADD                    0x00000010L
+#define SLAPI_OPERATION_DELETE                 0x00000020L
+#define SLAPI_OPERATION_MODDN                  0x00000040L
+#define SLAPI_OPERATION_MODRDN                 SLAPI_OPERATION_MODDN
+#define SLAPI_OPERATION_COMPARE                0x00000080L
+#define SLAPI_OPERATION_ABANDON                0x00000100L
+#define SLAPI_OPERATION_EXTENDED               0x00000200L
+#define SLAPI_OPERATION_ANY                    0xFFFFFFFFL
+#define SLAPI_OPERATION_NONE                   0x00000000L
+
+#endif /* _SLAPI_H */
+
diff --git a/servers/slapd/slapi/slapi_cl.h b/servers/slapd/slapi/slapi_cl.h
new file mode 100644 (file)
index 0000000..ad4ac6e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#ifndef _SLAPI_CL_H
+#define _SLAPI_CL_H
+
+#define TIME_SIZE 20
+#define OBJECTCLASS "objectclass"
+#define TOP "top"
+#define CHANGE_TIME "changetime"
+#define CHANGE_TYPE "changetype"
+#define CHANGE_TARGETDN "targetdn"
+#define CHANGES        "changes"
+#define CHANGE_NUMBER "changenumber"
+/*
+ * FIXME: I get complaints like "ADD" being redefined - first definition
+ * being in "/usr/include/arpa/nameser.h:552"
+ */
+#undef ADD
+#define ADD "add: "
+#define ADDLEN 5
+#define DEL "delete: "
+#define DELLEN 8
+#define REPLACE "replace: "
+#define REPLEN 9
+#define MOD "modify"
+#define MODRDN "modrdn"
+#define CHANGE_LOGENTRY "changelogentry"
+#define IBM_CHANGE_LOGENTRY "ibm-changelog"
+#define CL_NEWRDN "newrdn"
+#define CL_DELRDN "deleteoldrdn"
+#define CHANGE_INITIATOR "ibm-changeInitiatorsName" 
+
+void slapi_register_changelog_suffix(char *suffix);
+char **slapi_get_changelog_suffixes();
+void slapi_update_changelog_counters(long curNum, long numEntries);
+char *slapi_get_cl_firstNum();
+char *slapi_get_cl_lastNum();
+int slapi_add_to_changelog(Slapi_Entry *ent, char *suffix, char *chNum, Operation* op);        
+int slapi_delete_changelog(char *dn, char *suffix, char *chNum, Operation* op);        
+int slapi_modify_changelog(char *dn,LDAPMod    *mods,char *suffix, char *chNum, Operation* op); 
+int slapi_modifyrdn_changelog(char *olddn, char *newRdn, int delRdn, char *suffix, char *chNum, Operation* op);
+Backend * slapi_cl_get_be(char *dn);
+
+#endif /* _SLAPI_CL_H */
+
diff --git a/servers/slapd/slapi/slapi_common.h b/servers/slapd/slapi/slapi_common.h
new file mode 100644 (file)
index 0000000..7a97d5d
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#ifndef SLAPI_COMMON_H
+#define SLAPI_COMMON_H
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define dn_normalize_case      dn_normalize
+#define SLAPD_NO_MEMORY        7
+#define ANYBODY_STRING                 "CN=ANYBODY"
+
+extern int slap_debug;
+
+int
+dn_check(char *, int  *);
+
+
+typedef struct strlist {
+       char *string;
+       struct strlist *next;
+} StrList;
+
+#endif /* SLAPI_COMMON_H */
+
diff --git a/servers/slapd/slapi/slapi_ops.c b/servers/slapd/slapi/slapi_ops.c
new file mode 100644 (file)
index 0000000..4ff9264
--- /dev/null
@@ -0,0 +1,1269 @@
+/*\r
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.\r
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file\r
+ */\r
+/*\r
+ * (C) Copyright IBM Corp. 1997,2002\r
+ * Redistribution and use in source and binary forms are permitted\r
+ * provided that this notice is preserved and that due credit is\r
+ * given to IBM Corporation. This software is provided ``as is''\r
+ * without express or implied warranty.\r
+ */\r
+\r
+#include "portable.h"\r
+#include "slapi_common.h"\r
+#include <slap.h>\r
+#include <slapi.h>\r
+#include <lber.h>\r
+#include "../../../libraries/liblber/lber-int.h"\r
+\r
+\r
+int bvptr2obj( struct berval **bvptr, struct berval **bvobj );\r
+\r
+int\r
+internal_result_v3(\r
+       Connection *conn, \r
+       Operation *op, \r
+       int err,\r
+       char *matched, \r
+       char *text, \r
+       char **referrals )\r
+{\r
+       return LDAP_SUCCESS;\r
+}\r
+\r
+int\r
+internal_search_entry(\r
+       Backend *be, \r
+       Connection *conn, \r
+       Operation *op, \r
+       Entry *e, \r
+       char **attrs, \r
+       int attrsonly, \r
+       char **denied_attrs ) \r
+{\r
+       char *ent2str = NULL;\r
+       int nentries = 0, len = 0, i = 0;\r
+       Slapi_Entry **head = NULL, **tp;\r
+       \r
+       ent2str = slapi_entry2str( e, &len );\r
+       if ( ent2str == NULL ) {\r
+               return SLAPD_NO_MEMORY;\r
+       }\r
+\r
+       slapi_pblock_get( (Slapi_PBlock *)op->o_pb,\r
+                       SLAPI_NENTRIES, &nentries );\r
+       slapi_pblock_get( (Slapi_PBlock *)op->o_pb,\r
+                       SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );\r
+       \r
+       i = nentries + 1;\r
+       if ( nentries == 0 ) {\r
+               tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );\r
+               if ( tp == NULL ) {\r
+                       return SLAPD_NO_MEMORY;\r
+               }\r
+\r
+               tp[ 0 ] = (Slapi_Entry *)str2entry( ent2str );\r
+               if ( tp[ 0 ] == NULL ) { \r
+                       return SLAPD_NO_MEMORY;\r
+               }\r
+\r
+       } else {\r
+               tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,\r
+                               sizeof(Slapi_Entry *) * ( i + 1 ) );\r
+               if ( tp == NULL ) {\r
+                       return SLAPD_NO_MEMORY;\r
+               }\r
+               tp[ i - 1 ] = (Slapi_Entry *)str2entry( ent2str );\r
+               if ( tp[ i - 1 ] == NULL ) { \r
+                       return SLAPD_NO_MEMORY;\r
+               }\r
+       }\r
+       tp[ i ] = NULL;\r
+                 \r
+       slapi_pblock_set( (Slapi_PBlock *)op->o_pb,\r
+                       SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );\r
+       slapi_pblock_set( (Slapi_PBlock *)op->o_pb,\r
+                       SLAPI_NENTRIES, (void *)i );\r
+       slapi_ch_free( ent2str );\r
+\r
+       return LDAP_SUCCESS;\r
+}\r
+\r
+int\r
+internal_search_result(\r
+       Connection *conn, \r
+       Operation *op,\r
+       int err, \r
+       char *matched, \r
+       char *text, \r
+       int nentries ) \r
+{\r
+       slapi_pblock_set( (Slapi_PBlock *)op->o_pb,\r
+                       SLAPI_NENTRIES, (void *)nentries );\r
+\r
+       return LDAP_SUCCESS;\r
+}\r
+\r
+int\r
+internal_result_ext(\r
+       Connection *conn, \r
+       Operation *op, \r
+       int  errnum, \r
+       char *respname, \r
+       struct berval *response )\r
+{\r
+       return LDAP_SUCCESS;\r
+}\r
+\r
+int\r
+internal_search_reference(\r
+       Connection *conn, \r
+       Operation *op, \r
+       char **ref ) \r
+{\r
+       return LDAP_SUCCESS;\r
+}\r
+\r
+static Connection *\r
+fakeConnection(\r
+       char *DN, \r
+       int OpType ) \r
+{ \r
+       Connection *pConn, *c;\r
+       ber_len_t max = sockbuf_max_incoming;\r
+\r
+       pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection));\r
+       if (pConn == NULL) {\r
+               return (Connection *)NULL;\r
+       }\r
+\r
+       LDAP_STAILQ_INIT( &pConn->c_pending_ops );\r
+\r
+       pConn->c_pending_ops.stqh_first =\r
+               (Operation *) slapi_ch_calloc( 1, sizeof(Operation) );\r
+       if ( pConn->c_pending_ops.stqh_first == NULL ) { \r
+               slapi_ch_free( pConn );\r
+               return (Connection *)NULL;\r
+       }\r
+\r
+       pConn->c_pending_ops.stqh_first->o_pb = \r
+               (Slapi_PBlock *) slapi_pblock_new();\r
+       if ( pConn->c_pending_ops.stqh_first->o_pb == NULL ) {\r
+               slapi_ch_free( pConn->c_pending_ops.stqh_first );\r
+               slapi_ch_free( pConn );\r
+               return (Connection *)NULL;\r
+       }\r
+\r
+       c = pConn;\r
+\r
+       /* operation object */\r
+       c->c_pending_ops.stqh_first->o_tag = OpType;\r
+       c->c_pending_ops.stqh_first->o_protocol = LDAP_VERSION3; \r
+       c->c_pending_ops.stqh_first->o_authmech.bv_val = NULL; \r
+       c->c_pending_ops.stqh_first->o_authmech.bv_len = 0; \r
+       c->c_pending_ops.stqh_first->o_time = slap_get_time();\r
+\r
+       /* connection object */\r
+       c->c_authmech.bv_val = NULL;\r
+       c->c_authmech.bv_len = 0;\r
+       c->c_dn.bv_val = NULL;\r
+       c->c_dn.bv_len = 0;\r
+       c->c_ndn.bv_val = NULL;\r
+       c->c_ndn.bv_len = 0;\r
+       c->c_groups = NULL;\r
+\r
+       c->c_listener = NULL;\r
+       c->c_peer_domain.bv_val = NULL;\r
+       c->c_peer_domain.bv_len = 0;\r
+       c->c_peer_name.bv_val = NULL;\r
+       c->c_peer_name.bv_len = 0;\r
+\r
+       LDAP_STAILQ_INIT( &c->c_ops );\r
+\r
+       c->c_sasl_bind_mech.bv_val = NULL;\r
+       c->c_sasl_bind_mech.bv_len = 0;\r
+       c->c_sasl_context = NULL;\r
+       c->c_sasl_extra = NULL;\r
+\r
+       c->c_sb = ber_sockbuf_alloc( );\r
+\r
+       ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );\r
+\r
+       c->c_currentber = NULL;\r
+\r
+       /* should check status of thread calls */\r
+       ldap_pvt_thread_mutex_init( &c->c_mutex );\r
+       ldap_pvt_thread_mutex_init( &c->c_write_mutex );\r
+       ldap_pvt_thread_cond_init( &c->c_write_cv );\r
+\r
+       c->c_n_ops_received = 0;\r
+       c->c_n_ops_executing = 0;\r
+       c->c_n_ops_pending = 0;\r
+       c->c_n_ops_completed = 0;\r
+\r
+       c->c_n_get = 0;\r
+       c->c_n_read = 0;\r
+       c->c_n_write = 0;\r
+\r
+       c->c_protocol = LDAP_VERSION3; \r
+\r
+       c->c_activitytime = c->c_starttime = slap_get_time();\r
+\r
+       c->c_connid = 0;\r
+\r
+       c->c_conn_state  = 0x01;        /* SLAP_C_ACTIVE */\r
+       c->c_struct_state = 0x02;       /* SLAP_C_USED */\r
+\r
+       c->c_ssf = c->c_transport_ssf = 0;\r
+       c->c_tls_ssf = 0;\r
+\r
+       backend_connection_init( c );\r
+\r
+       pConn->c_send_ldap_result =\r
+               (SEND_LDAP_RESULT) internal_result_v3;\r
+       pConn->c_send_search_entry =\r
+               (SEND_SEARCH_ENTRY) internal_search_entry;\r
+       pConn->c_send_search_result =\r
+               (SEND_SEARCH_RESULT) internal_search_result;\r
+       pConn->c_send_ldap_extended =\r
+               (SEND_LDAP_EXTENDED) internal_result_ext;\r
+       pConn->c_send_search_reference =\r
+               (SEND_SEARCH_REFERENCE) internal_search_reference;\r
+\r
+       return pConn;\r
+}\r
+\r
+/* \r
+ * Function : ValuestoBValues \r
+ * Convert an array of char ptrs to an array of berval ptrs.\r
+ * return value : LDAP_SUCCESS\r
+ *                LDAP_NO_MEMORY\r
+ *                LDAP_OTHER\r
+*/\r
+\r
+static int \r
+ValuesToBValues(\r
+       char **ppValue, \r
+       struct berval ***pppBV )\r
+{\r
+       int  rc = LDAP_SUCCESS;\r
+       int  i;\r
+       struct berval *pTmpBV;\r
+       struct berval **ppNewBV;\r
+\r
+       /* count the number of char ptrs. */\r
+       for ( i = 0; ppValue != NULL && ppValue[i] != NULL; i++ ) {\r
+               ;       /* NULL */\r
+       }\r
+\r
+       if ( i == 0 ) {\r
+               rc = LDAP_OTHER;\r
+       } else {\r
+               *pppBV = ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*(sizeof(struct berval *)) );\r
+               if ( *pppBV == NULL ) {\r
+                       rc = LDAP_NO_MEMORY;\r
+               } else {\r
+                       while ( ppValue != NULL && *ppValue != NULL && rc == LDAP_SUCCESS ) {\r
+                               pTmpBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));\r
+                               if ( pTmpBV == NULL) {\r
+                                       rc = LDAP_NO_MEMORY;\r
+                               } else {\r
+                                       pTmpBV->bv_val = slapi_ch_strdup(*ppValue);\r
+                                       if ( pTmpBV->bv_val == NULL ) {\r
+                                               rc = LDAP_NO_MEMORY;\r
+                                       } else {\r
+                                               pTmpBV->bv_len = strlen(*ppValue);\r
+                                               *ppNewBV = pTmpBV;\r
+                                               ppNewBV++;\r
+                                       }\r
+                                       ppValue++;\r
+                               }\r
+                       }\r
+                       /* null terminate the array of berval ptrs */\r
+                       *ppNewBV = NULL;\r
+               }\r
+       }\r
+       return( rc );\r
+}\r
+\r
+\r
+/*\r
+ * Function : LDAPModToEntry \r
+ * convert a dn plus an array of LDAPMod struct ptrs to an entry structure\r
+ * with a link list of the correspondent attributes.\r
+ * Return value : LDAP_SUCCESS\r
+ *                LDAP_NO_MEMORY\r
+ *                LDAP_OTHER\r
+*/\r
+Entry *\r
+LDAPModToEntry(\r
+       char *ldn, \r
+       LDAPMod **mods )\r
+{\r
+       struct berval           dn = { 0, NULL };\r
+       Entry                   *pEntry=NULL;\r
+       LDAPMod                 *pMod;\r
+       struct berval           *bv;\r
+       struct berval           **ppBV;\r
+       Backend                 *be;\r
+       Operation               *op;\r
+\r
+       Modifications           *modlist = NULL;\r
+       Modifications           **modtail = &modlist;\r
+       Modifications           tmp;\r
+\r
+       int                     rc = LDAP_SUCCESS;\r
+       int                     i;\r
+\r
+       const char              *text = NULL;\r
+\r
+\r
+       op = (Operation *) slapi_ch_calloc(1, sizeof(Operation));\r
+       if ( pEntry == NULL) {\r
+               rc = LDAP_NO_MEMORY;\r
+               goto cleanup;\r
+       }  \r
+       op->o_tag = LDAP_REQ_ADD;\r
+\r
+       pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );\r
+       if ( pEntry == NULL) {\r
+               rc = LDAP_NO_MEMORY;\r
+               goto cleanup;\r
+       } \r
+\r
+       dn.bv_val = slapi_ch_strdup(ldn);\r
+       dn.bv_len = strlen(ldn);\r
+\r
+       rc = dnPrettyNormal( NULL, &dn, &pEntry->e_name, &pEntry->e_nname );\r
+       if (rc != LDAP_SUCCESS) goto cleanup;\r
+\r
+       if ( rc == LDAP_SUCCESS ) {\r
+               for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {\r
+                       Modifications *mod;\r
+                       if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {\r
+                               /* attr values are in berval format */\r
+                               /* convert an array of pointers to bervals to an array of bervals */\r
+                               rc = bvptr2obj(pMod->mod_bvalues, &bv);\r
+                               if (rc != LDAP_SUCCESS) goto cleanup;\r
+                               tmp.sml_type.bv_val = slapi_ch_strdup(pMod->mod_type);\r
+                               tmp.sml_type.bv_len = slapi_ch_stlen(pMod->mod_type);\r
+                               tmp.sml_bvalues = bv;\r
+               \r
+                               mod  = (Modifications *) ch_malloc( sizeof(Modifications) );\r
+\r
+                               mod->sml_op = LDAP_MOD_ADD;\r
+                               mod->sml_next = NULL;\r
+                               mod->sml_desc = NULL;\r
+                               mod->sml_type = tmp.sml_type;\r
+                               mod->sml_bvalues = tmp.sml_bvalues;\r
+\r
+                               *modtail = mod;\r
+                               modtail = &mod->sml_next;\r
+\r
+                       } else {\r
+                               /* attr values are in string format, need to be converted */\r
+                               /* to an array of bervals */ \r
+                               if ( pMod->mod_values == NULL ) {\r
+                                       rc = LDAP_OTHER;\r
+                               } else {\r
+                                       rc = ValuesToBValues( pMod->mod_values, &ppBV );\r
+                                       if (rc != LDAP_SUCCESS) goto cleanup;\r
+                                       rc = bvptr2obj(ppBV, &bv);\r
+                                       if (rc != LDAP_SUCCESS) goto cleanup;\r
+                                       tmp.sml_type.bv_val = slapi_ch_strdup(pMod->mod_type);\r
+                                       tmp.sml_type.bv_len = slapi_ch_stlen(pMod->mod_type);\r
+                                       tmp.sml_bvalues = bv;\r
+               \r
+                                       mod  = (Modifications *) ch_malloc( sizeof(Modifications) );\r
+\r
+                                       mod->sml_op = LDAP_MOD_ADD;\r
+                                       mod->sml_next = NULL;\r
+                                       mod->sml_desc = NULL;\r
+                                       mod->sml_type = tmp.sml_type;\r
+                                       mod->sml_bvalues = tmp.sml_bvalues;\r
+\r
+                                       *modtail = mod;\r
+                                       modtail = &mod->sml_next;\r
+\r
+                                       if ( ppBV != NULL ) {\r
+                                               ber_bvecfree( ppBV );\r
+                                       }\r
+                               }\r
+                       }\r
+               } /* for each LDAPMod */\r
+       }\r
+\r
+       be = select_backend(&dn, 0, 0);\r
+       if ( be == NULL ) {\r
+               rc =  LDAP_PARTIAL_RESULTS;\r
+               goto cleanup;\r
+       }\r
+\r
+       if ( be ) {\r
+               int repl_user = be_isupdate(be, &be->be_rootdn );\r
+               if ( !be->be_update_ndn.bv_len || repl_user ) {\r
+                       int update = be->be_update_ndn.bv_len;\r
+                       char textbuf[SLAP_TEXT_BUFLEN];\r
+                       size_t textlen = sizeof textbuf;\r
+\r
+                       rc = slap_mods_check( modlist, update, &text, \r
+                                       textbuf, textlen );\r
+                       if ( rc != LDAP_SUCCESS) {\r
+                               goto cleanup;\r
+                       }\r
+\r
+                       if ( !repl_user ) {\r
+                               rc = slap_mods_opattrs( be, op,\r
+                                               modlist, modtail, &text, \r
+                                               textbuf, textlen );\r
+                               if ( rc != LDAP_SUCCESS) {\r
+                                       goto cleanup;\r
+                               }\r
+                       }\r
+\r
+                       /*\r
+                        * FIXME: slap_mods2entry is declared static \r
+                        * in servers/slapd/add.c\r
+                        */\r
+                       rc = slap_mods2entry( modlist, &pEntry, repl_user,\r
+                                       &text, textbuf, textlen );\r
+                       if (rc != LDAP_SUCCESS) {\r
+                               goto cleanup;\r
+                       }\r
+\r
+               } else {\r
+                       rc = LDAP_REFERRAL;\r
+               }\r
+       } else {\r
+               rc = LDAP_UNWILLING_TO_PERFORM;\r
+       }\r
+\r
+cleanup:\r
+\r
+       if ( dn.bv_val ) slapi_ch_free( dn.bv_val );\r
+       if ( op ) slapi_ch_free( op );\r
+       if ( modlist != NULL ) slap_mods_free( modlist );\r
+       if ( rc != LDAP_SUCCESS ) {\r
+               if ( pEntry != NULL ) {\r
+                       slapi_entry_free( pEntry );\r
+               }\r
+               pEntry = NULL;\r
+       }\r
+\r
+       return( pEntry );\r
+}\r
+\r
+/* Function : slapi_delete_internal\r
+ *\r
+ * Description : Plugin functions call this routine to delete an entry \r
+ *               in the backend directly\r
+ * Return values : LDAP_SUCCESS\r
+ *                 LDAP_OPERAITONS_ERROR\r
+ *                 LDAP_NO_MEMORY\r
+ *                 LDAP_OTHER\r
+ *                 LDAP_UNWILLING_TO_PERFORM\r
+*/\r
+Slapi_PBlock *\r
+slapi_delete_internal(\r
+       char *ldn, \r
+       LDAPControl **controls, \r
+       int log_change )\r
+{\r
+#if defined(LDAP_SLAPI)\r
+       Backend                 *be;\r
+       Connection              *pConn = NULL;\r
+       Operation               *op = NULL;\r
+       Slapi_PBlock            *pPB = NULL;\r
+       Slapi_PBlock            *pSavePB = NULL;\r
+\r
+       struct berval dn  = { 0, NULL };\r
+       struct berval pdn = { 0, NULL };\r
+       struct berval ndn = { 0, NULL };\r
+\r
+       int                             rc=LDAP_SUCCESS;\r
+       int                             manageDsaIt = 0;\r
+       int                             isCritical;\r
+\r
+       if ( ldn == NULL ) {\r
+               rc = LDAP_OPERATIONS_ERROR; \r
+               goto cleanup;\r
+       }\r
+\r
+       pConn = fakeConnection( NULL,  LDAP_REQ_DELETE );\r
+       if (pConn == NULL) {\r
+               rc = LDAP_NO_MEMORY;\r
+               goto cleanup;\r
+       }\r
+\r
+       op = (Operation *)pConn->c_pending_ops.stqh_first;\r
+       pPB = (Slapi_PBlock *)op->o_pb;\r
+       op->o_ctrls = controls;\r
+\r
+       dn.bv_val = slapi_ch_strdup(ldn);\r
+       dn.bv_len = slapi_strlen(ldn);\r
+       rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
+       if ( rc != LDAP_SUCCESS ) goto cleanup;\r
+\r
+       if ( slapi_control_present( controls, \r
+                       SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical) ) {\r
+               manageDsaIt = 1; \r
+       }\r
+\r
+       be = select_backend( &dn, manageDsaIt, 0 );\r
+       if ( be == NULL ) {\r
+               rc =  LDAP_PARTIAL_RESULTS;\r
+               goto cleanup;\r
+       }\r
+\r
+       op->o_ndn.bv_val = slapi_ch_strdup(be->be_rootdn.bv_val);\r
+       op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
+       pConn->c_dn.bv_val = slapi_ch_strdup(be->be_rootdn.bv_val);\r
+       pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
+\r
+       suffix_alias( be, &ndn );\r
+\r
+       if ( be->be_delete ) {\r
+               int repl_user = be_isupdate( be, &op->o_ndn );\r
+               if ( !be->be_update_ndn.bv_len || repl_user ) {\r
+                       rc = (*be->be_delete)( be, pConn, op, &pdn, &ndn );\r
+                       if ( rc == 0 ) {\r
+                               if (log_change) {\r
+                                       replog( be, op, &pdn, &ndn, NULL );\r
+                               }\r
+                               rc = LDAP_SUCCESS;\r
+                       } else {\r
+                               rc = LDAP_OPERATIONS_ERROR;\r
+                       }\r
+               } else {\r
+                       rc = LDAP_REFERRAL;\r
+               }\r
+       } else {\r
+               rc = LDAP_UNWILLING_TO_PERFORM;\r
+       }\r
+\r
+cleanup:\r
+       if (pPB != NULL) \r
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
+\r
+       if (dn.bv_val) slapi_ch_free(dn.bv_val);\r
+       if (pdn.bv_val) slapi_ch_free(pdn.bv_val);\r
+       if (ndn.bv_val) slapi_ch_free(ndn.bv_val);\r
+\r
+       if ( pConn != NULL ) {\r
+               if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val );\r
+               if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val );\r
+               if ( op ) slapi_ch_free( op );\r
+               pSavePB = pPB;\r
+               free( pConn );\r
+       }\r
+       \r
+       return (pSavePB);\r
+#endif /* LDAP_SLAPI */\r
+       return NULL;\r
+}\r
+\r
+Slapi_PBlock * \r
+slapi_add_entry_internal(\r
+       Slapi_Entry *e, \r
+       LDAPControl **controls, \r
+       int log_changes ) \r
+{\r
+#if defined(LDAP_SLAPI)\r
+       Connection              *pConn = NULL;\r
+       Operation               *op = NULL;\r
+       Slapi_PBlock            *pPB = NULL, *pSavePB = NULL;\r
+       Backend                 *be;\r
+\r
+       int                     manageDsaIt = 0;\r
+       int                     isCritical;\r
+       int                     rc = LDAP_SUCCESS;\r
+\r
+       if ( e == NULL ) {\r
+               rc = LDAP_OPERATIONS_ERROR;\r
+               goto cleanup;\r
+       }\r
+       \r
+       pConn = fakeConnection( NULL, LDAP_REQ_ADD );\r
+       if ( pConn == NULL ) {\r
+               rc = LDAP_NO_MEMORY;\r
+               goto cleanup;\r
+       }\r
+\r
+       if ( slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT,\r
+                               NULL, &isCritical ) ) {\r
+               manageDsaIt = 1; \r
+       }\r
+\r
+       op = (Operation *)pConn->c_pending_ops.stqh_first;\r
+       pPB = (Slapi_PBlock *)op->o_pb;\r
+       op->o_ctrls = controls;\r
+\r
+       be = select_backend( &e->e_nname, manageDsaIt, 0 );\r
+       if ( be == NULL ) {\r
+               rc = LDAP_PARTIAL_RESULTS;\r
+               goto cleanup;\r
+       }\r
+\r
+       op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
+       op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
+       pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
+       pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
+\r
+       if ( be->be_add ) {\r
+               int repl_user = be_isupdate( be, &op->o_ndn );\r
+               if ( !be->be_update_ndn.bv_len || repl_user ){\r
+                       if ( (*be->be_add)( be, pConn, op, e ) == 0 ) {\r
+                               if ( log_changes ) {\r
+                                       replog( be, op, &e->e_name, \r
+                                                       &e->e_nname, e );\r
+                               }\r
+                               rc = LDAP_SUCCESS;\r
+                       }\r
+               } else {\r
+                       rc = LDAP_REFERRAL;\r
+               }\r
+       } else {\r
+               rc = LDAP_UNWILLING_TO_PERFORM;\r
+       }\r
+\r
+cleanup:\r
+\r
+       if ( pPB != NULL ) {\r
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
+       }\r
+\r
+       if ( pConn != NULL ) {\r
+               if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val );\r
+               if ( op ) {\r
+                       if ( op->o_ndn.bv_val ) {\r
+                               slapi_ch_free( op->o_ndn.bv_val );\r
+                       }\r
+                       free(op);\r
+               }\r
+               pSavePB = pPB;\r
+               free( pConn );\r
+       }\r
+       return( pSavePB );\r
+#endif /* LDAP_SLAPI */\r
+       return NULL;\r
+}\r
+\r
+\r
+Slapi_PBlock *\r
+slapi_add_internal(\r
+       char *dn, \r
+       LDAPMod **mods, \r
+       LDAPControl **controls, \r
+       int log_changes  ) \r
+{\r
+#if defined(LDAP_SLAPI)\r
+       LDAPMod                 *pMod = NULL;\r
+       Slapi_PBlock            *pb = NULL;\r
+       Entry                   *pEntry = NULL;\r
+       int                     i, rc=LDAP_SUCCESS;\r
+\r
+       if ( mods == NULL || *mods == NULL || dn == NULL || *dn == '\0' ) {\r
+               rc = LDAP_OPERATIONS_ERROR ;\r
+       }\r
+\r
+       if ( rc == LDAP_SUCCESS ) {\r
+               for ( i = 0, pMod = mods[0]; pMod != NULL; pMod = mods[++i] ) {\r
+                       if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD ) {\r
+                               rc = LDAP_OTHER;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       if ( rc == LDAP_SUCCESS ) {\r
+               if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {\r
+                       rc = LDAP_OTHER;\r
+               }\r
+       }\r
+\r
+       if ( rc != LDAP_SUCCESS ) {\r
+               pb = slapi_pblock_new();\r
+               slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
+       } else {\r
+               pb = slapi_add_entry_internal( pEntry, controls, log_changes );\r
+       }\r
+\r
+       if ( pEntry ) {\r
+               slapi_entry_free(pEntry);\r
+       }\r
+\r
+       return(pb);\r
+#endif /* LDAP_SLAPI */\r
+       return NULL;\r
+}\r
+\r
+/* Function : slapi_modrdn_internal\r
+ *\r
+ * Description : Plugin functions call this routine to modify the rdn \r
+ *                              of an entry in the backend directly\r
+ * Return values : LDAP_SUCCESS\r
+ *                 LDAP_OPERAITONS_ERROR\r
+ *                 LDAP_NO_MEMORY\r
+ *                 LDAP_OTHER\r
+ *                 LDAP_UNWILLING_TO_PERFORM\r
+ *\r
+ * NOTE: This function does not support the "newSuperior" option from LDAP V3.\r
+ */\r
+Slapi_PBlock *\r
+slapi_modrdn_internal(\r
+       char *olddn, \r
+       char *lnewrdn, \r
+       int deloldrdn, \r
+       LDAPControl **controls, \r
+       int log_change )\r
+{\r
+#if defined(LDAP_SLAPI)\r
+       int                     rc = LDAP_SUCCESS;\r
+\r
+       struct berval           dn = { 0, NULL };\r
+       struct berval           pdn = { 0, NULL };\r
+       struct berval           ndn = { 0, NULL };\r
+\r
+       struct berval           newrdn = { 0, NULL };\r
+       struct berval           pnewrdn = { 0, NULL };\r
+       struct berval           nnewrdn = { 0, NULL };\r
+\r
+#if 0 /* currently unused */\r
+       struct berval           newSuperior = { 0, NULL };\r
+#endif\r
+       struct berval           pnewSuperior = { 0, NULL }; \r
+#if 0 /* currently unused */\r
+       struct berval           nnewSuperior = { 0, NULL }; \r
+#endif\r
+\r
+       struct berval           *pnewS = NULL;\r
+       struct berval           *nnewS = NULL;\r
+\r
+       Connection              *pConn = NULL;\r
+       Operation               *op = NULL;\r
+       Slapi_PBlock            *pPB = NULL;\r
+       Slapi_PBlock            *pSavePB = NULL;\r
+\r
+       Backend                 *be;\r
+#if 0 /* currently unused */\r
+       Backend                 *newSuperior_be = NULL;\r
+#endif\r
+\r
+       int                     manageDsaIt = 0;\r
+       int                     isCritical;\r
+#if 0 /* currently unused */\r
+       const char              *text = NULL;\r
+#endif\r
+\r
+       dn.bv_val = slapi_ch_strdup(olddn);\r
+       dn.bv_len = slapi_ch_stlen(olddn);\r
+\r
+       rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
+\r
+       if ( rc != LDAP_SUCCESS ) goto cleanup;\r
+\r
+       if ( ndn.bv_len == 0 ) {\r
+               rc = LDAP_UNWILLING_TO_PERFORM;\r
+               goto cleanup;\r
+       }\r
+\r
+       newrdn.bv_val = slapi_ch_strdup( lnewrdn );\r
+       newrdn.bv_len = slapi_ch_stlen( lnewrdn );\r
+\r
+       rc = dnPrettyNormal( NULL, &newrdn, &pnewrdn, &nnewrdn );\r
+\r
+       if ( rc != LDAP_SUCCESS ) goto cleanup;\r
+\r
+       if ( rdnValidate( &pnewrdn ) != LDAP_SUCCESS ) goto cleanup;\r
+\r
+       pConn = fakeConnection( NULL,  LDAP_REQ_MODRDN);\r
+       if ( pConn == NULL) {\r
+               rc = LDAP_NO_MEMORY;\r
+               goto cleanup;\r
+       }\r
+\r
+       op = (Operation *)pConn->c_pending_ops.stqh_first;\r
+       pPB = (Slapi_PBlock *)op->o_pb;\r
+       op->o_ctrls = controls;\r
+\r
+       if ( slapi_control_present( controls, \r
+                       SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {\r
+               manageDsaIt = 1;\r
+       }\r
+\r
+       be = select_backend( &dn, manageDsaIt, 0 );\r
+       if ( be == NULL ) {\r
+               rc =  LDAP_PARTIAL_RESULTS;\r
+               goto cleanup;\r
+       }\r
+\r
+       op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
+       op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
+       pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
+       pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
+\r
+       suffix_alias( be, &ndn );\r
+\r
+       if ( be->be_modrdn ) {\r
+               int repl_user = be_isupdate( be, &op->o_ndn );\r
+               if ( !be->be_update_ndn.bv_len || repl_user ) {\r
+                       rc = (*be->be_modrdn)( be, pConn, op, &pdn, &ndn,\r
+                                       &pnewrdn, &nnewrdn, deloldrdn, pnewS,\r
+                                       nnewS );\r
+                       if ( rc == 0 ) {\r
+                               struct slap_replog_moddn moddn;\r
+                               moddn.newrdn = &pnewrdn;\r
+                               moddn.deloldrdn = deloldrdn;\r
+                               moddn.newsup = &pnewSuperior;\r
+                               if ( log_change ) {\r
+                                       replog( be, op, &pdn, &ndn, &moddn );\r
+                               }\r
+                               rc = LDAP_SUCCESS;\r
+\r
+                       } else {\r
+                               rc = LDAP_OPERATIONS_ERROR;\r
+                       }\r
+\r
+               } else {\r
+                       rc = LDAP_REFERRAL;\r
+               }\r
+\r
+       } else {\r
+               rc = LDAP_UNWILLING_TO_PERFORM;\r
+       }\r
+\r
+cleanup:\r
+\r
+       if ( pPB != NULL ) {\r
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
+       }\r
+       \r
+       if ( dn.bv_val ) ch_free( dn.bv_val );\r
+       if ( pdn.bv_val ) ch_free( pdn.bv_val );\r
+       if ( ndn.bv_val ) ch_free( ndn.bv_val );\r
+\r
+       if ( newrdn.bv_val ) ch_free( newrdn.bv_val );\r
+       if ( pnewrdn.bv_val ) ch_free( newrdn.bv_val );\r
+       if ( nnewrdn.bv_val ) ch_free( newrdn.bv_val );\r
+\r
+       if ( pConn != NULL ) {\r
+               if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val );\r
+               if ( op ) {\r
+                       if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val );\r
+                       slapi_ch_free( op );\r
+               }\r
+               pSavePB = pPB;\r
+               free( pConn );\r
+       }\r
+\r
+       return( pSavePB );\r
+#endif /* LDAP_SLAPI */\r
+       return NULL;\r
+}\r
+\r
+/* Function : slapi_modify_internal\r
+ *\r
+ * Description:        Plugin functions call this routine to modify an entry \r
+ *                             in the backend directly\r
+ * Return values : LDAP_SUCCESS\r
+ *                 LDAP_OPERAITONS_ERROR\r
+ *                 LDAP_NO_MEMORY\r
+ *                 LDAP_OTHER\r
+ *                 LDAP_UNWILLING_TO_PERFORM\r
+*/\r
+Slapi_PBlock *\r
+slapi_modify_internal(\r
+       char *ldn,      \r
+       LDAPMod **mods, \r
+       LDAPControl **controls, \r
+       int log_change )\r
+{\r
+#if defined(LDAP_SLAPI)\r
+       int                     i, rc = LDAP_SUCCESS;\r
+       Connection              *pConn = NULL;\r
+       Operation               *op = NULL;\r
+       Slapi_PBlock            *pPB = NULL;\r
+       Slapi_PBlock            *pSavePB = NULL;\r
+\r
+       struct berval dn = { 0, NULL };\r
+       struct berval pdn = { 0, NULL };\r
+       struct berval ndn = { 0, NULL };\r
+\r
+       int                     manageDsaIt = 0;\r
+       int                     isCritical;\r
+       Backend                 *be;\r
+       struct berval           *bv;\r
+       struct berval           **ppBV;\r
+       LDAPMod                 *pMod;\r
+\r
+       Modifications           *modlist = NULL;\r
+       Modifications           **modtail = &modlist;\r
+       Modifications           tmp;\r
+\r
+       if ( mods == NULL || *mods == NULL || ldn == NULL ) {\r
+               rc = LDAP_OPERATIONS_ERROR ;\r
+               goto cleanup;\r
+       }\r
+\r
+       pConn = fakeConnection( NULL,  LDAP_REQ_MODIFY );\r
+       if ( pConn == NULL ) {\r
+               rc = LDAP_NO_MEMORY;\r
+               goto cleanup;\r
+       }\r
+\r
+       op = (Operation *)pConn->c_pending_ops.stqh_first;\r
+       pPB = (Slapi_PBlock *)op->o_pb;\r
+       op->o_ctrls = controls;\r
+\r
+       dn.bv_val = slapi_ch_strdup( ldn );\r
+       dn.bv_len = slapi_strlen( ldn );\r
+       rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
+       if ( rc != LDAP_SUCCESS ) goto cleanup;\r
+\r
+       if ( slapi_control_present( controls, \r
+                       SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {\r
+               manageDsaIt = 1;\r
+       }\r
+\r
+       be = select_backend( &dn, manageDsaIt, 0 );\r
+       if ( be == NULL ) {\r
+               rc =  LDAP_PARTIAL_RESULTS;\r
+               goto cleanup;\r
+       }\r
+\r
+       op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
+       op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
+       pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
+       pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
+\r
+       suffix_alias( be, &ndn );\r
+\r
+       for ( i = 0, pMod = mods[0]; rc == LDAP_SUCCESS && pMod != NULL; \r
+                       pMod = mods[++i] ) {\r
+               Modifications *mod;\r
+               if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {\r
+                       /*\r
+                        * attr values are in berval format\r
+                        * convert an array of pointers to bervals\r
+                        * to an array of bervals\r
+                        */\r
+                       rc = bvptr2obj( pMod->mod_bvalues, &bv );\r
+                       if ( rc != LDAP_SUCCESS ) goto cleanup;\r
+                       tmp.sml_type.bv_val = slapi_ch_strdup( pMod->mod_type );\r
+                       tmp.sml_type.bv_len = slapi_ch_stlen( pMod->mod_type );\r
+                       tmp.sml_bvalues = bv;\r
+\r
+                       mod  = (Modifications *)ch_malloc( sizeof(Modifications) );\r
+\r
+                       mod->sml_op = pMod->mod_op;\r
+                       mod->sml_next = NULL;\r
+                       mod->sml_desc = NULL;\r
+                       mod->sml_type = tmp.sml_type;\r
+                       mod->sml_bvalues = tmp.sml_bvalues;\r
+               } else { \r
+                       rc = ValuesToBValues( pMod->mod_values, &ppBV );\r
+                       if ( rc != LDAP_SUCCESS ) goto cleanup;\r
+                       rc = bvptr2obj( ppBV, &bv );\r
+                       if ( rc != LDAP_SUCCESS ) goto cleanup;\r
+                       tmp.sml_type.bv_val = slapi_ch_strdup( pMod->mod_type );\r
+                       tmp.sml_type.bv_len = slapi_ch_stlen( pMod->mod_type );\r
+                       tmp.sml_bvalues = bv;\r
+\r
+                       mod  = (Modifications *) ch_malloc( sizeof(Modifications) );\r
+\r
+                       mod->sml_op = pMod->mod_op;\r
+                       mod->sml_next = NULL;\r
+                       mod->sml_desc = NULL;\r
+                       mod->sml_type = tmp.sml_type;\r
+                       mod->sml_bvalues = tmp.sml_bvalues;\r
+\r
+                       if ( ppBV != NULL ) {\r
+                               ber_bvecfree( ppBV );\r
+                       }\r
+               }\r
+               *modtail = mod;\r
+               modtail = &mod->sml_next;\r
+\r
+               switch( pMod->mod_op ) {\r
+               case LDAP_MOD_ADD:\r
+               if ( mod->sml_bvalues == NULL ) {\r
+                       rc = LDAP_PROTOCOL_ERROR;\r
+                       goto cleanup;\r
+               }\r
+\r
+               /* fall through */\r
+               case LDAP_MOD_DELETE:\r
+               case LDAP_MOD_REPLACE:\r
+               break;\r
+\r
+               default:\r
+                       rc = LDAP_PROTOCOL_ERROR;\r
+                       goto cleanup;\r
+               }\r
+       } \r
+       *modtail = NULL;\r
+\r
+       if ( ndn.bv_len == 0 ) {\r
+               rc = LDAP_UNWILLING_TO_PERFORM;\r
+               goto cleanup;\r
+       }\r
+\r
+       if ( be->be_modify ) {\r
+               int repl_user = be_isupdate( be, &op->o_ndn );\r
+               if ( !be->be_update_ndn.bv_len || repl_user ) {\r
+                       int update = be->be_update_ndn.bv_len;\r
+                       const char *text = NULL;\r
+                       char textbuf[SLAP_TEXT_BUFLEN];\r
+                       size_t textlen = sizeof( textbuf );\r
+\r
+                       rc = slap_mods_check( modlist, update,\r
+                                       &text, textbuf, textlen );\r
+                       if (rc != LDAP_SUCCESS) {\r
+                               goto cleanup;\r
+                       }\r
+\r
+                       if ( !repl_user ) {\r
+                               rc = slap_mods_opattrs( be, op, modlist,\r
+                                               modtail, &text, textbuf, \r
+                                               textlen );\r
+                               if (rc != LDAP_SUCCESS) {\r
+                                       goto cleanup;\r
+                               }\r
+                       }\r
+                       rc = (*be->be_modify)( be, pConn, op,\r
+                                       &pdn, &ndn, modlist );\r
+                       if ( rc == 0 ) {\r
+                               if ( log_change ) {\r
+                                       replog( be, op, &pdn, &ndn, modlist );\r
+                               }\r
+                               rc = LDAP_SUCCESS;\r
+                       } else {\r
+                               rc = LDAP_OPERATIONS_ERROR;\r
+                       }\r
+               } else {\r
+                       rc = LDAP_REFERRAL;\r
+               }\r
+       } else {\r
+               rc = LDAP_UNWILLING_TO_PERFORM;\r
+       }\r
+\r
+cleanup:\r
+\r
+       if ( pPB != NULL ) \r
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
+\r
+       if ( dn.bv_val ) ch_free( dn.bv_val );\r
+       if ( pdn.bv_val ) ch_free( pdn.bv_val );\r
+       if ( ndn.bv_val ) ch_free( ndn.bv_val );\r
+\r
+       if ( modlist != NULL ) slap_mods_free( modlist );\r
+\r
+       if ( pConn != NULL ) {\r
+               if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val );\r
+               if ( op ) {\r
+                       if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val );\r
+                       slapi_ch_free( op );\r
+               }\r
+               pSavePB = pPB;\r
+               free( pConn );\r
+       }\r
+\r
+       return ( pSavePB );\r
+\r
+#endif /* LDAP_SLAPI */\r
+       return NULL;\r
+}\r
+\r
+Slapi_PBlock *\r
+slapi_search_internal_bind(\r
+       char *bindDN, \r
+       char *ldn, \r
+       int scope, \r
+       char *filStr, \r
+       LDAPControl **controls, \r
+       char **attrs, \r
+       int attrsonly ) \r
+{      \r
+#if defined(LDAP_SLAPI)\r
+       Backend                 *be;\r
+       Connection              *c;\r
+       Operation               *op = NULL;\r
+       Slapi_PBlock            *ptr = NULL;            \r
+       Slapi_PBlock            *pSavePB = NULL;                \r
+       struct berval           dn = { 0, NULL };\r
+       struct berval           pdn = { 0, NULL };\r
+       struct berval           ndn = { 0, NULL };\r
+       Filter                  *filter=NULL;\r
+       struct berval           fstr = { 0, NULL };\r
+       AttributeName           *an = NULL;\r
+       const char              *text = NULL;\r
+\r
+       int                     deref=0;\r
+       int                     sizelimit=-1, timelimit=-1;\r
+\r
+       int                     manageDsaIt = 0; \r
+       int                     isCritical;\r
+\r
+       int                     i, rc = LDAP_SUCCESS;\r
+       \r
+       c = fakeConnection( NULL, LDAP_REQ_SEARCH );\r
+       if (c == NULL) {\r
+               rc = LDAP_NO_MEMORY;\r
+               goto cleanup;\r
+       }\r
+\r
+       op = (Operation *)c->c_pending_ops.stqh_first;\r
+       ptr = (Slapi_PBlock *)op->o_pb;\r
+       op->o_ctrls = controls;\r
+\r
+       dn.bv_val = slapi_ch_strdup(ldn);\r
+       dn.bv_len = slapi_strlen(ldn);\r
+\r
+       rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
+       if (rc != LDAP_SUCCESS) goto cleanup;\r
+\r
+       if ( scope != LDAP_SCOPE_BASE && \r
+                       scope != LDAP_SCOPE_ONELEVEL && \r
+                       scope != LDAP_SCOPE_SUBTREE ) {\r
+               rc = LDAP_PROTOCOL_ERROR;\r
+               goto cleanup;\r
+       }\r
+\r
+       filter = slapi_str2filter(filStr);\r
+       if ( filter == NULL ) {\r
+               rc = LDAP_PROTOCOL_ERROR;\r
+               goto cleanup;\r
+       }\r
+\r
+       filter2bv( filter, &fstr );\r
+\r
+       for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {\r
+               ; /* count the number of attributes */\r
+       }\r
+\r
+       if (i > 0) {\r
+               an = (AttributeName *)slapi_ch_calloc(1, sizeof(AttributeName));\r
+               for (i = 0; attrs[i] != 0; i++) {\r
+                       an[i].an_desc = NULL;\r
+                       an[i].an_oc = NULL;\r
+                       an[i].an_name.bv_val = slapi_ch_strdup(attrs[i]);\r
+                       an[i].an_name.bv_len = slapi_strlen(attrs[i]);\r
+                       slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text );\r
+               }\r
+       }\r
+\r
+       if ( scope == LDAP_SCOPE_BASE ) {\r
+               Entry *entry = NULL;\r
+\r
+               if ( ndn.bv_len == 0 ) {\r
+                       rc = root_dse_info( c, &entry, &text );\r
+               }\r
+\r
+               if( rc != LDAP_SUCCESS ) {\r
+                       send_ldap_result( c, op, rc, NULL, text, NULL, NULL );\r
+                       goto cleanup;\r
+               } else if ( entry != NULL ) {\r
+                       rc = test_filter( NULL, c, op, entry, filter );\r
+\r
+                       if( rc == LDAP_COMPARE_TRUE ) {\r
+                               send_search_entry( NULL, c, op, entry,\r
+                                               an, attrsonly, NULL );\r
+                       }\r
+\r
+                       entry_free( entry );\r
+\r
+                       send_ldap_result( c, op, LDAP_SUCCESS, \r
+                                       NULL, NULL, NULL, NULL );\r
+\r
+                       rc = LDAP_SUCCESS;\r
+\r
+                       goto cleanup;\r
+               }\r
+       }\r
+\r
+       if ( !ndn.bv_len && default_search_nbase.bv_len ) {\r
+               ch_free( pdn.bv_val );\r
+               ch_free( ndn.bv_val );\r
+\r
+               ber_dupbv( &pdn, &default_search_base );\r
+               ber_dupbv( &ndn, &default_search_nbase );\r
+       }\r
+\r
+       if ( slapi_control_present( controls,\r
+                       LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {\r
+               manageDsaIt = 1;\r
+       }\r
+\r
+       be = select_backend( &dn, manageDsaIt, 0 );\r
+       if ( be == NULL ) {\r
+               if ( manageDsaIt == 1 ) {\r
+                       rc = LDAP_NO_SUCH_OBJECT;\r
+               } else {\r
+                       rc = LDAP_PARTIAL_RESULTS;\r
+               }\r
+               goto cleanup;\r
+       } \r
+\r
+       op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
+       op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
+       c->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
+       c->c_dn.bv_len = be->be_rootdn.bv_len;\r
+\r
+       if ( be->be_search ) {\r
+               rc = (*be->be_search)( be, c, op, &pdn, &ndn,\r
+                       scope, deref, sizelimit, timelimit,\r
+                       filter, &fstr, an, attrsonly );\r
+               if ( rc == 0 ) {\r
+                       rc = LDAP_SUCCESS;\r
+               } else {\r
+                       rc = LDAP_OPERATIONS_ERROR;\r
+               }\r
+       } else {\r
+               rc = LDAP_UNWILLING_TO_PERFORM;\r
+       }\r
+\r
+cleanup:\r
+\r
+       if ( ptr != NULL )\r
+               slapi_pblock_set( ptr, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
+\r
+       if ( dn.bv_val ) free( dn.bv_val );\r
+       if ( ndn.bv_val ) free( ndn.bv_val );\r
+       if ( pdn.bv_val ) free( pdn.bv_val );\r
+\r
+       if ( filter ) slapi_filter_free( filter, 1 );\r
+       if ( fstr.bv_val ) free ( fstr.bv_val );\r
+\r
+       if ( an != NULL ) free( an );\r
+\r
+       if ( c != NULL ) {\r
+               if ( c->c_dn.bv_val ) slapi_ch_free( c->c_dn.bv_val );\r
+               if ( op ) {\r
+                       if ( op->o_ndn.bv_val ) slapi_ch_free( op->o_ndn.bv_val );\r
+                       free( op );\r
+               }\r
+               pSavePB = ptr;\r
+               free( c );\r
+       }\r
+       return( pSavePB );\r
+#endif /* LDAP_SLAPI */\r
+       return NULL;\r
+}\r
+\r
+Slapi_PBlock * \r
+slapi_search_internal(\r
+       char *base,\r
+       int scope,\r
+       char *filStr, \r
+       LDAPControl **controls,\r
+       char **attrs,\r
+       int attrsonly ) \r
+{\r
+#if defined(LDAP_SLAPI)\r
+       return slapi_search_internal_bind( NULL, base, scope, filStr,\r
+                       controls, attrs, attrsonly );\r
+#endif\r
+       return NULL;\r
+}\r
+\r
diff --git a/servers/slapd/slapi/slapi_ops.c.all b/servers/slapd/slapi/slapi_ops.c.all
new file mode 100644 (file)
index 0000000..dcf1682
--- /dev/null
@@ -0,0 +1,1303 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is
+ * given to IBM Corporation. This software is provided ``as is''
+ * without express or implied warranty.
+ */
+
+#include "portable.h"
+#include "slapi_common.h"
+#include <slap.h>
+#include <slapi.h>
+#include <lber.h>
+#include "../../../libraries/liblber/lber-int.h"
+
+int
+bvptr2obj(     struct berval **bvptr, 
+                       struct berval **bvobj);
+
+Slapi_PBlock *
+slapi_simple_bind_internal( char *dn, 
+                                                       struct berval *cred,            
+                                                       int method, 
+                                                       int version);
+
+
+Connection *
+fakeConnection(        char *DN, 
+                               int OpType) 
+{ 
+       Connection *pConn, *c;
+
+       if((pConn = (Connection *) slapi_ch_calloc(sizeof(Connection))) == NULL)
+               return (Connection *)NULL;
+
+       LDAP_STAILQ_INIT(&c->c_pending_ops);
+       LDAP_STAILQ_INIT(&c->c_ops);
+
+       if((pConn->c_pending_ops.stqh_first=(Operation *) slapi_ch_calloc(sizeof(Operation))) == NULL) { 
+               slapi_ch_free( pConn );
+               return (Connection *)NULL;
+       }
+
+       if((pConn->c_pending_ops.stqh_first->o_pb=(Slapi_PBlock *) slapi_pblock_new()) == NULL) {
+               slapi_ch_free( pConn->c_pending_ops.stqh_first );
+               slapi_ch_free( pConn );
+               return (Connection *)NULL;
+       }
+
+       c = pConn;
+
+       c->c_ops->o_opid = 0;
+       c->c_ops->o_msgid = 0;
+       c->c_ops->o_next = NULL;
+       c->c_ops->o_tag = OpType;
+       i->c_ops->o_abandon = 0;
+
+       c->c_authmech.bv_val = NULL;
+       c->c_authmech.bv_len = 0;
+       c->c_dn.bv_val = NULL;
+       c->c_dn.bv_len = 0;
+       c->c_ndn.bv_val = NULL;
+       c->c_ndn.bv_len = 0;
+       c->c_cdn.bv_val = NULL;
+       c->c_cdn.bv_len = 0;
+       c->c_groups = NULL;
+
+       c->c_listener_url.bv_val = NULL;
+       c->c_listener_url.bv_len = 0;
+       c->c_peer_domain.bv_val = NULL;
+       c->c_peer_domain.bv_len = 0;
+       c->c_peer_name.bv_val = NULL;
+       c->c_peer_name.bv_len = 0;
+       c->c_sock_name.bv_val = NULL;
+       c->c_sock_name.bv_len = 0;
+
+       c->c_sasl_bind_mech.bv_val = NULL;
+       c->c_sasl_bind_mech.bv_len = 0;
+       c->c_sasl_context = NULL;
+       c->c_sasl_extra = NULL;
+
+       c->c_sb = ber_sockbuf_alloc( );
+
+       c->c_currentber = NULL;
+
+       c->c_struct_state = SLAP_C_UNUSED;
+
+       c->c_n_get = 0;
+       c->c_n_read = 0;
+       c->c_n_write = 0;
+
+       c->c_protocol = LDAP_VERSION3; 
+
+       time(&pConn->c_pending_ops.stqh_first->o_time);
+
+       pConn->c_send_ldap_result_v3 = (SEND_LDAP_RESULT_V3) internal_result_v3;
+       pConn->c_send_search_entry = (SEND_SEARCH_ENTRY) internal_search_entry;
+       pConn->c_send_ldap_search_result = (SEND_LDAP_SEARCH_RESULT) internal_search_result;
+       pConn->c_send_ldap_result_ext = (SEND_LDAP_RESULT_EXT) internal_result_ext;
+       pConn->c_send_ldap_search_reference = (SEND_SEARCH_REFERENCE) internal_search_reference;
+
+       return pConn;
+}
+
+
+/* Function : slapi_delete_internal
+ *
+ * Description : Plugin functions call this routine to delete an entry 
+ *               in the backend directly
+ * Return values : LDAP_SUCCESS
+ *                 LDAP_OPERAITONS_ERROR
+ *                 LDAP_NO_MEMORY
+ *                 LDAP_OTHER
+ *                 LDAP_UNWILLING_TO_PERFORM
+*/
+Slapi_PBlock *
+slapi_delete_internal( char *ldn, 
+                                               LDAPControl **controls, 
+                                               int log_change)
+{
+
+       int                             rc=LDAP_SUCCESS;
+       Backend                 *be;
+       Slapi_PBlock    *pPB=NULL;
+       Slapi_PBlock    *pSavePB=NULL;
+       Connection              *pConn=NULL;
+       Operation               *op;
+
+       int                             manageDsaIt = 0;
+    int                                isCritical;
+
+       struct berval dn  = { 0, NULL };
+       struct berval pdn = { 0, NULL };
+       struct berval ndn = { 0, NULL };
+
+
+       if ( ldn == NULL ) {
+               rc = LDAP_OPERATIONS_ERROR; 
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               pConn = fakeConnection( NULL,  LDAP_REQ_DELETE );
+       }
+
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               op = (Operation *)pConn->c_pending_ops.stqh_first;
+               op->o_ctrls = controls;
+
+               op->o_ndn.bv_val = slapi_strdup(be->be_update_ndn.bv_val);
+               op->o_ndn.bv_len = be->be_update_ndn.bv_len;
+               pConn->c_dn.bv_val = slapi_strdup(be->be_update_ndn.bv_val);
+               pConn->c_dn.bv_len = be->be_update_ndn.bv_len;
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               dn.bv_val = slapi_strdup(ldn);
+               dn.bv_len = slapi_strlen(ldn);
+
+               rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
+
+               if( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
+                               "do_delete: conn %d  invalid dn (%s)\n",
+                               conn->c_connid, dn.bv_val ));
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                               "do_delete: invalid dn (%s)\n", dn.bv_val, 0, 0 );
+#endif
+               }
+       }
+
+       if( ndn.bv_len == 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
+                       "Attempt to delete root DSE.\n", conn->c_connid ));
+#else
+               Debug( LDAP_DEBUG_ANY, "Attempt to delete root DSE.\n", 0, 0, 0 );
+#endif
+               rc = LDAP_UNWILLING_TO_PERFORM;
+
+#ifdef SLAPD_SCHEMA_DN
+
+       } else if ( strcasecmp( ndn.bv_val, SLAPD_SCHEMA_DN ) == 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
+                               "Attempt to delete subschema subentry.\n", conn->c_connid ));
+#else
+               Debug( LDAP_DEBUG_ANY, "Attempt to delete subschema subentry.\n", 0, 0, 0 );
+#endif
+               rc = LDAP_UNWILLING_TO_PERFORM;
+
+#endif
+       }
+
+       if ( rc = slapi_control_present( controls, LDAP_MANAGEDSAIT_OID, NULL, &isCritical)){
+               manageDsaIt = 1; /* turn off referral */
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               be = select_backend(&bv, manageDsaIt, 0);
+               if ( be == NULL ) rc =  LDAP_PARTIAL_RESULTS;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
+       }
+
+       suffix_alias( be, &ndn );
+
+       if ( be->be_delete ) {
+               /* do the update here */
+               int repl_user = be_isupdate( be, &op->o_ndn );
+#ifndef SLAPD_MULTIMASTER
+               if ( !be->be_update_ndn.bv_len || repl_user )
+#endif
+               {
+                       if ( (*be->be_delete)( be, conn, op, &pdn, &ndn ) == 0 ) {
+#ifdef SLAPD_MULTIMASTER
+                               if ( !be->be_update_ndn.bv_len || !repl_user )
+#endif
+                               {
+                                       if (log_change) replog( be, op, &pdn, &ndn, NULL );
+                }
+            }
+#ifndef SLAPD_MULTIMASTER
+        } else {
+                       rc = LDAP_REFERRAL;
+#endif
+        }
+       } else {
+               rc = LDAP_UNWILLING_TO_PERFORM;
+       }
+
+       if ( pPB != NULL ) { 
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+       }
+       if ( pConn != NULL ) {
+               if ( pConn->c_dn.bv_val )
+                       slapi_ch_free( pConn->c_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first );
+               if (dn.bv_val)
+                       slapi_ch_free(dn.bv_val);
+               if (pdn.bv_val)
+                       slapi_ch_free(pdn.bv_val);
+               if (ndn.bv_val)
+                       slapi_ch_free(ndn_bv.val);
+               pSavePB = pPB;
+               free( pConn );
+       }
+       return( pSavePB );
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+int
+internal_result_v3( Connection *conn, 
+                                       Operation *op, 
+                                       int err,
+                                       char *matched, 
+                                       char *text, 
+                                       char **referrals) 
+{
+       return LDAP_SUCCESS;
+}
+
+int
+internal_result_ext(   Connection *conn, 
+                                               Operation *op, 
+                                               int  errnum, 
+                                               char *respname, 
+                                               struct berval *response ) 
+{
+       return LDAP_SUCCESS;
+}
+
+int
+internal_search_reference(     Connection *conn, 
+                                                       Operation *op, 
+                                                       char **ref) 
+{
+       return LDAP_SUCCESS;
+}
+
+int
+internal_search_result(        Connection *conn, 
+                                               Operation *op,
+                                               int err, 
+                                               char *matched, 
+                                               char *text, 
+                                               int nentries) 
+{
+       slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_NENTRIES,(void *)nentries);
+       return LDAP_SUCCESS;
+}
+
+
+int
+internal_search_entry( Backend *be, 
+                                               Connection *conn, 
+                                               Operation *op, 
+                                               Entry *e, 
+                                       char **attrs, 
+                                               int attrsonly, 
+                                               char **denied_attrs) 
+{
+       char *ent2str = NULL;
+       int nentries = 0, len = 0, i = 0;
+       Slapi_Entry **head = NULL, **tp;
+       
+       if((ent2str=slapi_entry2str(e,&len)) == NULL) {
+               return SLAPD_NO_MEMORY;
+       }
+
+       slapi_pblock_get((Slapi_PBlock *)op->o_pb, SLAPI_NENTRIES, &nentries);
+       slapi_pblock_get((Slapi_PBlock *)op->o_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head);
+       i=nentries + 1;
+       if(nentries == 0 ) {
+               if((tp=(Slapi_Entry **)slapi_ch_malloc(2 * sizeof(Slapi_Entry *))) == NULL) {
+                       return SLAPD_NO_MEMORY;
+               }
+               if((tp[0]=(Slapi_Entry *)str2entry(ent2str)) == NULL) { 
+                       return SLAPD_NO_MEMORY;
+               }
+       } else {
+               if((tp=(Slapi_Entry **)slapi_ch_realloc((char *)head,
+                                                       (sizeof(Slapi_Entry *) * (i+1)))) == NULL) {
+                       return SLAPD_NO_MEMORY;
+               }
+               if((tp[i-1]=(Slapi_Entry *)str2entry(ent2str)) == NULL) { 
+                       return SLAPD_NO_MEMORY;
+               }
+       }
+       tp[i] = NULL;  
+              
+       slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,(void *)tp);
+       slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_NENTRIES,(void *)i);
+       slapi_ch_free(ent2str);
+       return LDAP_SUCCESS;
+}
+
+
+/* 
+ * Function : freeModList 
+ * Free a list of LDAPMod structures which has the bvalue defined.
+*/
+static void 
+freeModList(   LDAPMod *pMod )
+{
+       LDAPMod *pNextMod;
+
+       while ( pMod != NULL ) {
+               pNextMod = pMod->mod_next;
+               free( pMod->mod_type );
+               ber_bvecfree( pMod->mod_bvalues );
+               free( pMod );
+               pMod = pNextMod;
+       }
+}
+
+
+/*
+ * Function : duplicateBVMod 
+ * Duplicate a LDAPMod structure in which the bervals are defined. 
+ * return code : LDAP_SUCEESS, 
+ *                              LDAP_OTHER, 
+ *                              LDAP_NO_MEMORY
+ */
+
+int 
+duplicateBVMod(        LDAPMod *pMod, 
+                               LDAPMod **ppNewMod )
+{
+       int rc = LDAP_SUCCESS;
+       int i;
+       struct berval **ppNewBV;
+       struct berval *pNewBV;
+
+       if ( pMod == NULL ) {
+               rc = LDAP_OTHER;
+       } else {
+               *ppNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
+               if ( *ppNewMod == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+               } else {
+                       memset( (*ppNewMod),'\0',sizeof(LDAPMod) );
+                       (*ppNewMod)->mod_op = pMod->mod_op;
+                       (*ppNewMod)->mod_type = slapi_ch_strdup( pMod->mod_type);
+                       if ( (*ppNewMod)->mod_type == NULL) {
+                               rc = LDAP_NO_MEMORY;
+                       } else {
+                               if ( pMod->mod_bvalues == NULL ) {
+                                       (*ppNewMod)->mod_values = NULL; 
+                               } else {
+                                       for ( i=0; pMod->mod_bvalues[i] != NULL; i++ ) {
+                                               ;
+                                       }
+                                       ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*sizeof(struct berval *));
+                                       if ( ppNewBV == NULL ) {
+                                               rc = LDAP_NO_MEMORY;
+                                       } else {
+                                               for ( i=0; pMod->mod_bvalues[i] != NULL &&
+                                                                                       rc == LDAP_SUCCESS; i++ ) {
+                                                       pNewBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+                                                       if ( pNewBV == NULL ) {
+                                                               rc = LDAP_NO_MEMORY;
+                                                       } else {
+                                                               pNewBV->bv_val = slapi_ch_malloc(pMod->mod_bvalues[i]->bv_len+1);
+                                                               if ( pNewBV->bv_val == NULL ) {
+                                                                       rc = LDAP_NO_MEMORY;
+                                                               } else {
+                                                                       memset(pNewBV->bv_val,'\0',pMod->mod_bvalues[i]->bv_len+1);
+                                                                       pNewBV->bv_len = pMod->mod_bvalues[i]->bv_len;
+                                                                       memcpy(pNewBV->bv_val,pMod->mod_bvalues[i]->bv_val,pNewBV->bv_len);
+                                                                       ppNewBV[i] = pNewBV;
+                                                               }
+                                                       }
+                                               } /* for each bvalue */
+                                               if ( rc == LDAP_SUCCESS ) {
+                                                       ppNewBV[i] = NULL;
+                                                       (*ppNewMod)->mod_bvalues = ppNewBV;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       return( rc );
+}
+
+/* 
+ * Function : ValuestoBValues 
+ * Convert an array of char ptrs to an array of berval ptrs.
+ * return value : LDAP_SUCCESS
+ *                LDAP_NO_MEMORY
+ *                LDAP_OTHER
+*/
+static int 
+ValuesToBValues(       char **ppValue, 
+                                       struct berval ***pppBV )
+{
+       int  rc = LDAP_SUCCESS;
+       int  i;
+       struct berval *pTmpBV;
+       struct berval **ppNewBV;
+
+       /* count the number of char ptrs. */
+       for ( i=0; ppValue != NULL && ppValue[i] != NULL; i++ ) {
+               ;       /* NULL */
+       }
+
+       if ( i == 0 ) {
+               rc = LDAP_OTHER;
+       } else {
+               *pppBV = ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*(sizeof(struct berval *)) );
+               if ( *pppBV == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+               } else {
+                       while ( ppValue != NULL && *ppValue != NULL && rc == LDAP_SUCCESS ) {
+                               pTmpBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+                               if ( pTmpBV == NULL) {
+                                       rc = LDAP_NO_MEMORY;
+                               } else {
+                                       pTmpBV->bv_val = slapi_ch_strdup(*ppValue);
+                                       if ( pTmpBV->bv_val == NULL ) {
+                                               rc = LDAP_NO_MEMORY;
+                                       } else {
+                                               pTmpBV->bv_len = strlen(*ppValue);
+                                               *ppNewBV = pTmpBV;
+                                               ppNewBV++;
+                                       }
+                                       ppValue++;
+                               }
+                       }
+                       /* null terminate the array of berval ptrs */
+                       *ppNewBV = NULL;
+               }
+       }
+       return( rc );
+}
+
+
+/*
+ * Function : LDAPModToEntry 
+ * convert a dn plus an array of LDAPMod struct ptrs to an entry structure
+ * with a link list of the correspondent attributes.
+ * Return value : LDAP_SUCCESS
+ *                LDAP_NO_MEMORY
+ *                LDAP_OTHER
+*/
+Entry *
+LDAPModToEntry(        char *ldn, 
+                               LDAPMod **mods )
+{
+       int                             rc=LDAP_SUCCESS;
+       LDAPMod                 *pMod;
+       Entry                   *pEntry=NULL;
+       int                             i,j;
+       struct berval   **ppSaveBV;
+       struct berval   **ppBV;
+       struct berval   *pTmpBV;
+       char                    **ppValue;
+
+
+       AttributeDescription *ad;
+       struct berval *bv;
+       const char *text;
+
+    Modifications   *modlist = NULL;
+    Modifications   **modtail = &modlist;
+    Modifications   tmp;
+
+       struct berval dn = { 0, NULL };
+
+       dn.ber_val = slapi_ch_strdup(ldn);
+       dn.ber_len = slapi_ch_strlen(ldn);
+
+       pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
+       if ( pEntry == NULL) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
+               if( rc != LDAP_SUCCESS ) { 
+#ifdef NEW_LOGGING
+                       LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
+                               "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val ));
+#else
+                       Debug( LDAP_DEBUG_ANY, "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val, 0, 0 ); 
+#endif
+                       rc = LDAP_INVALID_DN_SYNTAX;
+               }
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
+                       Modifications *mod;
+                       if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
+                               /* attr values are in berval format */
+                               /* convert an array of pointers to bervals to an array of bervals */
+                               rc = bvptr2obj(pMod->mod_bvalues, &bv);
+                               if (rc != LDAP_SUCCESS) break;
+                               tmp.sml_type = pMod->mod_type;
+                               tmp.sml_bvalues = bv;
+               
+                               mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
+
+                               mod->sml_op = LDAP_MOD_ADD;
+                               mod->sml_next = NULL;
+                               mod->sml_desc = NULL;
+                               mod->sml_type = tmp.sml_type;
+                               mod->sml_bvalues = tmp.sml_bvalues;
+
+                               *modtail = mod;
+                               modtail = &mod->sml_next;
+
+                       } else {
+               /* attr values are in string format, need to be converted */
+                               /* to an array of bervals */ 
+                               if ( pMod->mod_values == NULL ) {
+                                       rc = LDAP_OTHER;
+                               } else {
+                                       rc = ValuesToBValues( pMod->mod_values, &ppBV );
+                                       if (rc != LDAP_SUCCESS) break;
+                                       rc = bvptr2obj(ppBV, &bv);
+                                       if (rc != LDAP_SUCCESS) break;
+                                       tmp.sml_type = pMod->mod_type;
+                                       tmp.sml_bvalues = bv;
+               
+                                       mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
+
+                                       mod->sml_op = LDAP_MOD_ADD;
+                                       mod->sml_next = NULL;
+                                       mod->sml_desc = NULL;
+                                       mod->sml_type = tmp.sml_type;
+                                       mod->sml_bvalues = tmp.sml_bvalues;
+
+                                       *modtail = mod;
+                                       modtail = &mod->sml_next;
+
+
+                                       if ( ppBV != NULL ) {
+                                               ber_bvecfree( ppBV );
+                                       }
+                               }
+                       }
+               } /* for each LDAPMod */
+       }
+
+    if( e->e_nname.bv_len == 0 ) 
+               rc = LDAP_ALREADY_EXISTS;
+
+       /* check if ManageDsaIt control is set  */
+       if ( rc = slapi_control_present( controls, LDAP_MANAGEDSAIT_OID, NULL, &isCritical)){
+               manageDsaIt = 1; /* turn off referral */
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               be = select_backend(&bv, manageDsaIt, 0);
+               if ( be == NULL ) rc =  LDAP_PARTIAL_RESULTS;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
+       }
+
+
+       if ( rc != LDAP_SUCCESS ) {
+               if ( pEntry != NULL ) {
+                       slapi_entry_free( pEntry );
+               }
+               pEntry = NULL;
+       }
+    return( pEntry );
+}
+
+/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
+
+Slapi_PBlock * 
+slapi_add_entry_internal(      Slapi_Entry *e, 
+                                                       LDAPControl **controls, 
+                                                       int log_changes) 
+{
+       int                             rc=LDAP_SUCCESS, i;
+       Backend                 *be;
+       Connection              *pConn=NULL;
+       Operation               *op;
+       Slapi_PBlock    *pPB=NULL, *pSavePB=NULL;
+       char                    *pDn=NULL;
+       int                             manageDsaIt = 0; /* referral is on */
+       int                             isCritical;
+       struct berval   bv;
+       
+       /* check if ManageDsaIt control is set  */
+       if (slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical)) {
+                manageDsaIt = 1; /* turn off referral */
+       }
+
+       pConn = fakeConnection(NULL, LDAP_REQ_ADD);
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else { 
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               if (e == NULL) {
+                       rc =  LDAP_OPERATIONS_ERROR;
+               } else {
+                       if ( rc == LDAP_SUCCESS ) {
+                               be = select_backend(&e->e_nname, manageDsaIt, 0);
+                               if ( be == NULL ) {
+                                       rc = LDAP_PARTIAL_RESULTS;
+                               } else if ( be->be_add == NULL) { 
+                                       rc = LDAP_UNWILLING_TO_PERFORM;
+                               } else {
+                                       op = (Operation *)pConn->c_pending_ops.stqh_first;
+                                       op->o_ctrls = controls;
+                                       rc = (*be->be_add)( be, pConn, op, e );
+                                       if (rc == LDAP_SUCCESS)
+                                               Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
+                                       else
+                                               Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
+                               }
+                       }
+               }
+       }
+       if ( pPB != NULL ) 
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );   
+       if ( pDn != NULL )
+               slapi_ch_free( pDn );
+       if (bv.bv_val != NULL)
+               slapi_ch_free(bv.bv_val);
+       if ( pConn != NULL ) {
+               if ( pConn->c_dn.bv_val ) 
+                       slapi_ch_free( pConn->c_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first);
+               if (pConn->c_original_dn)
+                       slapi_ch_free(pConn->c_original_dn); 
+               pSavePB = pPB;
+               free( pConn );
+       }
+       return( pSavePB );
+}
+
+
+
+Slapi_PBlock *
+slapi_add_internal(    char *dn, 
+                                       LDAPMod **mods, 
+                                       LDAPControl **controls, 
+                                       int log_changes  ) 
+{
+       LDAPMod                 *pMod=NULL;
+       Slapi_PBlock    *pb=NULL;
+       Entry                   *pEntry=NULL;
+       int                             i, rc=LDAP_SUCCESS;
+
+
+       if(mods == NULL || *mods == NULL || dn == NULL || *dn == NULL) 
+               rc = LDAP_OPERATIONS_ERROR ;
+
+       if (rc == LDAP_SUCCESS) {
+               for (i=0, pMod=mods[0]; pMod != NULL; pMod=mods[++i] ) {
+                       if ((pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD) {
+                               rc = LDAP_OTHER;
+                               break;
+                       }
+               }
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
+                       rc = LDAP_OTHER;
+               }
+       }
+
+       if(rc != LDAP_SUCCESS) {
+               pb = slapi_pblock_new();
+               slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+       } else {
+               pb = slapi_add_entry_internal(pEntry, controls, log_changes);
+       }
+
+       if(pEntry) 
+               slapi_entry_free(pEntry);
+
+       return(pb);
+}
+
+
+/*dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd*/
+/* Function : slapi_modify_internal
+ *
+ * Description : Plugin functions call this routine to modify an entry in the backend directly
+ * Return values : LDAP_SUCCESS
+ *                 LDAP_OPERAITONS_ERROR
+ *                 LDAP_NO_MEMORY
+ *                 LDAP_OTHER
+ *                 LDAP_UNWILLING_TO_PERFORM
+*/
+Slapi_PBlock *
+slapi_modify_internal( char *dn, LDAPMod **mods, LDAPControl **controls, int log_change)
+{
+       int                             rc=LDAP_SUCCESS;
+       int                             i;
+       int                             dnBadChar;
+       LDAPMod                 *pMod;
+       LDAPMod                 *pNewMod;
+       LDAPMod                 *pTmpMod;
+       LDAPMod                 *pSaveMod;
+       LDAPMod                 *pModList=NULL;
+       Backend                 *be;
+       Slapi_PBlock    *pPB=NULL;
+       Slapi_PBlock    *pSavePB=NULL;
+       Connection              *pConn=NULL;
+
+       int                             manageDsaIt = 0;
+       int                             isCritical;
+       struct berval   bv;
+       struct berval   *pbv;
+       AttributeDescription *ad;
+       const char              *text;
+       Operation               *op;
+       Modifications   *modlist = NULL;
+       Modifications   **modtail = &modlist;
+       struct berval pdn = { 0, NULL };
+       struct berval ndn = { 0, NULL };
+
+
+
+       pConn = fakeConnection( NULL,  LDAP_REQ_MODIFY );
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               if ( dn == NULL || mods == NULL || *mods == NULL ) {
+                       rc = LDAP_OPERATIONS_ERROR; 
+               }
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               dn_normalize( dn );
+
+               Debug(LDAP_DEBUG_TRACE,"slapi modifying object %s.\n", dn, 0, 0);
+               rc = dn_check(dn, &dnBadChar);
+               if ( rc == LDAP_SUCCESS ) {
+
+                       /* We could be serving multiple database backends.  Select the
+                        * appropriate one, or send a referral to our "referral server"
+                        * if we don't hold it. 
+                        */
+
+                       /* check if ManageDsaIt control is set  */
+                       if ( slapi_control_present( controls,
+                                LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
+                                       manageDsaIt = 1; /* turn off referral */
+                       }
+                       bv.bv_val = strdup(dn);
+                       bv.bv_len = strlen(dn);
+                       be = select_backend(&bv, manageDsaIt, 0);
+                       if ( be == NULL )  {
+                               rc =  LDAP_PARTIAL_RESULTS;
+                       } else if ( be->be_modify == NULL ) {
+                               rc = LDAP_UNWILLING_TO_PERFORM;
+                       }
+               }
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               for ( i=0, pMod=mods[0]; pMod != NULL; pMod=mods[++i] ) {
+                       if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
+               /* attr values are in berval format, merge them with the Entry's attr list */
+                               rc = duplicateBVMod( pMod, &pNewMod );
+                       } else {
+               pNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
+               if ( pNewMod == NULL ) {
+                                       rc = LDAP_NO_MEMORY;
+                               } else {
+                                       memset( pNewMod, '\0', sizeof(LDAPMod) );
+                                       pNewMod->mod_op = pMod->mod_op | LDAP_MOD_BVALUES;
+                                       pNewMod->mod_type = slapi_ch_strdup( pMod->mod_type );
+                                       if ( pNewMod->mod_type == NULL ) {
+                                               rc = LDAP_NO_MEMORY;
+                                       } else {
+                                               if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE ) {
+                                                       rc = ValuesToBValues( pMod->mod_values, &(pNewMod->mod_bvalues) );
+                                               } else {
+                                                       if ( pMod->mod_values == NULL ) {
+                                                               Debug(LDAP_DEBUG_TRACE,
+                                                                "slapi_modify_internal:mod_values is null\n",0, 0, 0);
+                                       rc = LDAP_OTHER;
+                                                       } else {
+                                                               rc = ValuesToBValues( pMod->mod_values, 
+                                                                                                         &(pNewMod->mod_bvalues) );
+                                                       }
+                                               }
+                                       }
+               }
+                       }
+                       if ( rc == LDAP_SUCCESS ) {
+                               /* add the new mod to the end of mod list */
+                               if ( pModList == NULL ) {
+                                       pModList = pNewMod;
+                               } else {
+                                       pTmpMod = pModList;
+                                       while ( pTmpMod != NULL ) {
+                                               pSaveMod = pTmpMod;
+                                               pTmpMod = pTmpMod->mod_next;
+                                       }
+                                       pSaveMod->mod_next = pNewMod;
+                               }
+                       }
+               }  /* for each LDAPMod */
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               /* convert LDAPModList to Modification list */
+               pTmpMod = pModList;
+               while (pTmpMod != NULL) {
+                       Modifications *mod;
+                       mod = (Modifications *) ch_malloc( sizeof(Modifications) );
+                       mod->sml_type.bv_val = ch_strdup(pTmpMod->mod_type);
+                       mod->sml_type.bv_len = strlen(pTmpMod->mod_type);
+                       mod->sml_op = pTmpMod->mod_op;
+                       pbv = NULL;
+                       rc = bvptr2obj(pTmpMod->mod_bvalues, &pbv);
+                       mod->sml_bvalues = pbv;
+                       ad = NULL;
+                       rc = slap_str2ad(pTmpMod->mod_type, &ad, &text );
+                       mod->sml_desc = ad;
+                       *modtail = mod;
+                       modtail = &mod->sml_next;
+                       pTmpMod = pTmpMod->mod_next;
+               }
+               *modtail = NULL;
+       }
+
+   if ( rc == LDAP_SUCCESS ) {
+               op = (Operation *)pConn->c_pending_ops.stqh_first;
+               op->o_ctrls = controls;
+               Debug (LDAP_DEBUG_TRACE, "Calling backend routine \n", 0, 0, 0);
+               pdn.bv_val = ch_strdup(dn);
+               pdn.bv_len = strlen(dn);
+               ndn.bv_val = ch_strdup(dn);
+               ndn.bv_len = strlen(dn);
+               rc = (*be->be_modify)( be, pConn, op, &pdn, &ndn, modlist );
+               if (rc == LDAP_SUCCESS)
+             Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
+               else
+                       Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
+
+       } else { 
+               rc = LDAP_OPERATIONS_ERROR;
+       }
+
+   if ( pPB != NULL ) {
+      slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+   }
+   if (pModList != NULL)  {
+         freeModList( pModList ); 
+   }
+   if ( pConn != NULL ) {
+      if ( pConn->c_dn.bv_val )
+         slapi_ch_free( pConn->c_dn.bv_val );
+      if ( pConn->c_original_dn )
+         slapi_ch_free( pConn->c_original_dn ); 
+      if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
+         slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val);
+      if ( pConn->c_pending_ops.stqh_first )
+         slapi_ch_free( pConn->c_pending_ops.stqh_first );
+      pSavePB = pPB;
+      free( pConn );
+   }
+   return( pSavePB );
+}
+
+
+/* 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_OPERAITONS_ERROR
+ *                 LDAP_NO_MEMORY
+ *                 LDAP_OTHER
+ *                 LDAP_UNWILLING_TO_PERFORM
+*/
+Slapi_PBlock *
+slapi_modrdn_internal( char *olddn, 
+                                               char *newrdn, 
+                                               int deloldrdn, 
+                                               LDAPControl **controls, 
+                                               int log_change)
+{
+
+       int                             rc=LDAP_SUCCESS;
+       int                             dnBadChar;
+       Backend                 *be;
+       char                    *pDn=NULL;
+       Slapi_PBlock    *pPB=NULL;
+       Slapi_PBlock    *pSavePB=NULL;
+       Connection              *pConn=NULL;
+
+       int                             manageDsaIt = 0;
+    int                                isCritical;
+    struct berval      bv  = { 0, NULL };
+       Operation       *op;
+
+       struct berval dn = { 0, NULL };
+       struct berval ndn = { 0, NULL };
+       struct berval pdn = { 0, NULL };
+
+       struct berval newrdnO = { 0, NULL };
+       struct berval nnewrdnO = { 0, NULL };
+       struct berval pnewrdnO = { 0, NULL };
+
+       struct berval *nnewS = NULL;
+       struct berval *pnewS = NULL;
+
+       
+       dn.bv_val = ch_strdup(olddn);
+       if (dn.bv_val == NULL) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               dn.bv_len = strlen(olddn);
+       }
+
+       if (rc == LDAP_SUCCESS) {
+               newrdnO.bv_val = ch_strdup(newrdn);
+               if (newrdnO.bv_val == NULL) {
+                       rc = LDAP_NO_MEMORY;
+               } else {
+                       newrdnO.bv_len = strlen(newrdn);
+               }
+       } 
+
+       if (rc == LDAP_SUCCESS) {
+               rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
+       }
+
+       if (rc == LDAP_SUCCESS) {
+               rc = dnPrettyNormal( NULL, &newrdnO, &pnewrdnO, &nnewrdnO );
+       }
+               
+       if ( rc == LDAP_SUCCESS ) {
+               pConn = fakeConnection(NULL,  LDAP_REQ_MODRDN );
+       } 
+
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               if ( olddn == NULL || newrdn == NULL ) {
+                       rc = LDAP_OPERATIONS_ERROR;
+               }
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               Debug(LDAP_DEBUG_TRACE,"slapi modify rdn %s new RDN: %s.\n", olddn, newrdn, 0);
+               rc = dn_check(olddn, &dnBadChar);
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+
+               /* We could be serving multiple database backends.  Select the
+                * appropriate one, or send a referral to our "referral server"
+                * if we don't hold it. */
+
+               op = (Operation *)pConn->c_pending_ops.stqh_first;
+               op->o_ctrls = controls;
+
+               /* check if ManageDsaIt control is set  */
+               if ( slapi_control_present( controls,
+                        LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
+                               manageDsaIt = 1; /* turn off referral */
+               }
+               be = select_backend(&bv, manageDsaIt, 0);
+               if ( be == NULL )  {
+                       rc =  LDAP_PARTIAL_RESULTS;
+               }
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               if ( be->be_modrdn == NULL ) {
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+               } else {
+                       Debug (LDAP_DEBUG_TRACE, "Calling backend routine \n", 0, 0, 0);
+                       rc = (*be->be_modrdn)( be, pConn, op, &pdn, &ndn,
+                                    &pnewrdnO, &nnewrdnO, deloldrdn, pnewS, nnewS );
+                       if (rc == LDAP_SUCCESS)
+                               Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
+                       else
+                               Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
+               }
+       }
+
+       if (dn.bv_val)
+               ch_free(dn.bv_val);
+       if (pdn.bv_val)
+               ch_free(pdn.bv_val);
+       if (ndn.bv_val)
+               ch_free(ndn.bv_val);
+       if (newrdnO.bv_val)
+               ch_free(newrdnO.bv_val);
+       if (pnewrdnO.bv_val)
+               ch_free(newrdnO.bv_val);
+       if (nnewrdnO.bv_val)
+               ch_free(newrdnO.bv_val);
+
+       if ( pPB != NULL ) { 
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+       }
+       if ( pConn != NULL ) {
+               if ( pConn->c_dn.bv_val )
+                       slapi_ch_free( pConn->c_dn.bv_val );
+               if (pConn->c_original_dn)
+                       slapi_ch_free(pConn->c_original_dn);
+               if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first );
+               pSavePB = pPB;
+               free( pConn );
+       }
+       return( pSavePB );
+}
+
+Slapi_PBlock * 
+slapi_search_internal( char *base, int scope, char *filStr, 
+                                          LDAPControl **controls, char **attrs, int attrsonly ) 
+{
+       return slapi_search_internal_bind(NULL,base,scope,filStr,controls, attrs,attrsonly);
+}
+
+Slapi_PBlock *
+slapi_search_internal_bind( char *bindDN, char *b, int scope, char *filStr, 
+                                                        LDAPControl **controls, char **attrs, int attrsonly ) 
+{      
+       Slapi_PBlock    *ptr;           
+       Connection              *c;
+       Backend                 *be;
+       Filter                  *filter=NULL;
+       int                             i, deref=0, sizelimit=-1, timelimit=-1, rc, dnCheckJunk=0;
+       int                             manageDsaIt = 0; 
+       int                             isCritical;
+       struct berval   bv;
+       Operation               *op;
+
+       struct berval base = { 0, NULL };
+       struct berval pbase = { 0, NULL };
+       struct berval nbase = { 0, NULL };
+       AttributeName   *an;
+       const char      *text;
+       struct berval   fstr = { 0, NULL };
+
+
+       
+       c=fakeConnection(bindDN,LDAP_REQ_SEARCH);
+
+       if ( c == NULL ) { 
+               rc = LDAP_NO_MEMORY;
+       } else {
+               ptr = (Slapi_PBlock *)c->c_pending_ops.stqh_first->o_pb;
+    }
+
+       /* check if ManageDsaIt control is set  */
+       if ( rc = slapi_control_present( controls, 
+                                                                        LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
+               manageDsaIt = 1; /* turn off referral */
+       }
+       if ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
+                                                                       && scope != LDAP_SCOPE_SUBTREE ) {
+               slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PROTOCOL_ERROR);
+               return ptr;
+       }
+
+       dn_normalize( b );
+       rc=dn_check(b, &dnCheckJunk);
+       if(rc != LDAP_SUCCESS) {
+               slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc);
+               return ptr;
+       }
+
+       if ( attrs != NULL ) {
+               for ( i = 0; attrs[i] != NULL; i++ )
+                       attr_normalize( attrs[i] );
+       }
+       if((filter=slapi_str2filter(filStr)) == NULL) {
+               slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PROTOCOL_ERROR);
+               return ptr;
+       }
+       bv.bv_val = ch_strdup(b);
+       bv.bv_len = strlen(b);
+       /* check if ManageDsaIt control is set  */
+       if ( slapi_control_present( controls,
+               LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
+               manageDsaIt = 1; /* turn off referral */
+       }
+
+       if ((be = select_backend( &bv, manageDsaIt, 0 )) == NULL) {
+                if ( manageDsaIt == 1 ) { /* referral turned off */
+                        slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_NO_SUCH_OBJECT);
+                } else {
+                        slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PARTIAL_RESULTS);
+                }
+               return ptr;
+       } else if ( be->be_search == NULL ) {
+               slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_UNWILLING_TO_PERFORM);
+               return ptr;
+       } else {
+
+               base.bv_val = ch_strdup(b);
+               base.bv_len = strlen(b);
+               rc = dnPrettyNormal( NULL, &base, &pbase, &nbase );
+               for (i = 0; attrs[i] != 0; i++) {
+                       an[i].an_desc = NULL;
+                       an[i].an_name.bv_val = ch_strdup(attrs[i]);
+                       an[i].an_name.bv_len = strlen(attrs[i]);
+                       slap_bv2ad(&an[i].an_name, &an[i].an_desc, &text);
+               }
+               fstr.bv_val = ch_strdup(filStr);
+               fstr.bv_len = strlen(filStr);
+               rc = (*be->be_search)( be, c, op, &pbase, &nbase, scope, deref, 
+                                       sizelimit, timelimit, filter, &fstr, an, attrsonly );
+       } 
+       slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc); 
+        if ( c->c_pending_ops.stqh_first ){
+          if(c->c_dn.bv_val)
+            slapi_ch_free(c->c_dn.bv_val);
+          if (c->c_original_dn)
+            slapi_ch_free(c->c_original_dn); 
+          if(c->c_pending_ops.stqh_first->o_dn.bv_val)
+            slapi_ch_free(c->c_pending_ops.stqh_first->o_dn.bv_val);
+          slapi_ch_free( c->c_pending_ops.stqh_first );
+        }
+       slapi_ch_free((void **)c);
+       if (filter) 
+               slapi_filter_free(filter,1);
+       return ptr;     
+}
+
+/*
+ Function : slapi_get_supported_extended_ops
+ Description : This function returns a pointer points to an array of Null terminated char pointers.
+               Each char pointer points to an oid of an extended operation.
+               If there is no defined extended operaitons, this routine returns NULL. 
+ Input : none
+ Output : pointer to an null terminated char pointer array or null.
+ Notes: The caller of this routine needs to free the retuned array pointer, but
+        should not free the pointers inside the array.
+*/
+char
+**slapi_get_supported_extended_ops(void)
+{
+
+       ExtendedOp   *pTmpExtOp;
+       int          numExtOps = 0;
+       int          i=0;
+       char         **ppExtOpOID = NULL;
+
+       if ( pGExtendedOps != NULL ) {
+               pTmpExtOp = pGExtendedOps;
+                       while ( pTmpExtOp != NULL ) {
+                               numExtOps++;
+                               pTmpExtOp = pTmpExtOp->ext_next;
+                       }
+
+               if ( numExtOps > 0 ) {
+                       ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps+1) * sizeof(char *) );
+                       if ( ppExtOpOID != NULL ) {
+                               pTmpExtOp = pGExtendedOps;
+                               while ( pTmpExtOp != NULL ) {
+                                       ppExtOpOID[i] = pTmpExtOp->ext_oid;
+                                       i++;
+                                       pTmpExtOp = pTmpExtOp->ext_next;
+                               }
+                               ppExtOpOID[i] = NULL;
+                       }
+               }
+       }
+
+       return( ppExtOpOID );
+}
+
+Slapi_PBlock *
+slapi_simple_bind_internal( char *d, struct berval *cred, int method, int version)
+{
+
+       int                             rc=LDAP_SUCCESS;
+       Connection              *pConn=NULL;
+       Backend                 *be;
+       Slapi_PBlock    *pPB=NULL;
+       int                             dnBadChar;
+
+       int             isCritical;
+       struct berval   bv;
+       struct berval   dn = { 0, NULL };
+       struct berval   pdn = { 0, NULL };
+       struct berval   ndn = { 0, NULL };
+       Operation               *op;
+
+
+       pConn = fakeConnection(NULL, LDAP_REQ_BIND );
+
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               pConn->c_version = version;
+               op = (Operation *)pConn->c_pending_ops.stqh_first;
+       }
+
+       if ( d == NULL ) {
+               rc = LDAP_OPERATIONS_ERROR;
+       } else {
+               dn.bv_val = ch_strdup (d);
+               dn.bv_len = strlen(d);
+               rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               be = select_backend(&ndn, 0, 0 );
+               if ( be == NULL )  {
+                       rc =  LDAP_PARTIAL_RESULTS;
+               } else if ( be->be_bind == NULL  ) {
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+               }
+       }
+
+       rc = (*be->be_bind)( be, pConn, op,
+                                       &pdn, &ndn, method, cred, NULL );
+
+       if (rc == LDAP_SUCCESS) {
+               pConn->c_version = version;
+               pConn->c_dn.bv_val = strdup( d );
+               pConn->c_dn.bv_len = strlen( d );
+               if (pConn->c_dn.bv_val == NULL) {
+                       rc = LDAP_NO_MEMORY;
+                       Debug (LDAP_DEBUG_TRACE, " backend routine successful, but has no more memory \n",0, 0, 0);
+               } 
+               Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
+       }
+
+       if ( pPB != NULL )
+       slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+
+   return(pPB);
+
+}
+
diff --git a/servers/slapd/slapi/slapi_ops.c.save b/servers/slapd/slapi/slapi_ops.c.save
new file mode 100644 (file)
index 0000000..4833d00
--- /dev/null
@@ -0,0 +1,1271 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is
+ * given to IBM Corporation. This software is provided ``as is''
+ * without express or implied warranty.
+ */
+
+#include "portable.h"
+#include "slapi_common.h"
+#include <slap.h>
+#include <slapi.h>
+#include <lber.h>
+#include "../../../libraries/liblber/lber-int.h"
+
+
+int
+bvptr2obj(     struct berval **bvptr, 
+                       struct berval **bvobj);
+
+Slapi_PBlock *
+slapi_simple_bind_internal( char *dn, 
+                                                       struct berval *cred,            
+                                                       int method, 
+                                                       int version);
+
+int
+internal_result_v3( Connection *conn, 
+                                       Operation *op, 
+                                       int err,
+                                       char *matched, 
+                                       char *text, 
+                                       char **referrals) 
+{
+       return LDAP_SUCCESS;
+}
+
+
+
+int
+internal_search_entry( Backend *be, 
+                                               Connection *conn, 
+                                               Operation *op, 
+                                               Entry *e, 
+                                       char **attrs, 
+                                               int attrsonly, 
+                                               char **denied_attrs) 
+{
+       char *ent2str = NULL;
+       int nentries = 0, len = 0, i = 0;
+       Slapi_Entry **head = NULL, **tp;
+       
+       if((ent2str=slapi_entry2str(e,&len)) == NULL) {
+               return SLAPD_NO_MEMORY;
+       }
+
+       slapi_pblock_get((Slapi_PBlock *)op->o_pb, SLAPI_NENTRIES, &nentries);
+       slapi_pblock_get((Slapi_PBlock *)op->o_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head);
+       i=nentries + 1;
+       if(nentries == 0 ) {
+               if((tp=(Slapi_Entry **)slapi_ch_malloc(2 * sizeof(Slapi_Entry *))) == NULL) {
+                       return SLAPD_NO_MEMORY;
+               }
+               if((tp[0]=(Slapi_Entry *)str2entry(ent2str)) == NULL) { 
+                       return SLAPD_NO_MEMORY;
+               }
+       } else {
+               if((tp=(Slapi_Entry **)slapi_ch_realloc((char *)head,
+                                                       (sizeof(Slapi_Entry *) * (i+1)))) == NULL) {
+                       return SLAPD_NO_MEMORY;
+               }
+               if((tp[i-1]=(Slapi_Entry *)str2entry(ent2str)) == NULL) { 
+                       return SLAPD_NO_MEMORY;
+               }
+       }
+       tp[i] = NULL;  
+              
+       slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,(void *)tp);
+       slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_NENTRIES,(void *)i);
+       slapi_ch_free(ent2str);
+       return LDAP_SUCCESS;
+}
+
+int
+internal_search_result(        Connection *conn, 
+                                               Operation *op,
+                                               int err, 
+                                               char *matched, 
+                                               char *text, 
+                                               int nentries) 
+{
+       slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_NENTRIES,(void *)nentries);
+       return LDAP_SUCCESS;
+}
+
+
+int
+internal_result_ext(   Connection *conn, 
+                                               Operation *op, 
+                                               int  errnum, 
+                                               char *respname, 
+                                               struct berval *response ) 
+{
+       return LDAP_SUCCESS;
+}
+
+
+int
+internal_search_reference(     Connection *conn, 
+                                                       Operation *op, 
+                                                       char **ref) 
+{
+       return LDAP_SUCCESS;
+}
+
+Connection *
+fakeConnection(        char *DN, 
+                               int OpType) 
+{ 
+       Connection *pConn, *c;
+
+       if((pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection))) == NULL)
+               return (Connection *)NULL;
+
+       LDAP_STAILQ_INIT(&c->c_pending_ops);
+       LDAP_STAILQ_INIT(&c->c_ops);
+
+       if((pConn->c_pending_ops.stqh_first=(Operation *) slapi_ch_calloc(1, sizeof(Operation))) == NULL) { 
+               slapi_ch_free( pConn );
+               return (Connection *)NULL;
+       }
+
+       if((pConn->c_pending_ops.stqh_first->o_pb=(Slapi_PBlock *) slapi_pblock_new()) == NULL) {
+               slapi_ch_free( pConn->c_pending_ops.stqh_first );
+               slapi_ch_free( pConn );
+               return (Connection *)NULL;
+       }
+
+       c = pConn;
+
+       c->c_pending_ops.stqh_first->o_tag = OpType;
+       c->c_sb = ber_sockbuf_alloc( );
+       c->c_protocol = LDAP_VERSION3; 
+
+       time(&pConn->c_pending_ops.stqh_first->o_time);
+
+       pConn->c_send_ldap_result = (SEND_LDAP_RESULT) internal_result_v3;
+       pConn->c_send_search_entry = (SEND_SEARCH_ENTRY) internal_search_entry;
+       pConn->c_send_search_result = (SEND_SEARCH_RESULT) internal_search_result;
+       pConn->c_send_ldap_extended = (SEND_LDAP_EXTENDED) internal_result_ext;
+       pConn->c_send_search_reference = (SEND_SEARCH_REFERENCE) internal_search_reference;
+
+       return pConn;
+}
+
+
+/* Function : slapi_delete_internal
+ *
+ * Description : Plugin functions call this routine to delete an entry 
+ *               in the backend directly
+ * Return values : LDAP_SUCCESS
+ *                 LDAP_OPERAITONS_ERROR
+ *                 LDAP_NO_MEMORY
+ *                 LDAP_OTHER
+ *                 LDAP_UNWILLING_TO_PERFORM
+*/
+Slapi_PBlock *
+slapi_delete_internal( char *ldn, 
+                                               LDAPControl **controls, 
+                                               int log_change)
+{
+
+       int                             rc=LDAP_SUCCESS;
+       Backend                 *be;
+       Slapi_PBlock    *pPB=NULL;
+       Slapi_PBlock    *pSavePB=NULL;
+       Connection              *pConn=NULL;
+       Operation               *op;
+
+       int                             manageDsaIt = 0;
+    int                                isCritical;
+
+       struct berval dn  = { 0, NULL };
+       struct berval pdn = { 0, NULL };
+       struct berval ndn = { 0, NULL };
+
+
+       if ( ldn == NULL ) {
+               rc = LDAP_OPERATIONS_ERROR; 
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               pConn = fakeConnection( NULL,  LDAP_REQ_DELETE );
+       }
+
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               op = (Operation *)pConn->c_pending_ops.stqh_first;
+               op->o_ctrls = controls;
+
+               op->o_ndn.bv_val = slapi_strdup(be->be_update_ndn.bv_val);
+               op->o_ndn.bv_len = be->be_update_ndn.bv_len;
+               pConn->c_dn.bv_val = slapi_strdup(be->be_update_ndn.bv_val);
+               pConn->c_dn.bv_len = be->be_update_ndn.bv_len;
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               dn.bv_val = slapi_strdup(ldn);
+               dn.bv_len = slapi_strlen(ldn);
+
+               rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
+
+               if( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
+                               "do_delete: conn %d  invalid dn (%s)\n",
+                               conn->c_connid, dn.bv_val ));
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                               "do_delete: invalid dn (%s)\n", dn.bv_val, 0, 0 );
+#endif
+               }
+       }
+
+       if( ndn.bv_len == 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
+                       "Attempt to delete root DSE.\n", conn->c_connid ));
+#else
+               Debug( LDAP_DEBUG_ANY, "Attempt to delete root DSE.\n", 0, 0, 0 );
+#endif
+               rc = LDAP_UNWILLING_TO_PERFORM;
+
+#ifdef SLAPD_SCHEMA_DN
+
+       } else if ( strcasecmp( ndn.bv_val, SLAPD_SCHEMA_DN ) == 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
+                               "Attempt to delete subschema subentry.\n", conn->c_connid ));
+#else
+               Debug( LDAP_DEBUG_ANY, "Attempt to delete subschema subentry.\n", 0, 0, 0 );
+#endif
+               rc = LDAP_UNWILLING_TO_PERFORM;
+
+#endif
+       }
+
+       if ( rc = slapi_control_present( controls, LDAP_MANAGEDSAIT_OID, NULL, &isCritical)){
+               manageDsaIt = 1; /* turn off referral */
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               be = select_backend(&bv, manageDsaIt, 0);
+               if ( be == NULL ) rc =  LDAP_PARTIAL_RESULTS;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
+       }
+
+       suffix_alias( be, &ndn );
+
+       if ( be->be_delete ) {
+               /* do the update here */
+               int repl_user = be_isupdate( be, &op->o_ndn );
+#ifndef SLAPD_MULTIMASTER
+               if ( !be->be_update_ndn.bv_len || repl_user )
+#endif
+               {
+                       if ( (*be->be_delete)( be, conn, op, &pdn, &ndn ) == 0 ) {
+#ifdef SLAPD_MULTIMASTER
+                               if ( !be->be_update_ndn.bv_len || !repl_user )
+#endif
+                               {
+                                       if (log_change) replog( be, op, &pdn, &ndn, NULL );
+                }
+            }
+#ifndef SLAPD_MULTIMASTER
+        } else {
+                       rc = LDAP_REFERRAL;
+#endif
+        }
+       } else {
+               rc = LDAP_UNWILLING_TO_PERFORM;
+       }
+
+       if ( pPB != NULL ) { 
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+       }
+       if ( pConn != NULL ) {
+               if ( pConn->c_dn.bv_val )
+                       slapi_ch_free( pConn->c_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first );
+               if (dn.bv_val)
+                       slapi_ch_free(dn.bv_val);
+               if (pdn.bv_val)
+                       slapi_ch_free(pdn.bv_val);
+               if (ndn.bv_val)
+                       slapi_ch_free(ndn_bv.val);
+               pSavePB = pPB;
+               free( pConn );
+       }
+       return( pSavePB );
+}
+
+#if 0
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+
+/* 
+ * Function : freeModList 
+ * Free a list of LDAPMod structures which has the bvalue defined.
+*/
+static void 
+freeModList(   LDAPMod *pMod )
+{
+       LDAPMod *pNextMod;
+
+       while ( pMod != NULL ) {
+               pNextMod = pMod->mod_next;
+               free( pMod->mod_type );
+               ber_bvecfree( pMod->mod_bvalues );
+               free( pMod );
+               pMod = pNextMod;
+       }
+}
+
+
+/*
+ * Function : duplicateBVMod 
+ * Duplicate a LDAPMod structure in which the bervals are defined. 
+ * return code : LDAP_SUCEESS, 
+ *                              LDAP_OTHER, 
+ *                              LDAP_NO_MEMORY
+ */
+
+int 
+duplicateBVMod(        LDAPMod *pMod, 
+                               LDAPMod **ppNewMod )
+{
+       int rc = LDAP_SUCCESS;
+       int i;
+       struct berval **ppNewBV;
+       struct berval *pNewBV;
+
+       if ( pMod == NULL ) {
+               rc = LDAP_OTHER;
+       } else {
+               *ppNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
+               if ( *ppNewMod == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+               } else {
+                       memset( (*ppNewMod),'\0',sizeof(LDAPMod) );
+                       (*ppNewMod)->mod_op = pMod->mod_op;
+                       (*ppNewMod)->mod_type = slapi_ch_strdup( pMod->mod_type);
+                       if ( (*ppNewMod)->mod_type == NULL) {
+                               rc = LDAP_NO_MEMORY;
+                       } else {
+                               if ( pMod->mod_bvalues == NULL ) {
+                                       (*ppNewMod)->mod_values = NULL; 
+                               } else {
+                                       for ( i=0; pMod->mod_bvalues[i] != NULL; i++ ) {
+                                               ;
+                                       }
+                                       ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*sizeof(struct berval *));
+                                       if ( ppNewBV == NULL ) {
+                                               rc = LDAP_NO_MEMORY;
+                                       } else {
+                                               for ( i=0; pMod->mod_bvalues[i] != NULL &&
+                                                                                       rc == LDAP_SUCCESS; i++ ) {
+                                                       pNewBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+                                                       if ( pNewBV == NULL ) {
+                                                               rc = LDAP_NO_MEMORY;
+                                                       } else {
+                                                               pNewBV->bv_val = slapi_ch_malloc(pMod->mod_bvalues[i]->bv_len+1);
+                                                               if ( pNewBV->bv_val == NULL ) {
+                                                                       rc = LDAP_NO_MEMORY;
+                                                               } else {
+                                                                       memset(pNewBV->bv_val,'\0',pMod->mod_bvalues[i]->bv_len+1);
+                                                                       pNewBV->bv_len = pMod->mod_bvalues[i]->bv_len;
+                                                                       memcpy(pNewBV->bv_val,pMod->mod_bvalues[i]->bv_val,pNewBV->bv_len);
+                                                                       ppNewBV[i] = pNewBV;
+                                                               }
+                                                       }
+                                               } /* for each bvalue */
+                                               if ( rc == LDAP_SUCCESS ) {
+                                                       ppNewBV[i] = NULL;
+                                                       (*ppNewMod)->mod_bvalues = ppNewBV;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       return( rc );
+}
+
+/* 
+ * Function : ValuestoBValues 
+ * Convert an array of char ptrs to an array of berval ptrs.
+ * return value : LDAP_SUCCESS
+ *                LDAP_NO_MEMORY
+ *                LDAP_OTHER
+*/
+
+static int 
+ValuesToBValues(       char **ppValue, 
+                                       struct berval ***pppBV )
+{
+       int  rc = LDAP_SUCCESS;
+       int  i;
+       struct berval *pTmpBV;
+       struct berval **ppNewBV;
+
+       /* count the number of char ptrs. */
+       for ( i=0; ppValue != NULL && ppValue[i] != NULL; i++ ) {
+               ;       /* NULL */
+       }
+
+       if ( i == 0 ) {
+               rc = LDAP_OTHER;
+       } else {
+               *pppBV = ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*(sizeof(struct berval *)) );
+               if ( *pppBV == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+               } else {
+                       while ( ppValue != NULL && *ppValue != NULL && rc == LDAP_SUCCESS ) {
+                               pTmpBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+                               if ( pTmpBV == NULL) {
+                                       rc = LDAP_NO_MEMORY;
+                               } else {
+                                       pTmpBV->bv_val = slapi_ch_strdup(*ppValue);
+                                       if ( pTmpBV->bv_val == NULL ) {
+                                               rc = LDAP_NO_MEMORY;
+                                       } else {
+                                               pTmpBV->bv_len = strlen(*ppValue);
+                                               *ppNewBV = pTmpBV;
+                                               ppNewBV++;
+                                       }
+                                       ppValue++;
+                               }
+                       }
+                       /* null terminate the array of berval ptrs */
+                       *ppNewBV = NULL;
+               }
+       }
+       return( rc );
+}
+
+
+/*
+ * Function : LDAPModToEntry 
+ * convert a dn plus an array of LDAPMod struct ptrs to an entry structure
+ * with a link list of the correspondent attributes.
+ * Return value : LDAP_SUCCESS
+ *                LDAP_NO_MEMORY
+ *                LDAP_OTHER
+*/
+Entry *
+LDAPModToEntry(        char *ldn, 
+                               LDAPMod **mods )
+{
+       int                             rc=LDAP_SUCCESS;
+       LDAPMod                 *pMod;
+       Entry                   *pEntry=NULL;
+       int                             i,j;
+       struct berval   **ppSaveBV;
+       struct berval   **ppBV;
+       struct berval   *pTmpBV;
+       char                    **ppValue;
+
+
+       AttributeDescription *ad;
+       struct berval *bv;
+       const char *text;
+
+    Modifications   *modlist = NULL;
+    Modifications   **modtail = &modlist;
+    Modifications   tmp;
+
+       struct berval dn = { 0, NULL };
+
+       dn.ber_val = slapi_ch_strdup(ldn);
+       dn.ber_len = slapi_ch_strlen(ldn);
+
+       pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
+       if ( pEntry == NULL) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
+               if( rc != LDAP_SUCCESS ) { 
+#ifdef NEW_LOGGING
+                       LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
+                               "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val ));
+#else
+                       Debug( LDAP_DEBUG_ANY, "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val, 0, 0 ); 
+#endif
+                       rc = LDAP_INVALID_DN_SYNTAX;
+               }
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
+                       Modifications *mod;
+                       if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
+                               /* attr values are in berval format */
+                               /* convert an array of pointers to bervals to an array of bervals */
+                               rc = bvptr2obj(pMod->mod_bvalues, &bv);
+                               if (rc != LDAP_SUCCESS) break;
+                               tmp.sml_type = pMod->mod_type;
+                               tmp.sml_bvalues = bv;
+               
+                               mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
+
+                               mod->sml_op = LDAP_MOD_ADD;
+                               mod->sml_next = NULL;
+                               mod->sml_desc = NULL;
+                               mod->sml_type = tmp.sml_type;
+                               mod->sml_bvalues = tmp.sml_bvalues;
+
+                               *modtail = mod;
+                               modtail = &mod->sml_next;
+
+                       } else {
+               /* attr values are in string format, need to be converted */
+                               /* to an array of bervals */ 
+                               if ( pMod->mod_values == NULL ) {
+                                       rc = LDAP_OTHER;
+                               } else {
+                                       rc = ValuesToBValues( pMod->mod_values, &ppBV );
+                                       if (rc != LDAP_SUCCESS) break;
+                                       rc = bvptr2obj(ppBV, &bv);
+                                       if (rc != LDAP_SUCCESS) break;
+                                       tmp.sml_type = pMod->mod_type;
+                                       tmp.sml_bvalues = bv;
+               
+                                       mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
+
+                                       mod->sml_op = LDAP_MOD_ADD;
+                                       mod->sml_next = NULL;
+                                       mod->sml_desc = NULL;
+                                       mod->sml_type = tmp.sml_type;
+                                       mod->sml_bvalues = tmp.sml_bvalues;
+
+                                       *modtail = mod;
+                                       modtail = &mod->sml_next;
+
+
+                                       if ( ppBV != NULL ) {
+                                               ber_bvecfree( ppBV );
+                                       }
+                               }
+                       }
+               } /* for each LDAPMod */
+       }
+
+    if( e->e_nname.bv_len == 0 ) 
+               rc = LDAP_ALREADY_EXISTS;
+
+       /* check if ManageDsaIt control is set  */
+       if ( rc = slapi_control_present( controls, LDAP_MANAGEDSAIT_OID, NULL, &isCritical)){
+               manageDsaIt = 1; /* turn off referral */
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               be = select_backend(&bv, manageDsaIt, 0);
+               if ( be == NULL ) rc =  LDAP_PARTIAL_RESULTS;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
+       }
+
+
+       if ( rc != LDAP_SUCCESS ) {
+               if ( pEntry != NULL ) {
+                       slapi_entry_free( pEntry );
+               }
+               pEntry = NULL;
+       }
+    return( pEntry );
+}
+
+/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
+
+Slapi_PBlock * 
+slapi_add_entry_internal(      Slapi_Entry *e, 
+                                                       LDAPControl **controls, 
+                                                       int log_changes) 
+{
+       int                             rc=LDAP_SUCCESS, i;
+       Backend                 *be;
+       Connection              *pConn=NULL;
+       Operation               *op;
+       Slapi_PBlock    *pPB=NULL, *pSavePB=NULL;
+       char                    *pDn=NULL;
+       int                             manageDsaIt = 0; /* referral is on */
+       int                             isCritical;
+       struct berval   bv;
+       
+       /* check if ManageDsaIt control is set  */
+       if (slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical)) {
+                manageDsaIt = 1; /* turn off referral */
+       }
+
+       pConn = fakeConnection(NULL, LDAP_REQ_ADD);
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else { 
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               if (e == NULL) {
+                       rc =  LDAP_OPERATIONS_ERROR;
+               } else {
+                       if ( rc == LDAP_SUCCESS ) {
+                               be = select_backend(&e->e_nname, manageDsaIt, 0);
+                               if ( be == NULL ) {
+                                       rc = LDAP_PARTIAL_RESULTS;
+                               } else if ( be->be_add == NULL) { 
+                                       rc = LDAP_UNWILLING_TO_PERFORM;
+                               } else {
+                                       op = (Operation *)pConn->c_pending_ops.stqh_first;
+                                       op->o_ctrls = controls;
+                                       rc = (*be->be_add)( be, pConn, op, e );
+                                       if (rc == LDAP_SUCCESS)
+                                               Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
+                                       else
+                                               Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
+                               }
+                       }
+               }
+       }
+       if ( pPB != NULL ) 
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );   
+       if ( pDn != NULL )
+               slapi_ch_free( pDn );
+       if (bv.bv_val != NULL)
+               slapi_ch_free(bv.bv_val);
+       if ( pConn != NULL ) {
+               if ( pConn->c_dn.bv_val ) 
+                       slapi_ch_free( pConn->c_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first);
+               if (pConn->c_original_dn)
+                       slapi_ch_free(pConn->c_original_dn); 
+               pSavePB = pPB;
+               free( pConn );
+       }
+       return( pSavePB );
+}
+
+
+
+Slapi_PBlock *
+slapi_add_internal(    char *dn, 
+                                       LDAPMod **mods, 
+                                       LDAPControl **controls, 
+                                       int log_changes  ) 
+{
+       LDAPMod                 *pMod=NULL;
+       Slapi_PBlock    *pb=NULL;
+       Entry                   *pEntry=NULL;
+       int                             i, rc=LDAP_SUCCESS;
+
+
+       if(mods == NULL || *mods == NULL || dn == NULL || *dn == NULL) 
+               rc = LDAP_OPERATIONS_ERROR ;
+
+       if (rc == LDAP_SUCCESS) {
+               for (i=0, pMod=mods[0]; pMod != NULL; pMod=mods[++i] ) {
+                       if ((pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD) {
+                               rc = LDAP_OTHER;
+                               break;
+                       }
+               }
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
+                       rc = LDAP_OTHER;
+               }
+       }
+
+       if(rc != LDAP_SUCCESS) {
+               pb = slapi_pblock_new();
+               slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+       } else {
+               pb = slapi_add_entry_internal(pEntry, controls, log_changes);
+       }
+
+       if(pEntry) 
+               slapi_entry_free(pEntry);
+
+       return(pb);
+}
+
+
+/*dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd*/
+/* Function : slapi_modify_internal
+ *
+ * Description : Plugin functions call this routine to modify an entry in the backend directly
+ * Return values : LDAP_SUCCESS
+ *                 LDAP_OPERAITONS_ERROR
+ *                 LDAP_NO_MEMORY
+ *                 LDAP_OTHER
+ *                 LDAP_UNWILLING_TO_PERFORM
+*/
+Slapi_PBlock *
+slapi_modify_internal( char *dn, LDAPMod **mods, LDAPControl **controls, int log_change)
+{
+       int                             rc=LDAP_SUCCESS;
+       int                             i;
+       int                             dnBadChar;
+       LDAPMod                 *pMod;
+       LDAPMod                 *pNewMod;
+       LDAPMod                 *pTmpMod;
+       LDAPMod                 *pSaveMod;
+       LDAPMod                 *pModList=NULL;
+       Backend                 *be;
+       Slapi_PBlock    *pPB=NULL;
+       Slapi_PBlock    *pSavePB=NULL;
+       Connection              *pConn=NULL;
+
+       int                             manageDsaIt = 0;
+       int                             isCritical;
+       struct berval   bv;
+       struct berval   *pbv;
+       AttributeDescription *ad;
+       const char              *text;
+       Operation               *op;
+       Modifications   *modlist = NULL;
+       Modifications   **modtail = &modlist;
+       struct berval pdn = { 0, NULL };
+       struct berval ndn = { 0, NULL };
+
+
+
+       pConn = fakeConnection( NULL,  LDAP_REQ_MODIFY );
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               if ( dn == NULL || mods == NULL || *mods == NULL ) {
+                       rc = LDAP_OPERATIONS_ERROR; 
+               }
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               dn_normalize( dn );
+
+               Debug(LDAP_DEBUG_TRACE,"slapi modifying object %s.\n", dn, 0, 0);
+               rc = dn_check(dn, &dnBadChar);
+               if ( rc == LDAP_SUCCESS ) {
+
+                       /* We could be serving multiple database backends.  Select the
+                        * appropriate one, or send a referral to our "referral server"
+                        * if we don't hold it. 
+                        */
+
+                       /* check if ManageDsaIt control is set  */
+                       if ( slapi_control_present( controls,
+                                LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
+                                       manageDsaIt = 1; /* turn off referral */
+                       }
+                       bv.bv_val = strdup(dn);
+                       bv.bv_len = strlen(dn);
+                       be = select_backend(&bv, manageDsaIt, 0);
+                       if ( be == NULL )  {
+                               rc =  LDAP_PARTIAL_RESULTS;
+                       } else if ( be->be_modify == NULL ) {
+                               rc = LDAP_UNWILLING_TO_PERFORM;
+                       }
+               }
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               for ( i=0, pMod=mods[0]; pMod != NULL; pMod=mods[++i] ) {
+                       if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
+               /* attr values are in berval format, merge them with the Entry's attr list */
+                               rc = duplicateBVMod( pMod, &pNewMod );
+                       } else {
+               pNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
+               if ( pNewMod == NULL ) {
+                                       rc = LDAP_NO_MEMORY;
+                               } else {
+                                       memset( pNewMod, '\0', sizeof(LDAPMod) );
+                                       pNewMod->mod_op = pMod->mod_op | LDAP_MOD_BVALUES;
+                                       pNewMod->mod_type = slapi_ch_strdup( pMod->mod_type );
+                                       if ( pNewMod->mod_type == NULL ) {
+                                               rc = LDAP_NO_MEMORY;
+                                       } else {
+                                               if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE ) {
+                                                       rc = ValuesToBValues( pMod->mod_values, &(pNewMod->mod_bvalues) );
+                                               } else {
+                                                       if ( pMod->mod_values == NULL ) {
+                                                               Debug(LDAP_DEBUG_TRACE,
+                                                                "slapi_modify_internal:mod_values is null\n",0, 0, 0);
+                                       rc = LDAP_OTHER;
+                                                       } else {
+                                                               rc = ValuesToBValues( pMod->mod_values, 
+                                                                                                         &(pNewMod->mod_bvalues) );
+                                                       }
+                                               }
+                                       }
+               }
+                       }
+                       if ( rc == LDAP_SUCCESS ) {
+                               /* add the new mod to the end of mod list */
+                               if ( pModList == NULL ) {
+                                       pModList = pNewMod;
+                               } else {
+                                       pTmpMod = pModList;
+                                       while ( pTmpMod != NULL ) {
+                                               pSaveMod = pTmpMod;
+                                               pTmpMod = pTmpMod->mod_next;
+                                       }
+                                       pSaveMod->mod_next = pNewMod;
+                               }
+                       }
+               }  /* for each LDAPMod */
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               /* convert LDAPModList to Modification list */
+               pTmpMod = pModList;
+               while (pTmpMod != NULL) {
+                       Modifications *mod;
+                       mod = (Modifications *) ch_malloc( sizeof(Modifications) );
+                       mod->sml_type.bv_val = ch_strdup(pTmpMod->mod_type);
+                       mod->sml_type.bv_len = strlen(pTmpMod->mod_type);
+                       mod->sml_op = pTmpMod->mod_op;
+                       pbv = NULL;
+                       rc = bvptr2obj(pTmpMod->mod_bvalues, &pbv);
+                       mod->sml_bvalues = pbv;
+                       ad = NULL;
+                       rc = slap_str2ad(pTmpMod->mod_type, &ad, &text );
+                       mod->sml_desc = ad;
+                       *modtail = mod;
+                       modtail = &mod->sml_next;
+                       pTmpMod = pTmpMod->mod_next;
+               }
+               *modtail = NULL;
+       }
+
+   if ( rc == LDAP_SUCCESS ) {
+               op = (Operation *)pConn->c_pending_ops.stqh_first;
+               op->o_ctrls = controls;
+               Debug (LDAP_DEBUG_TRACE, "Calling backend routine \n", 0, 0, 0);
+               pdn.bv_val = ch_strdup(dn);
+               pdn.bv_len = strlen(dn);
+               ndn.bv_val = ch_strdup(dn);
+               ndn.bv_len = strlen(dn);
+               rc = (*be->be_modify)( be, pConn, op, &pdn, &ndn, modlist );
+               if (rc == LDAP_SUCCESS)
+             Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
+               else
+                       Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
+
+       } else { 
+               rc = LDAP_OPERATIONS_ERROR;
+       }
+
+   if ( pPB != NULL ) {
+      slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+   }
+   if (pModList != NULL)  {
+         freeModList( pModList ); 
+   }
+   if ( pConn != NULL ) {
+      if ( pConn->c_dn.bv_val )
+         slapi_ch_free( pConn->c_dn.bv_val );
+      if ( pConn->c_original_dn )
+         slapi_ch_free( pConn->c_original_dn ); 
+      if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
+         slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val);
+      if ( pConn->c_pending_ops.stqh_first )
+         slapi_ch_free( pConn->c_pending_ops.stqh_first );
+      pSavePB = pPB;
+      free( pConn );
+   }
+   return( pSavePB );
+}
+
+
+/* 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_OPERAITONS_ERROR
+ *                 LDAP_NO_MEMORY
+ *                 LDAP_OTHER
+ *                 LDAP_UNWILLING_TO_PERFORM
+*/
+Slapi_PBlock *
+slapi_modrdn_internal( char *olddn, 
+                                               char *newrdn, 
+                                               int deloldrdn, 
+                                               LDAPControl **controls, 
+                                               int log_change)
+{
+
+       int                             rc=LDAP_SUCCESS;
+       int                             dnBadChar;
+       Backend                 *be;
+       char                    *pDn=NULL;
+       Slapi_PBlock    *pPB=NULL;
+       Slapi_PBlock    *pSavePB=NULL;
+       Connection              *pConn=NULL;
+
+       int                             manageDsaIt = 0;
+    int                                isCritical;
+    struct berval      bv  = { 0, NULL };
+       Operation       *op;
+
+       struct berval dn = { 0, NULL };
+       struct berval ndn = { 0, NULL };
+       struct berval pdn = { 0, NULL };
+
+       struct berval newrdnO = { 0, NULL };
+       struct berval nnewrdnO = { 0, NULL };
+       struct berval pnewrdnO = { 0, NULL };
+
+       struct berval *nnewS = NULL;
+       struct berval *pnewS = NULL;
+
+       
+       dn.bv_val = ch_strdup(olddn);
+       if (dn.bv_val == NULL) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               dn.bv_len = strlen(olddn);
+       }
+
+       if (rc == LDAP_SUCCESS) {
+               newrdnO.bv_val = ch_strdup(newrdn);
+               if (newrdnO.bv_val == NULL) {
+                       rc = LDAP_NO_MEMORY;
+               } else {
+                       newrdnO.bv_len = strlen(newrdn);
+               }
+       } 
+
+       if (rc == LDAP_SUCCESS) {
+               rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
+       }
+
+       if (rc == LDAP_SUCCESS) {
+               rc = dnPrettyNormal( NULL, &newrdnO, &pnewrdnO, &nnewrdnO );
+       }
+               
+       if ( rc == LDAP_SUCCESS ) {
+               pConn = fakeConnection(NULL,  LDAP_REQ_MODRDN );
+       } 
+
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               if ( olddn == NULL || newrdn == NULL ) {
+                       rc = LDAP_OPERATIONS_ERROR;
+               }
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               Debug(LDAP_DEBUG_TRACE,"slapi modify rdn %s new RDN: %s.\n", olddn, newrdn, 0);
+               rc = dn_check(olddn, &dnBadChar);
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+
+               /* We could be serving multiple database backends.  Select the
+                * appropriate one, or send a referral to our "referral server"
+                * if we don't hold it. */
+
+               op = (Operation *)pConn->c_pending_ops.stqh_first;
+               op->o_ctrls = controls;
+
+               /* check if ManageDsaIt control is set  */
+               if ( slapi_control_present( controls,
+                        LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
+                               manageDsaIt = 1; /* turn off referral */
+               }
+               be = select_backend(&bv, manageDsaIt, 0);
+               if ( be == NULL )  {
+                       rc =  LDAP_PARTIAL_RESULTS;
+               }
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               if ( be->be_modrdn == NULL ) {
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+               } else {
+                       Debug (LDAP_DEBUG_TRACE, "Calling backend routine \n", 0, 0, 0);
+                       rc = (*be->be_modrdn)( be, pConn, op, &pdn, &ndn,
+                                    &pnewrdnO, &nnewrdnO, deloldrdn, pnewS, nnewS );
+                       if (rc == LDAP_SUCCESS)
+                               Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
+                       else
+                               Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
+               }
+       }
+
+       if (dn.bv_val)
+               ch_free(dn.bv_val);
+       if (pdn.bv_val)
+               ch_free(pdn.bv_val);
+       if (ndn.bv_val)
+               ch_free(ndn.bv_val);
+       if (newrdnO.bv_val)
+               ch_free(newrdnO.bv_val);
+       if (pnewrdnO.bv_val)
+               ch_free(newrdnO.bv_val);
+       if (nnewrdnO.bv_val)
+               ch_free(newrdnO.bv_val);
+
+       if ( pPB != NULL ) { 
+               slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+       }
+       if ( pConn != NULL ) {
+               if ( pConn->c_dn.bv_val )
+                       slapi_ch_free( pConn->c_dn.bv_val );
+               if (pConn->c_original_dn)
+                       slapi_ch_free(pConn->c_original_dn);
+               if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
+               if ( pConn->c_pending_ops.stqh_first )
+                       slapi_ch_free( pConn->c_pending_ops.stqh_first );
+               pSavePB = pPB;
+               free( pConn );
+       }
+       return( pSavePB );
+}
+
+Slapi_PBlock * 
+slapi_search_internal( char *base, int scope, char *filStr, 
+                                          LDAPControl **controls, char **attrs, int attrsonly ) 
+{
+       return slapi_search_internal_bind(NULL,base,scope,filStr,controls, attrs,attrsonly);
+}
+
+Slapi_PBlock *
+slapi_search_internal_bind( char *bindDN, char *b, int scope, char *filStr, 
+                                                        LDAPControl **controls, char **attrs, int attrsonly ) 
+{      
+       Slapi_PBlock    *ptr;           
+       Connection              *c;
+       Backend                 *be;
+       Filter                  *filter=NULL;
+       int                             i, deref=0, sizelimit=-1, timelimit=-1, rc, dnCheckJunk=0;
+       int                             manageDsaIt = 0; 
+       int                             isCritical;
+       struct berval   bv;
+       Operation               *op;
+
+       struct berval base = { 0, NULL };
+       struct berval pbase = { 0, NULL };
+       struct berval nbase = { 0, NULL };
+       AttributeName   *an;
+       const char      *text;
+       struct berval   fstr = { 0, NULL };
+
+
+       
+       c=fakeConnection(bindDN,LDAP_REQ_SEARCH);
+
+       if ( c == NULL ) { 
+               rc = LDAP_NO_MEMORY;
+       } else {
+               ptr = (Slapi_PBlock *)c->c_pending_ops.stqh_first->o_pb;
+    }
+
+       /* check if ManageDsaIt control is set  */
+       if ( rc = slapi_control_present( controls, 
+                                                                        LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
+               manageDsaIt = 1; /* turn off referral */
+       }
+       if ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
+                                                                       && scope != LDAP_SCOPE_SUBTREE ) {
+               slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PROTOCOL_ERROR);
+               return ptr;
+       }
+
+       dn_normalize( b );
+       rc=dn_check(b, &dnCheckJunk);
+       if(rc != LDAP_SUCCESS) {
+               slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc);
+               return ptr;
+       }
+
+       if ( attrs != NULL ) {
+               for ( i = 0; attrs[i] != NULL; i++ )
+                       attr_normalize( attrs[i] );
+       }
+       if((filter=slapi_str2filter(filStr)) == NULL) {
+               slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PROTOCOL_ERROR);
+               return ptr;
+       }
+       bv.bv_val = ch_strdup(b);
+       bv.bv_len = strlen(b);
+       /* check if ManageDsaIt control is set  */
+       if ( slapi_control_present( controls,
+               LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
+               manageDsaIt = 1; /* turn off referral */
+       }
+
+       if ((be = select_backend( &bv, manageDsaIt, 0 )) == NULL) {
+                if ( manageDsaIt == 1 ) { /* referral turned off */
+                        slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_NO_SUCH_OBJECT);
+                } else {
+                        slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PARTIAL_RESULTS);
+                }
+               return ptr;
+       } else if ( be->be_search == NULL ) {
+               slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_UNWILLING_TO_PERFORM);
+               return ptr;
+       } else {
+
+               base.bv_val = ch_strdup(b);
+               base.bv_len = strlen(b);
+               rc = dnPrettyNormal( NULL, &base, &pbase, &nbase );
+               for (i = 0; attrs[i] != 0; i++) {
+                       an[i].an_desc = NULL;
+                       an[i].an_name.bv_val = ch_strdup(attrs[i]);
+                       an[i].an_name.bv_len = strlen(attrs[i]);
+                       slap_bv2ad(&an[i].an_name, &an[i].an_desc, &text);
+               }
+               fstr.bv_val = ch_strdup(filStr);
+               fstr.bv_len = strlen(filStr);
+               rc = (*be->be_search)( be, c, op, &pbase, &nbase, scope, deref, 
+                                       sizelimit, timelimit, filter, &fstr, an, attrsonly );
+       } 
+       slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc); 
+        if ( c->c_pending_ops.stqh_first ){
+          if(c->c_dn.bv_val)
+            slapi_ch_free(c->c_dn.bv_val);
+          if (c->c_original_dn)
+            slapi_ch_free(c->c_original_dn); 
+          if(c->c_pending_ops.stqh_first->o_dn.bv_val)
+            slapi_ch_free(c->c_pending_ops.stqh_first->o_dn.bv_val);
+          slapi_ch_free( c->c_pending_ops.stqh_first );
+        }
+       slapi_ch_free((void **)c);
+       if (filter) 
+               slapi_filter_free(filter,1);
+       return ptr;     
+}
+
+/*
+ Function : slapi_get_supported_extended_ops
+ Description : This function returns a pointer points to an array of Null terminated char pointers.
+               Each char pointer points to an oid of an extended operation.
+               If there is no defined extended operaitons, this routine returns NULL. 
+ Input : none
+ Output : pointer to an null terminated char pointer array or null.
+ Notes: The caller of this routine needs to free the retuned array pointer, but
+        should not free the pointers inside the array.
+*/
+char
+**slapi_get_supported_extended_ops(void)
+{
+
+       ExtendedOp   *pTmpExtOp;
+       int          numExtOps = 0;
+       int          i=0;
+       char         **ppExtOpOID = NULL;
+
+       if ( pGExtendedOps != NULL ) {
+               pTmpExtOp = pGExtendedOps;
+                       while ( pTmpExtOp != NULL ) {
+                               numExtOps++;
+                               pTmpExtOp = pTmpExtOp->ext_next;
+                       }
+
+               if ( numExtOps > 0 ) {
+                       ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps+1) * sizeof(char *) );
+                       if ( ppExtOpOID != NULL ) {
+                               pTmpExtOp = pGExtendedOps;
+                               while ( pTmpExtOp != NULL ) {
+                                       ppExtOpOID[i] = pTmpExtOp->ext_oid;
+                                       i++;
+                                       pTmpExtOp = pTmpExtOp->ext_next;
+                               }
+                               ppExtOpOID[i] = NULL;
+                       }
+               }
+       }
+
+       return( ppExtOpOID );
+}
+
+Slapi_PBlock *
+slapi_simple_bind_internal( char *d, struct berval *cred, int method, int version)
+{
+
+       int                             rc=LDAP_SUCCESS;
+       Connection              *pConn=NULL;
+       Backend                 *be;
+       Slapi_PBlock    *pPB=NULL;
+       int                             dnBadChar;
+
+       int             isCritical;
+       struct berval   bv;
+       struct berval   dn = { 0, NULL };
+       struct berval   pdn = { 0, NULL };
+       struct berval   ndn = { 0, NULL };
+       Operation               *op;
+
+
+       pConn = fakeConnection(NULL, LDAP_REQ_BIND );
+
+       if ( pConn == NULL ) {
+               rc = LDAP_NO_MEMORY;
+       } else {
+               pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
+               pConn->c_version = version;
+               op = (Operation *)pConn->c_pending_ops.stqh_first;
+       }
+
+       if ( d == NULL ) {
+               rc = LDAP_OPERATIONS_ERROR;
+       } else {
+               dn.bv_val = ch_strdup (d);
+               dn.bv_len = strlen(d);
+               rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               be = select_backend(&ndn, 0, 0 );
+               if ( be == NULL )  {
+                       rc =  LDAP_PARTIAL_RESULTS;
+               } else if ( be->be_bind == NULL  ) {
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+               }
+       }
+
+       rc = (*be->be_bind)( be, pConn, op,
+                                       &pdn, &ndn, method, cred, NULL );
+
+       if (rc == LDAP_SUCCESS) {
+               pConn->c_version = version;
+               pConn->c_dn.bv_val = strdup( d );
+               pConn->c_dn.bv_len = strlen( d );
+               if (pConn->c_dn.bv_val == NULL) {
+                       rc = LDAP_NO_MEMORY;
+                       Debug (LDAP_DEBUG_TRACE, " backend routine successful, but has no more memory \n",0, 0, 0);
+               } 
+               Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
+       }
+
+       if ( pPB != NULL )
+       slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
+
+   return(pPB);
+
+}
+
+#endif
diff --git a/servers/slapd/slapi/slapi_ops.h b/servers/slapd/slapi/slapi_ops.h
new file mode 100644 (file)
index 0000000..26adf35
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#ifndef SLAPI_OPS_H
+#define SLAPI_OPS_H
+
+Slapi_PBlock *slapi_search_internal( char *base, int scope, char *filter, 
+       LDAPControl **controls, char **attrs, int attrsonly );
+Slapi_PBlock *slapi_search_internal_bind( char *bindDN, char *base, int scope, char *filter, 
+       LDAPControl **controls, char **attrs, int attrsonly ); /* d58508 */
+Slapi_PBlock *slapi_modify_internal( char *dn, LDAPMod **mods,
+        LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_add_entry_internal( Slapi_Entry * e, LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_add_internal( char * dn, LDAPMod **attrs, LDAPControl **controls, int log_changes );
+Slapi_PBlock *slapi_add_entry_internal( Slapi_Entry * e, LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_delete_internal( char * dn,  LDAPControl **controls, int log_change );
+Slapi_PBlock *slapi_modrdn_internal( char * olddn, char * newrdn, int deloldrdn, LDAPControl **controls, int log_change);
+/*
+Slapi_PBlock *slapi_modrdn_internal( char * olddn, char * newrdn, char *newParent, int deloldrdn, LDAPControl **controls, int log_change);
+*/
+char **slapi_get_supported_extended_ops(void);
+int duplicateBVMod( LDAPMod *pMod, LDAPMod **ppNewMod );
+
+#endif /* SLAPI_OPS_H */
+
diff --git a/servers/slapd/slapi/slapi_pblock.c b/servers/slapd/slapi/slapi_pblock.c
new file mode 100644 (file)
index 0000000..03edd7c
--- /dev/null
@@ -0,0 +1,436 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#include "portable.h"
+#include "slapi_common.h"
+#include <slap.h>
+#include <slapi.h>
+
+static int 
+isOkNetscapeParam( int param ) 
+{
+       switch ( param ) {
+       case SLAPI_BACKEND:
+       case SLAPI_CONNECTION:
+       case SLAPI_OPERATION:
+       case SLAPI_REQUESTOR_ISROOT:
+       case SLAPI_BE_MONITORDN:
+       case SLAPI_BE_TYPE:
+       case SLAPI_BE_READONLY:
+       case SLAPI_BE_LASTMOD:
+       case SLAPI_CONN_ID:
+       case SLAPI_OPINITIATED_TIME:
+       case SLAPI_REQUESTOR_DN:
+       case SLAPI_REQUESTOR_ISUPDATEDN:
+       case SLAPI_CONN_DN:
+       case SLAPI_CONN_AUTHTYPE:
+       case SLAPI_IBM_CONN_DN_ALT:
+       case SLAPI_IBM_CONN_DN_ORIG:
+       case SLAPI_IBM_GSSAPI_CONTEXT:
+       case SLAPI_PLUGIN:
+       case SLAPI_PLUGIN_PRIVATE:
+       case SLAPI_PLUGIN_TYPE:
+       case SLAPI_PLUGIN_ARGV:
+       case SLAPI_PLUGIN_ARGC:
+       case SLAPI_PLUGIN_VERSION:
+       case SLAPI_PLUGIN_OPRETURN:
+       case SLAPI_PLUGIN_OBJECT:
+       case SLAPI_PLUGIN_DESTROY_FN:
+       case SLAPI_PLUGIN_DESCRIPTION:
+       case SLAPI_PLUGIN_INTOP_RESULT:
+       case SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES:
+       case SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS:
+       case SLAPI_PLUGIN_DB_BIND_FN:
+       case SLAPI_PLUGIN_DB_UNBIND_FN:
+       case SLAPI_PLUGIN_DB_SEARCH_FN:
+       case SLAPI_PLUGIN_DB_COMPARE_FN:
+       case SLAPI_PLUGIN_DB_MODIFY_FN:
+       case SLAPI_PLUGIN_DB_MODRDN_FN:
+       case SLAPI_PLUGIN_DB_ADD_FN:
+       case SLAPI_PLUGIN_DB_DELETE_FN:
+       case SLAPI_PLUGIN_DB_ABANDON_FN:
+       case SLAPI_PLUGIN_DB_CONFIG_FN:
+       case SLAPI_PLUGIN_CLOSE_FN:
+       case SLAPI_PLUGIN_DB_FLUSH_FN:
+       case SLAPI_PLUGIN_START_FN:
+       case SLAPI_PLUGIN_DB_SEQ_FN:
+       case SLAPI_PLUGIN_DB_ENTRY_FN:
+       case SLAPI_PLUGIN_DB_REFERRAL_FN:
+       case SLAPI_PLUGIN_DB_RESULT_FN:
+       case SLAPI_PLUGIN_DB_LDIF2DB_FN:
+       case SLAPI_PLUGIN_DB_DB2LDIF_FN:
+       case SLAPI_PLUGIN_DB_BEGIN_FN:
+       case SLAPI_PLUGIN_DB_COMMIT_FN:
+       case SLAPI_PLUGIN_DB_ABORT_FN:
+       case SLAPI_PLUGIN_DB_ARCHIVE2DB_FN:
+       case SLAPI_PLUGIN_DB_DB2ARCHIVE_FN:
+       case SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN:
+       case SLAPI_PLUGIN_DB_FREE_RESULT_SET_FN:
+       case SLAPI_PLUGIN_DB_SIZE_FN:
+       case SLAPI_PLUGIN_DB_TEST_FN:
+       case SLAPI_PLUGIN_DB_NO_ACL:
+       case SLAPI_PLUGIN_EXT_OP_FN:
+       case SLAPI_PLUGIN_EXT_OP_OIDLIST:
+       case SLAPI_PLUGIN_PRE_BIND_FN:
+       case SLAPI_PLUGIN_PRE_UNBIND_FN:
+       case SLAPI_PLUGIN_PRE_SEARCH_FN:
+       case SLAPI_PLUGIN_PRE_COMPARE_FN:
+       case SLAPI_PLUGIN_PRE_MODIFY_FN:
+       case SLAPI_PLUGIN_PRE_MODRDN_FN:
+       case SLAPI_PLUGIN_PRE_ADD_FN:
+       case SLAPI_PLUGIN_PRE_DELETE_FN:
+       case SLAPI_PLUGIN_PRE_ABANDON_FN:
+       case SLAPI_PLUGIN_PRE_ENTRY_FN:
+       case SLAPI_PLUGIN_PRE_REFERRAL_FN:
+       case SLAPI_PLUGIN_PRE_RESULT_FN:
+       case SLAPI_PLUGIN_POST_BIND_FN:
+       case SLAPI_PLUGIN_POST_UNBIND_FN:
+       case SLAPI_PLUGIN_POST_SEARCH_FN:
+       case SLAPI_PLUGIN_POST_COMPARE_FN:
+       case SLAPI_PLUGIN_POST_MODIFY_FN:
+       case SLAPI_PLUGIN_POST_MODRDN_FN:
+       case SLAPI_PLUGIN_POST_ADD_FN:
+       case SLAPI_PLUGIN_POST_DELETE_FN:
+       case SLAPI_PLUGIN_POST_ABANDON_FN:
+       case SLAPI_PLUGIN_POST_ENTRY_FN:
+       case SLAPI_PLUGIN_POST_REFERRAL_FN:
+       case SLAPI_PLUGIN_POST_RESULT_FN:
+       case SLAPI_PLUGIN_MR_FILTER_CREATE_FN:
+       case SLAPI_PLUGIN_MR_INDEXER_CREATE_FN:
+       case SLAPI_PLUGIN_MR_FILTER_MATCH_FN:
+       case SLAPI_PLUGIN_MR_FILTER_INDEX_FN:
+       case SLAPI_PLUGIN_MR_FILTER_RESET_FN:
+       case SLAPI_PLUGIN_MR_INDEX_FN:
+       case SLAPI_PLUGIN_MR_OID:
+       case SLAPI_PLUGIN_MR_TYPE:
+       case SLAPI_PLUGIN_MR_VALUE:
+       case SLAPI_PLUGIN_MR_VALUES:
+       case SLAPI_PLUGIN_MR_KEYS:
+       case SLAPI_PLUGIN_MR_FILTER_REUSABLE:
+       case SLAPI_PLUGIN_MR_QUERY_OPERATOR:
+       case SLAPI_PLUGIN_MR_USAGE:
+       case SLAPI_OP_LESS:
+       case SLAPI_OP_LESS_OR_EQUAL:
+       case SLAPI_PLUGIN_MR_USAGE_INDEX:
+       case SLAPI_PLUGIN_SYNTAX_FILTER_AVA:
+       case SLAPI_PLUGIN_SYNTAX_FILTER_SUB:
+       case SLAPI_PLUGIN_SYNTAX_VALUES2KEYS:
+       case SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA:
+       case SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB:
+       case SLAPI_PLUGIN_SYNTAX_NAMES:
+       case SLAPI_PLUGIN_SYNTAX_OID:
+       case SLAPI_PLUGIN_SYNTAX_FLAGS:
+       case SLAPI_PLUGIN_SYNTAX_COMPARE:
+       case SLAPI_MANAGEDSAIT:
+       case SLAPI_CONFIG_FILENAME:
+       case SLAPI_CONFIG_LINENO:
+       case SLAPI_CONFIG_ARGC:
+       case SLAPI_CONFIG_ARGV:
+       case SLAPI_TARGET_DN:
+       case SLAPI_REQCONTROLS:
+       case SLAPI_ENTRY_PRE_OP:
+       case SLAPI_ENTRY_POST_OP:
+       case SLAPI_RESCONTROLS:
+       case SLAPI_ADD_RESCONTROL:
+       case SLAPI_ADD_ENTRY:
+       case SLAPI_BIND_METHOD:
+       case SLAPI_BIND_CREDENTIALS:
+       case SLAPI_BIND_SASLMECHANISM:
+       case SLAPI_BIND_RET_SASLCREDS:
+       case SLAPI_COMPARE_TYPE:
+       case SLAPI_COMPARE_VALUE:
+       case SLAPI_MODIFY_MODS:
+       case SLAPI_MODRDN_NEWRDN:
+       case SLAPI_MODRDN_DELOLDRDN:
+       case SLAPI_MODRDN_NEWSUPERIOR:
+       case SLAPI_SEARCH_SCOPE:
+       case SLAPI_SEARCH_DEREF:
+       case SLAPI_SEARCH_SIZELIMIT:
+       case SLAPI_SEARCH_TIMELIMIT:
+       case SLAPI_SEARCH_FILTER:
+       case SLAPI_SEARCH_STRFILTER:
+       case SLAPI_SEARCH_ATTRS:
+       case SLAPI_SEARCH_ATTRSONLY:
+       case SLAPI_ABANDON_MSGID:
+       case SLAPI_SEQ_TYPE:
+       case SLAPI_SEQ_ATTRNAME:
+       case SLAPI_SEQ_VAL:
+       case SLAPI_EXT_OP_REQ_OID:
+       case SLAPI_EXT_OP_REQ_VALUE:
+       case SLAPI_EXT_OP_RET_OID:
+       case SLAPI_EXT_OP_RET_VALUE:
+       case SLAPI_MR_FILTER_ENTRY:
+       case SLAPI_MR_FILTER_TYPE:
+       case SLAPI_MR_FILTER_VALUE:
+       case SLAPI_MR_FILTER_OID:
+       case SLAPI_MR_FILTER_DNATTRS:
+       case SLAPI_LDIF2DB_FILE:
+       case SLAPI_LDIF2DB_REMOVEDUPVALS:
+       case SLAPI_DB2LDIF_PRINTKEY:
+       case SLAPI_PARENT_TXN:
+       case SLAPI_TXN:
+       case SLAPI_SEARCH_RESULT_SET:
+       case SLAPI_SEARCH_RESULT_ENTRY:
+       case SLAPI_NENTRIES:
+       case SLAPI_SEARCH_REFERRALS:
+       case SLAPI_CHANGENUMBER:
+       case SLAPI_LOG_OPERATION:
+       case SLAPI_DBSIZE:
+               return LDAP_SUCCESS;
+       default:
+               return INVALID_PARAM;
+       }
+}
+
+static int
+isValidParam( Slapi_PBlock *pb, int param ) 
+{
+       if ( pb->ckParams == TRUE ) {
+               if ( IBM_RESERVED( param ) ) return LDAP_SUCCESS;
+               if (param == SLAPI_PLUGIN_AUDIT_FN ||
+                               param == SLAPI_PLUGIN_AUDIT_DATA )
+                       return LDAP_SUCCESS;
+               if ( param < LAST_IBM_PARAM ) {
+                       return INVALID_PARAM;
+               } else if ( NETSCAPE_RESERVED( param ) ) {
+                       return INVALID_PARAM;
+               } else {
+                       return isOkNetscapeParam(param);
+               }
+       } else {
+               return LDAP_SUCCESS;
+       }
+}
+
+static void
+Lock( Slapi_PBlock *pb )
+{
+       ldap_pvt_thread_mutex_lock(&pb->pblockMutex);
+}
+
+static void
+unLock( Slapi_PBlock *pb )
+{
+       ldap_pvt_thread_mutex_unlock(&pb->pblockMutex);
+}
+
+static int 
+get( Slapi_PBlock *pb, int param, void **val ) 
+{      
+       int i;
+
+       if ( isValidParam( pb, param ) == INVALID_PARAM ) {
+               return PBLOCK_ERROR;
+       }
+       
+       Lock( pb );
+       
+       *val = NULL;
+       for ( i = 0; i < pb->numParams; i++ ) {
+               if ( pb->curParams[i] == param ) {
+                       *val = pb->curVals[i];
+                       break;
+               }
+       }
+       unLock( pb );   
+       return LDAP_SUCCESS;
+}
+
+static int 
+set( Slapi_PBlock *pb, int param, void *val ) 
+{
+#if defined(LDAP_SLAPI)
+       int i;
+
+       if ( isValidParam( pb, param ) == INVALID_PARAM ) {
+               return PBLOCK_ERROR;
+       }
+
+       Lock( pb );     
+
+       if ( pb->numParams == MAX_PARAMS ) {
+               unLock( pb );
+               return PBLOCK_ERROR; 
+       }
+
+       for( i = 0; i < pb->numParams; i++ ) { 
+               if ( pb->curParams[i] == param ) {
+                       break;
+               }
+       }
+
+       if ( i >= pb->numParams ) {
+               pb->curParams[i] = param;
+               pb->numParams++;
+       }
+       pb->curVals[i] = val;
+
+       unLock( pb );   
+       return LDAP_SUCCESS;
+#endif /* LDAP_SLAPI */
+       return PBLOCK_ERROR;
+}
+
+static void
+clearPB( Slapi_PBlock *pb ) 
+{
+       pb->numParams = 1;
+}
+
+static void
+checkParams( Slapi_PBlock *pb, int flag ) 
+{
+       pb->ckParams = flag;
+}
+
+static int
+deleteParam( Slapi_PBlock *p, int param ) 
+{
+       int i;
+
+       Lock(p);
+       for ( i = 0; i < p->numParams; i++ ) { 
+               if ( p->curParams[i] == param ) {
+                       break;
+               }
+       }
+    
+       if (i >= p->numParams ) {
+               unLock( p );
+               return PBLOCK_ERROR;
+       }
+       if ( p->numParams > 1 ) {
+               p->curParams[i] = p->curParams[p->numParams];
+               p->curVals[i] = p->curVals[p->numParams];
+       }
+       p->numParams--;
+       unLock( p );    
+       return LDAP_SUCCESS;
+}
+
+Slapi_PBlock *
+slapi_pblock_new() 
+{
+#if defined(LDAP_SLAPI)
+       Slapi_PBlock *pb;
+
+       pb = (Slapi_PBlock *) ch_malloc(sizeof(Slapi_PBlock));
+       if ( pb != NULL ) {
+               pb->ckParams = TRUE;
+               ldap_pvt_thread_mutex_init( &pb->pblockMutex );
+               memset( pb->curParams, 0, sizeof(pb->curParams) );
+               memset( pb->curVals, 0, sizeof(pb->curVals) );
+               pb->curParams[0] = SLAPI_IBM_PBLOCK;
+               pb->curVals[0] = NULL;
+               pb->numParams = 1;
+       }
+       return pb;
+#endif /* LDAP_SLAPI */
+       return NULL;
+}
+
+void 
+slapi_pblock_destroy( Slapi_PBlock* pb ) 
+{
+#if defined(LDAP_SLAPI)
+       char *str = NULL;
+
+       get( pb, SLAPI_CONN_DN,(void **)&str );
+       if ( str != NULL ) {
+               ch_free( str );
+               str = NULL;
+       }
+
+       get( pb, SLAPI_CONN_AUTHTYPE, (void **)&str );
+       if ( str != NULL ) {
+               ch_free( str );
+               str = NULL;
+       }
+
+       get( pb, SLAPI_IBM_CONN_DN_ALT, (void **)&str );
+       if ( str != NULL ) {
+               ch_free( str );
+               str = NULL;
+       }
+
+       get( pb, SLAPI_IBM_CONN_DN_ORIG, (void **)&str );
+       if ( str != NULL ) {
+               ch_free( str );
+       }
+
+       ldap_pvt_thread_mutex_destroy( &pb->pblockMutex );
+
+       ch_free( pb ); 
+#endif /* LDAP_SLAPI */
+}
+
+int 
+slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value ) 
+{
+#if defined(LDAP_SLAPI)
+       return get( pb, arg, (void **)value );
+#endif /* LDAP_SLAPI */
+       return PBLOCK_ERROR;
+}
+
+int 
+slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value ) 
+{
+#if defined(LDAP_SLAPI)
+       void *pTmp = NULL;
+
+       switch ( arg ) {
+        case SLAPI_CONN_DN:
+        case SLAPI_CONN_AUTHTYPE:
+        case SLAPI_IBM_CONN_DN_ALT:
+        case SLAPI_IBM_CONN_DN_ORIG:
+               if ( value != NULL ) {
+                       pTmp = (void *)slapi_ch_strdup((char *)value);
+                       if ( pTmp == NULL ) {
+                               return LDAP_NO_MEMORY;
+                       }
+               }
+               break;
+       default:
+               pTmp = value;
+               break;
+       }
+       return set( pb, arg, pTmp );
+#endif /* LDAP_SLAPI */
+       return LDAP_NO_MEMORY;
+}
+
+void
+slapi_pblock_clear( Slapi_PBlock *pb ) 
+{
+#if defined(LDAP_SLAPI)
+   clearPB( pb );
+#endif /* LDAP_SLAPI */
+}
+
+int 
+slapi_pblock_delete_param( Slapi_PBlock *p, int param ) 
+{
+#if defined(LDAP_SLAPI)
+       return deleteParam( p, param );
+#endif /* LDAP_SLAPI */
+       return PBLOCK_ERROR;
+}
+
+void
+slapi_pblock_check_params( Slapi_PBlock *pb, int flag ) 
+{
+#if defined(LDAP_SLAPI)
+       checkParams( pb, flag );
+#endif /* LDAP_SLAPI */
+}
+
diff --git a/servers/slapd/slapi/slapi_pblock.h b/servers/slapd/slapi/slapi_pblock.h
new file mode 100644 (file)
index 0000000..d5087a8
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#ifndef SLAPI_PBLOCK_H
+#define SLAPI_PBLOCK_H
+
+#define CMP_EQUAL 0
+#define CMP_GREATER 1
+#define CMP_LOWER (-1)
+#define PBLOCK_ERROR (-1)
+#define INVALID_PARAM PBLOCK_ERROR
+#define MAX_PARAMS 100
+
+struct slapi_pblock {
+       ldap_pvt_thread_mutex_t pblockMutex;
+       int                     ckParams;
+       int                     numParams;
+       int                     curParams[MAX_PARAMS];
+       void                    *curVals[MAX_PARAMS];
+};
+
+Slapi_PBlock *slapi_pblock_new();
+void slapi_pblock_destroy( Slapi_PBlock* );
+int slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value );
+int slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value );
+void slapi_pblock_check_params(Slapi_PBlock *pb, int flag);
+int slapi_pblock_delete_param(Slapi_PBlock *p, int param);
+void slapi_pblock_clear(Slapi_PBlock *pb); 
+
+#endif /* SLAPI_PBLOCK_H */
+
diff --git a/servers/slapd/slapi/slapi_utils.c b/servers/slapd/slapi/slapi_utils.c
new file mode 100644 (file)
index 0000000..2c90e82
--- /dev/null
@@ -0,0 +1,1132 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#include "portable.h"
+#include "slapi_common.h"
+
+#include <slap.h>
+#include <slapi.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <slap.h>
+#include <unistd.h>
+#include <ldap_pvt.h>
+
+struct berval *ns_get_supported_extop( int );
+
+#ifdef _SPARC  
+#include <sys/systeminfo.h>
+#endif
+
+#include <netdb.h>
+
+/*
+ * server start time (should we use a struct timeval also in slapd?
+ */
+static struct                  timeval base_time;
+ldap_pvt_thread_mutex_t                slapi_hn_mutex;
+ldap_pvt_thread_mutex_t                slapi_time_mutex;
+
+/*
+ * This function converts an array of pointers to berval objects to
+ * an array of berval objects.
+ */
+
+int
+bvptr2obj(
+       struct berval   **bvptr, 
+       BerVarray       *bvobj )
+{
+       int             rc = LDAP_SUCCESS;
+       int             i;
+       BerVarray       tmpberval;
+
+       if ( bvptr == NULL || *bvptr == NULL ) {
+               return LDAP_OTHER;
+       }
+
+       for ( i = 0; bvptr != NULL && bvptr[i] != NULL; i++ ) {
+               ; /* EMPTY */
+       }
+
+       tmpberval = (BerVarray)slapi_ch_malloc( (i + 1)*sizeof(struct berval));
+       if ( tmpberval == NULL ) {
+               return LDAP_NO_MEMORY;
+       } 
+
+       for ( i = 0; bvptr[i] != NULL; i++ ) {
+               tmpberval[i].bv_val = bvptr[i]->bv_val;
+               tmpberval[i].bv_len = bvptr[i]->bv_len;
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               *bvobj = tmpberval;
+       }
+
+       return rc;
+}
+
+Slapi_Entry *
+slapi_str2entry(
+       char            *s, 
+       int             check_dup )
+{
+#if defined(LDAP_SLAPI)
+       Slapi_Entry     *e = NULL;
+       char            *pTmpS;
+
+       pTmpS = slapi_ch_strdup( s );
+       if ( pTmpS != NULL ) {
+               e = str2entry( pTmpS ); 
+               slapi_ch_free( pTmpS );
+       }
+
+       return e;
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+char *
+slapi_entry2str(
+       Slapi_Entry     *e, 
+       int             *len ) 
+{
+#if defined(LDAP_SLAPI)
+       char            *ret;
+
+       ldap_pvt_thread_mutex_lock( &entry2str_mutex );
+       ret = entry2str( e, len );
+       ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
+
+       return ret;
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+char *
+slapi_entry_get_dn( Slapi_Entry *e ) 
+{
+#if defined(LDAP_SLAPI)
+       return e->e_name.bv_val;
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+void 
+slapi_entry_set_dn(
+       Slapi_Entry     *e, 
+       char            *ldn )
+{
+#if defined(LDAP_SLAPI)
+       struct berval   dn = { 0, NULL };
+
+       dn.bv_val = ldn;
+       dn.bv_len = strlen( ldn );
+
+       dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
+#endif /* defined(LDAP_SLAPI) */
+}
+
+Slapi_Entry *
+slapi_entry_dup( Slapi_Entry *e ) 
+{
+#if defined(LDAP_SLAPI)
+       char            *tmp = NULL;
+       Slapi_Entry     *tmpEnt;
+       int             len = 0;
+       
+       tmp = slapi_entry2str( e, &len );
+       if ( tmp == NULL ) {
+               return (Slapi_Entry *)NULL;
+       }
+
+       tmpEnt = (Slapi_Entry *)str2entry( tmp );
+       if ( tmpEnt == NULL ) { 
+               slapi_ch_free( tmp );
+               return (Slapi_Entry *)NULL;
+       }
+       
+       if (tmp != NULL) {
+               slapi_ch_free( tmp );
+       }
+
+       return tmpEnt;
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_entry_attr_delete(
+       Slapi_Entry     *e,             
+       char            *type ) 
+{
+#if defined(LDAP_SLAPI)
+       AttributeDescription    *ad;
+       const char              *text;
+
+       if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
+               return 1;       /* LDAP_NO_SUCH_ATTRIBUTE */
+       }
+
+       if ( attr_delete( &e->e_attrs, ad ) == LDAP_SUCCESS ) {
+               return 0;       /* attribute is deleted */
+       } else {
+               return -1;      /* something went wrong */
+       }
+#else /* !defined(LDAP_SLAPI) */
+       return -1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+Slapi_Entry *
+slapi_entry_alloc( void ) 
+{
+#if defined(LDAP_SLAPI)
+       return (Slapi_Entry *)slapi_ch_calloc( 1, sizeof(Slapi_Entry) );
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+void 
+slapi_entry_free( Slapi_Entry *e ) 
+{
+#if defined(LDAP_SLAPI)
+       entry_free( e );
+#endif /* defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_entry_attr_merge(
+       Slapi_Entry     *e, 
+       char            *type, 
+       struct berval   **vals ) 
+{
+#if defined(LDAP_SLAPI)
+       AttributeDescription    *ad;
+       const char              *text;
+       BerVarray               bv;
+       int                     rc;
+
+       rc = bvptr2obj( vals, &bv );
+       if ( rc != LDAP_SUCCESS ) {
+               return -1;
+       }
+       
+       rc = slap_str2ad( type, &ad, &text );
+       if ( rc != LDAP_SUCCESS ) {
+               return -1;
+       }
+       
+       rc = attr_merge( e, ad, bv );
+       ch_free( bv );
+
+       return rc;
+#else /* !defined(LDAP_SLAPI) */
+       return -1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+int
+slapi_entry_attr_find(
+       Slapi_Entry     *e, 
+       char            *type, 
+       Slapi_Attr      **attr ) 
+{
+#if defined(LDAP_SLAPI)
+       AttributeDescription    *ad;
+       const char              *text;
+       int                     rc;
+
+       rc = slap_str2ad( type, &ad, &text );
+       if ( rc != LDAP_SUCCESS ) {
+               return -1;
+       }
+
+       *attr = attr_find( e->e_attrs, ad );
+       if ( *attr == NULL ) {
+               return -1;
+       }
+
+       return 0;
+#else /* !defined(LDAP_SLAPI) */
+       return -1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+/* 
+ * FIXME -- The caller must free the allocated memory. 
+ * In Netscape they do not have to.
+ */
+int 
+slapi_attr_get_values(
+       Slapi_Attr      *attr, 
+       struct berval   ***vals ) 
+{
+#if defined(LDAP_SLAPI)
+       int             i, j;
+       struct berval   **bv;
+
+       if ( attr == NULL ) {
+               return 1;
+       }
+
+       for ( i = 0; attr->a_vals[i].bv_val != NULL; i++ ) {
+               ; /* EMPTY */
+       }
+
+       bv = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
+       for ( j = 0; j < i; j++ ) {
+               bv[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
+               bv[j]->bv_val = ch_strdup( attr->a_vals[j].bv_val );
+               bv[j]->bv_len = attr->a_vals[j].bv_len;
+       }
+       bv[j] = NULL;
+       
+       *vals = (struct berval **)bv;
+
+       return 0;
+#else /* !defined(LDAP_SLAPI) */
+       return -1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+char *
+slapi_dn_normalize( char *dn ) 
+{
+#if defined(LDAP_SLAPI)
+       struct berval   bdn;
+       struct berval   ndn;
+
+       assert( dn != NULL );
+       
+       bdn.bv_val = dn;
+       bdn.bv_len = strlen( dn );
+
+       dnNormalize2( NULL, &bdn, &ndn );
+
+       /*
+        * FIXME: ain't it safe to set dn = ndn.bv_val ?
+        */
+       dn = ch_strdup( ndn.bv_val );
+       ch_free( ndn.bv_val );
+       
+       return dn;
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+/*
+ * FIXME: this function is dangerous and should be deprecated;
+ * DN normalization is a lot more than lower-casing, and BTW
+ * OpenLDAP's DN normalization for case insensitive attributes
+ * is already lower case
+ */
+char *
+slapi_dn_normalize_case( char *dn ) 
+{
+#if defined(LDAP_SLAPI)
+       slapi_dn_normalize( dn );
+       ldap_pvt_str2lower( dn );
+
+       return dn;
+#else /* defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_dn_issuffix(
+       char            *dn, 
+       char            *suffix )
+{
+#if defined(LDAP_SLAPI)
+       struct berval   bdn, ndn;
+       struct berval   bsuffix, nsuffix;
+
+       assert( dn != NULL );
+       assert( suffix != NULL );
+
+       bdn.bv_val = dn;
+       bdn.bv_len = strlen( dn );
+
+       bsuffix.bv_val = suffix;
+       bsuffix.bv_len = strlen( suffix );
+
+       dnNormalize2( NULL, &bdn, &ndn );
+       dnNormalize2( NULL, &bsuffix, &nsuffix );
+
+       return dnIsSuffix( &ndn, &nsuffix );
+#else /* !defined(LDAP_SLAPI) */
+       return 0;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+char *
+slapi_dn_ignore_case( char *dn )
+{       
+#if defined(LDAP_SLAPI)
+       return slapi_dn_normalize_case( dn );
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+char *
+slapi_ch_malloc( unsigned long size ) 
+{
+#if defined(LDAP_SLAPI)
+       return ch_malloc( size );       
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+void 
+slapi_ch_free( void *ptr ) 
+{
+#if defined(LDAP_SLAPI)
+#if 0
+       if ( ptr != NULL )      /* not required ... */
+#endif /* 0 */
+               ch_free( ptr );
+#endif /* defined(LDAP_SLAPI) */
+}
+
+char *
+slapi_ch_calloc(
+       unsigned long nelem, 
+       unsigned long size ) 
+{
+#if defined(LDAP_SLAPI)
+       return ch_calloc( nelem, size );
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+char *
+slapi_ch_realloc(
+       char *block, 
+       unsigned long size ) 
+{
+#if defined(LDAP_SLAPI)
+       return ch_realloc( block, size );
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+char *
+slapi_ch_strdup( char *s ) 
+{
+#if defined(LDAP_SLAPI)
+       return ch_strdup( (const char *)s );
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+size_t
+slapi_ch_stlen( char *s ) 
+{
+#if defined(LDAP_SLAPI)
+       return strlen( (const char *)s );
+#else /* !defined(LDAP_SLAPI) */
+       return 0;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_control_present(
+       LDAPControl     **controls, 
+       char            *oid, 
+       struct berval   **val, 
+       int             *iscritical ) 
+{
+#if defined(LDAP_SLAPI)
+       int             i;
+       int             rc = 0;
+
+       if ( val ) {
+               *val = NULL;
+       }
+       
+       if ( iscritical ) {
+               *iscritical = 0;
+       }
+       
+       for ( i = 0; controls != NULL && controls[i] != NULL; i++ ) {
+               if ( strcmp( controls[i]->ldctl_oid, oid ) != 0 ) {
+                       continue;
+               }
+
+               rc = 1;
+               if ( controls[i]->ldctl_value.bv_len != 0 ) {
+                       /*
+                        * FIXME: according to 6.1 specification,
+                        *    "The val output parameter is set
+                        *    to point into the controls array.
+                        *    A copy of the control value is
+                        *    not made."
+                        */
+#if 0
+                       struct berval   *pTmpBval;
+
+                       pTmpBval = (struct berval *)slapi_ch_malloc( sizeof(struct berval));
+                       if ( pTmpBval == NULL ) {
+                               rc = 0;
+                       } else {
+                               pTmpBval->bv_len = controls[i]->ldctl_value.bv_len;
+                               pTmpBval->bv_val = controls[i]->ldctl_value.bv_val;
+                               if ( val ) {
+                                       *val = pTmpBval;
+                               } else {
+                                       slapi_ch_free( pTmpBval );
+                                       rc = 0;
+                               }
+                       }
+#endif /* 0 */
+                       if ( val ) {
+                               *val = &controls[i]->ldctl_value;
+                       }
+               }
+
+               if ( iscritical ) {
+                       *iscritical = controls[i]->ldctl_iscritical;
+               }
+
+               break;
+       }
+
+       return rc;
+#else /* !defined(LDAP_SLAPI) */
+       return 0;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+void 
+slapi_register_supported_control(
+       char            *controloid, 
+       unsigned long   controlops )
+{
+#if defined(LDAP_SLAPI)
+       /* FIXME -- can not add controls to openLDAP dynamically */
+       slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_CONTROLS",
+                       "can not add controls to openLDAP dynamically\n" );
+#endif /* defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_get_supported_controls(
+       char            ***ctrloidsp, 
+       unsigned long   **ctrlopsp ) 
+{
+#if defined(LDAP_SLAPI)
+       int             i, n;
+       int             rc = 1;
+       char            **oids = NULL;
+       unsigned long   *masks = NULL;
+
+       for (n = 0; get_supported_ctrl( n ) != NULL; n++) {
+               ; /* count them */
+       }
+       
+       if ( n == 0 ) {
+               /* no controls */
+               *ctrloidsp = NULL;
+               *ctrlopsp = NULL;
+               return LDAP_SUCCESS;
+       }
+
+
+       oids = (char **)slapi_ch_malloc( (n + 1) * sizeof(char *) );
+       if ( oids == NULL ) {
+               rc = LDAP_NO_MEMORY;
+               goto error_return;
+       }
+
+       masks = (unsigned long *)slapi_ch_malloc( n * sizeof(int) );
+       if ( masks == NULL ) {
+               rc = LDAP_NO_MEMORY;
+               goto error_return;
+       }
+
+       for ( i = 0; i < n; i++ ) {
+               /*
+                * FIXME: Netscape's specification says nothing about
+                * memory; should we copy the OIDs or return pointers
+                * to internal values? In OpenLDAP the latter is safe
+                * since we do not allow to register coltrols runtime
+                */
+               oids[ i ] = ch_strdup( get_supported_ctrl( i ) );
+               if ( oids[ i ] == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+                       goto error_return;
+               }
+               masks[ i ] = (unsigned long)get_supported_ctrl_mask( i );
+       }
+
+       *ctrloidsp = oids;
+       *ctrlopsp = masks;
+       return LDAP_SUCCESS;
+
+error_return:
+       if ( rc != LDAP_SUCCESS ) {
+               for ( i = 0; oids != NULL && oids[ i ] != NULL; i++ ) {
+                       ch_free( oids[ i ] );
+               }
+               ch_free( oids );
+               ch_free( masks );
+       }
+
+       return rc;
+#else /* !defined(LDAP_SLAPI) */
+       return 1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+void 
+slapi_register_supported_saslmechanism( char *mechanism )
+{
+#if defined(LDAP_SLAPI)
+       /* FIXME -- can not add saslmechanism to openLDAP dynamically */
+       slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
+                       "can not add saslmechanism to openLDAP dynamically\n" );
+#endif /* defined(LDAP_SLAPI) */
+}
+
+char **
+slapi_get_supported_saslmechanisms( void )
+{
+#if defined(LDAP_SLAPI)
+       /* FIXME -- can not get the saslmechanism wihtout a connection. */
+       slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
+                       "can not get the saslmechanism "
+                       "wihtout a connection\n" );
+       return NULL;
+#else /* defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* defined(LDAP_SLAPI) */
+}
+
+char **
+slapi_get_supported_extended_ops( void )
+{
+#if defined(LDAP_SLAPI)
+       int             i, j, k;
+       char            **ppExtOpOID = NULL;
+       int             numExtOps = 0;
+
+       for ( i = 0; get_supported_extop( i ) != NULL; i++ ) {
+               ;
+       }
+       
+       for ( j = 0; ns_get_supported_extop( j ) != NULL; j++ ) {
+               ;
+       }
+
+       numExtOps = i + j;
+       if ( numExtOps == 0 ) {
+               return NULL;
+       }
+
+       ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps + 1) * sizeof(char *) );
+       for ( k = 0; k < i; k++ ) {
+               struct berval   *bv;
+
+               bv = get_supported_extop( k );
+               assert( bv != NULL );
+
+               ppExtOpOID[ k ] = bv->bv_val;
+       }
+       
+       for ( ; k < j; k++ ) {
+               struct berval   *bv;
+
+               bv = ns_get_supported_extop( k );
+               assert( bv != NULL );
+
+               ppExtOpOID[ i + k ] = bv->bv_val;
+       }
+       ppExtOpOID[ i + k ] = NULL;
+
+       return ppExtOpOID;
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+void 
+slapi_send_ldap_result(
+       Slapi_PBlock    *pb, 
+       int             err, 
+       char            *matched, 
+       char            *text, 
+       int             nentries, 
+       struct berval   **urls ) 
+{
+#if defined(LDAP_SLAPI)
+       Connection      *conn;
+       Operation       *op;
+       struct berval   *s;
+       char            *extOID = NULL;
+       struct berval   *extValue = NULL;
+       int             rc;
+
+       slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
+       slapi_pblock_get( pb, SLAPI_OPERATION, &op );
+       if ( err == LDAP_SASL_BIND_IN_PROGRESS ) {
+               slapi_pblock_get( pb, SLAPI_BIND_RET_SASLCREDS, &s );
+               rc = LDAP_SASL_BIND_IN_PROGRESS;
+               send_ldap_sasl( conn, op, rc, NULL, NULL, NULL, NULL, s );
+               return;
+       }
+
+       slapi_pblock_get( pb, SLAPI_EXT_OP_RET_OID, &extOID );
+       if ( extOID != NULL ) {
+               slapi_pblock_get( pb, SLAPI_EXT_OP_RET_VALUE, &extValue );
+               slapi_send_ldap_extended_response( conn, op, err, extOID,
+                               extValue );
+               return;
+       }
+
+       send_ldap_result( conn, op, err, matched, text, NULL, NULL );
+#endif /* defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_send_ldap_search_entry(
+       Slapi_PBlock    *pb, 
+       Slapi_Entry     *e, 
+       LDAPControl     **ectrls, 
+       char            **attrs, 
+       int             attrsonly )
+{
+#if defined(LDAP_SLAPI)
+       Backend         *be;
+       Connection      *pConn;
+       Operation       *pOp;
+       int             rc;
+
+       int             i;
+       AttributeName   *an = NULL;
+       const char      *text;
+
+       for ( i = 0; attrs[ i ] != NULL; i++ ) {
+               ; /* empty */
+       }
+
+       if ( i > 0 ) {
+               an = (AttributeName *) ch_malloc( i * sizeof(AttributeName) );
+               for ( i = 0; attrs[i] != NULL; i++ ) {
+                       an[i].an_name.bv_val = ch_strdup( attrs[i] );
+                       an[i].an_name.bv_len = strlen( attrs[i] );
+                       an[i].an_desc = NULL;
+                       if( slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text ) != LDAP_SUCCESS)
+                               return -1;
+               }
+       }
+
+       if ( ( rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) ||
+                       ( rc = slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&pConn) != 0 ) ||
+                       ( rc = slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&pOp) != 0 ) ) {
+               rc = LDAP_OTHER;
+       } else {
+               rc = send_search_entry( be, pConn, pOp, e, an, attrsonly, NULL );
+       }
+
+       return rc;
+
+#else /* !defined(LDAP_SLAPI) */
+       return -1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+
+Slapi_Filter *
+slapi_str2filter( char *str ) 
+{
+#if defined(LDAP_SLAPI)
+       return str2filter( str );
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+void 
+slapi_filter_free(
+       Slapi_Filter    *f, 
+       int             recurse ) 
+{
+#if defined(LDAP_SLAPI)
+       filter_free( f );
+#endif /* defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_filter_get_choice( Slapi_Filter *f )
+{
+#if defined(LDAP_SLAPI)
+       int             rc;
+
+       if ( f != NULL ) {
+               rc = f->f_choice;
+       } else {
+               rc = 0;
+       }
+
+       return rc;
+#else /* !defined(LDAP_SLAPI) */
+       return -1;              /* invalid filter type */
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_filter_get_ava(
+       Slapi_Filter    *f, 
+       char            **type, 
+       struct berval   **bval )
+{
+#if defined(LDAP_SLAPI)
+       int             ftype;
+       int             rc = LDAP_SUCCESS;
+
+       assert( type != NULL );
+       assert( bval != NULL );
+
+       *type = NULL;
+       *bval = NULL;
+
+       ftype = f->f_choice;
+       if ( ftype == LDAP_FILTER_EQUALITY 
+                       || ftype ==  LDAP_FILTER_GE 
+                       || ftype == LDAP_FILTER_LE 
+                       || ftype == LDAP_FILTER_APPROX ) {
+               *type = slapi_ch_strdup( f->f_un.f_un_ava->aa_desc->ad_cname.bv_val );
+               if ( *type == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+                       goto done;
+               }
+
+               *bval = (struct berval *)slapi_ch_malloc( sizeof(struct berval) );
+               if ( *bval == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+                       goto done;
+               }
+
+               (*bval)->bv_len = f->f_un.f_un_ava->aa_value.bv_len;
+               (*bval)->bv_val = slapi_ch_strdup( f->f_un.f_un_ava->aa_value.bv_val );
+               if ( (*bval)->bv_val == NULL ) {
+                       rc = LDAP_NO_MEMORY;
+                       goto done;
+               }
+       } else { /* filter type not supported */
+               rc = -1;
+       }
+
+done:
+       if ( rc != LDAP_SUCCESS ) {
+               if ( *bval ) {
+                       ch_free( *bval );
+                       *bval = NULL;
+               }
+
+               if ( *type ) {
+                       ch_free( *type );
+                       *type = NULL;
+               }
+       }
+
+       return rc;
+#else /* !defined(LDAP_SLAPI) */
+       return -1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+Slapi_Filter *
+slapi_filter_list_first( Slapi_Filter *f )
+{
+#if defined(LDAP_SLAPI)
+       int             ftype;
+
+       if ( f == NULL ) {
+               return NULL;
+       }
+
+       ftype = f->f_choice;
+       if ( ftype == LDAP_FILTER_AND
+                       || ftype == LDAP_FILTER_OR
+                       || ftype == LDAP_FILTER_NOT ) {
+               return (Slapi_Filter *)f->f_and;
+       } else {
+               return NULL;
+       }
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+Slapi_Filter *
+slapi_filter_list_next(
+       Slapi_Filter    *f, 
+       Slapi_Filter    *fprev )
+{
+#if defined(LDAP_SLAPI)
+       int             ftype;
+
+       if ( f == NULL ) {
+               return NULL;
+       }
+
+       ftype = f->f_choice;
+       if ( ftype == LDAP_FILTER_AND
+                       || ftype == LDAP_FILTER_OR
+                       || ftype == LDAP_FILTER_NOT ) {
+               if ( f->f_and == fprev ) {
+                       return f->f_and->f_next;
+               }
+       }
+
+       return NULL;
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_send_ldap_extended_response(
+       Connection      *conn, 
+       Operation       *op,
+       int             errornum, 
+       char            *respName,
+       struct berval   *response )
+{
+#if defined(LDAP_SLAPI)
+       send_ldap_extended( conn,op, errornum, NULL, NULL, NULL,
+                       respName,response, NULL );
+       return LDAP_SUCCESS;
+#else /* !defined(LDAP_SLAPI) */
+       return -1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+int 
+slapi_pw_find(
+       struct berval   **vals, 
+       struct berval   *v ) 
+{
+#if defined(LDAP_SLAPI)
+       /*
+        * FIXME: what's the point?
+        */
+       return 1;
+#else /* !defined(LDAP_SLAPI) */
+       return 1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+             
+char *
+slapi_get_hostname( void ) 
+{
+#if defined(LDAP_SLAPI)
+       char            *hn = NULL;
+
+       /*
+        * FIXME: I'd prefer a different check ...
+        */
+#if defined _SPARC 
+       hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
+       if ( hn == NULL) {
+               slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
+                               "can't malloc memory for hostname\n" );
+               hn = NULL;
+               
+       } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) {
+               slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
+                               "can't get hostname\n" );
+               slapi_ch_free( hn );
+               hn = NULL;
+       }
+#else /* !_SPARC */
+       static int      been_here = 0;   
+       static char     *static_hn = NULL;
+
+       ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
+       if ( !been_here ) {
+               static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
+               if ( static_hn == NULL) {
+                       slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
+                                       "can't malloc memory for hostname\n" );
+                       static_hn = NULL;
+                       ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
+
+                       return hn;
+                       
+               } else { 
+                       if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
+                               slapi_log_error( SLAPI_LOG_FATAL,
+                                               "SLAPI_SYSINFO",
+                                               "can't get hostname\n" );
+                               slapi_ch_free( static_hn );
+                               static_hn = NULL;
+                               ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
+
+                               return hn;
+
+                       } else {
+                               been_here = 1;
+                       }
+               }
+       }
+       ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
+       
+       hn = ch_strdup( static_hn );
+#endif /* !_SPARC */
+
+       return hn;
+#else /* !defined(LDAP_SLAPI) */
+       return NULL;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+/*
+ * FIXME: this should go in an appropriate header ...
+ */
+extern int vLogError( int level, char *subsystem, char *fmt, va_list arglist );
+
+int 
+slapi_log_error(
+       int             severity, 
+       char            *subsystem, 
+       char            *fmt, 
+       ... ) 
+{
+#if defined(LDAP_SLAPI)
+       int             rc = LDAP_SUCCESS;
+       va_list         arglist;
+
+       va_start( arglist, fmt );
+       rc = vLogError( severity, subsystem, fmt, arglist );
+       va_end( arglist );
+
+       return rc;
+#else /* !defined(LDAP_SLAPI) */
+       return -1;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+
+unsigned long
+slapi_timer_current_time( void ) 
+{
+#if defined(LDAP_SLAPI)
+       static int      first_time = 1;
+#if !defined (_WIN32)
+       struct timeval  now;
+       unsigned long   ret;
+
+       ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
+       if (first_time) {
+               first_time = 0;
+               gettimeofday( &base_time, NULL );
+       }
+       gettimeofday( &now, NULL );
+       ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
+                       (now.tv_usec - base_time.tv_usec);
+       ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
+
+       return ret;
+
+       /*
+        * Ain't it better?
+       return (slap_get_time() - starttime) * 1000000;
+        */
+#else /* _WIN32 */
+       LARGE_INTEGER now;
+
+       if ( first_time ) {
+               first_time = 0;
+               performance_counter_present = QueryPerformanceCounter( &base_time );
+               QueryPerformanceFrequency( &performance_freq );
+       }
+
+       if ( !performance_counter_present )
+            return 0;
+
+       QueryPerformanceCounter( &now );
+       return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
+#endif /* _WIN32 */
+#else /* !defined(LDAP_SLAPI) */
+       return 0;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+/*
+ * FIXME ?
+ */
+unsigned long
+slapi_timer_get_time( char *label ) 
+{
+#if defined(LDAP_SLAPI)
+       unsigned long start = slapi_timer_current_time();
+       printf("%10ld %10ld usec %s\n", start, 0, label);
+       return start;
+#else /* !defined(LDAP_SLAPI) */
+       return 0;
+#endif /* !defined(LDAP_SLAPI) */
+}
+
+/*
+ * FIXME ?
+ */
+void
+slapi_timer_elapsed_time(
+       char *label,
+       unsigned long start ) 
+{
+#if defined(LDAP_SLAPI)
+       unsigned long stop = slapi_timer_current_time();
+       printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
+#endif /* defined(LDAP_SLAPI) */
+}
+
+void
+slapi_free_search_results_internal( Slapi_PBlock *pb ) 
+{
+#if defined(LDAP_SLAPI)
+       Slapi_Entry     **entries;
+       int             k = 0, nEnt = 0;
+
+       slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
+       slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
+       if ( nEnt == 0 ) {
+               return;
+       }
+       
+       if ( entries == NULL ) {
+               return;
+       }
+       
+       for ( k = 0; k < nEnt; k++ ) {
+               slapi_entry_free( entries[k] );
+       }
+       
+       slapi_ch_free( entries );
+#endif /* defined(LDAP_SLAPI) */
+}
+
diff --git a/servers/slapd/slapi/slapi_utils.h b/servers/slapd/slapi/slapi_utils.h
new file mode 100644 (file)
index 0000000..9bdd05b
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * (C) Copyright IBM Corp. 1997,2002
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is 
+ * given to IBM Corporation. This software is provided ``as is'' 
+ * without express or implied warranty.
+ */
+
+#ifndef _SLAPI_UTILS_H
+#define _SLAPI_UTILS_H
+
+struct _Audit_record;
+typedef struct _Audit_record Audit_record;
+
+#define SLAPI_CONTROL_MANAGEDSAIT_OID "2.16.840.1.113730.3.4.2"
+#define SLAPI_CONTROL_SORTEDSEARCH_OID "1.2.840.113556.1.4.473"
+#define SLAPI_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319"
+
+typedef int (*SLAPI_FUNC)(Slapi_PBlock *pb);
+
+#define MAX_HOSTNAME 512
+
+#define DOMAIN "Domain"
+#define TCPIPPATH "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+
+typedef struct _slapi_control {
+        int           s_ctrl_num;
+        char          **s_ctrl_oids;
+        unsigned long *s_ctrl_ops;
+} Slapi_Control;
+
+typedef struct _ExtendedOp {
+       struct berval ext_oid;
+        SLAPI_FUNC ext_func;
+        Backend    *ext_be;
+        struct _ExtendedOp *ext_next;
+} ExtendedOp;
+
+int slapi_log_error( int severity, char *subsystem, char *fmt, ... );
+Slapi_Entry *slapi_str2entry( char *s, int flags );
+char *slapi_entry2str( Slapi_Entry *e, int *len );
+int slapi_entry_attr_merge( Slapi_Entry *e, char *type, struct berval **vals );
+int slapi_entry_attr_find( Slapi_Entry *e, char *type, Slapi_Attr **attr );
+int slapi_entry_attr_delete( Slapi_Entry *e, char *type );
+char *slapi_entry_get_dn( Slapi_Entry *e );
+void slapi_entry_set_dn( Slapi_Entry *e, char *dn );
+Slapi_Entry *slapi_entry_dup( Slapi_Entry *e );
+Slapi_Entry *slapi_entry_alloc();
+void slapi_entry_free( Slapi_Entry *e );
+int slapi_attr_get_values( Slapi_Attr *attr, struct berval ***vals );
+char *slapi_ch_malloc( unsigned long size );
+void slapi_ch_free( void *ptr );
+char *slapi_ch_calloc( unsigned long nelem, unsigned long size );
+char *slapi_ch_realloc( char *block, unsigned long size );
+char *slapi_ch_strdup( char *s );
+/*
+ * FIXME: these two were missing, but widely used in a couple of .c files
+ */
+size_t slapi_strlen(char *s );
+#define slapi_ch_stlen(s)      slapi_strlen(s)
+/* end of FIXME */
+char *slapi_dn_normalize( char *dn );
+char *slapi_dn_normalize_case( char *dn );
+char * slapi_esc_dn_normalize( char *dn );
+char * slapi_esc_dn_normalize_case( char *dn );
+int slapi_dn_isroot( Slapi_PBlock *pb, char *dn );
+int slapi_dn_issuffix( char *dn, char *suffix );
+char *slapi_dn_ignore_case( char *dn );
+char *slapi_get_hostname();
+void slapi_register_supported_saslmechanism( char *mechanism );
+void slapi_send_ldap_result( Slapi_PBlock *pb, int err, 
+       char *matched, char *text, int nentries, struct berval **urls );
+int slapi_send_ldap_extended_response(Connection *conn, Operation *op, 
+                       int errornum, char *respName, struct berval *response);
+int slapi_send_ldap_search_entry( Slapi_PBlock *pb, Slapi_Entry *e, 
+                       LDAPControl **ectrls, char **attrs, int attrsonly ); 
+void slapi_register_supported_control(char *controloid, 
+                                       unsigned long controlops);
+int slapi_get_supported_controls(char ***ctrloidsp, unsigned long **ctrlopsp);
+int slapi_control_present( LDAPControl **controls, char *oid, 
+                               struct berval **val, int *iscritical);
+void slapi_register_supported_saslmechanism(char *mechanism);
+char **slapi_get_supported_saslmechanisms();
+char **slapi_get_supported_extended_ops(void);
+int checkControlHonored(LDAPControl **controls, char *pControlOid, 
+                               unsigned long operation, int *isHonored );
+void slapi_broadcast_be(int funcType, Slapi_PBlock *pPB);
+Slapi_Filter *slapi_str2filter( char *str );
+void slapi_filter_free( Slapi_Filter *f, int recurse );
+int slapi_filter_get_choice( Slapi_Filter *f);
+int slapi_filter_get_ava( Slapi_Filter *f, char **type, struct berval **bval );
+Slapi_Filter *slapi_filter_list_first( Slapi_Filter *f );
+Slapi_Filter *slapi_filter_list_next( Slapi_Filter *f, Slapi_Filter *fprev );
+void slapi_free_search_results_internal(Slapi_PBlock *pb);
+int slapi_is_connection_ssl(Slapi_PBlock *pPB, int *isSSL);
+int slapi_get_client_port(Slapi_PBlock *pPB, int *fromPort);
+int slapi_get_num_be(char *type);
+unsigned long slapi_timer_current_time();
+unsigned long slapi_timer_get_time(char *label);
+void slapi_timer_elapsed_time(char *label,unsigned long start);
+int slapi_audit_init_header( Connection *conn, Operation *op, 
+               Audit_record **arp, void **audit_op_str,        
+               int audit_op, int audit_ext_op, int audit_op_str_len); 
+int slapi_audit_send_record( Slapi_PBlock *pb, Connection *conn, 
+                                               Operation *op, int rc);
+
+extern ldap_pvt_thread_mutex_t slapi_hn_mutex;
+extern ldap_pvt_thread_mutex_t slapi_time_mutex;
+
+#endif /* _SLAPI_UTILS_H */
+
index bed694b5027ab350960068faa3ebf03f779ae6a1..c700c8816fa2b0e5864e83615b2376abe1f730d4 100644 (file)
@@ -27,7 +27,8 @@ XLIBS = $(SLAPD_L) $(LDBM_LIBS)
 XXLIBS = $(SLAPD_LIBS) \
        $(LDBM_LIBS) $(SECURITY_LIBS) \
        $(LDIF_LIBS) $(LUTIL_LIBS)
-XXXLIBS = $(MODULES_LIBS) $(LTHREAD_LIBS)
+XXXLIBS = $(MODULES_LIBS) $(LTHREAD_LIBS) \
+       $(SLAPI_LIBS) ../libslapi.a
 
 STATIC_DEPENDS=@SLAPD_NO_STATIC@ ../libbackends.a
 
index 70f87c3dddbf2e28b152512b072529b9a062fbd4..355752ac71d9a848f669c040c8dfbcfb5dd3f346 100644 (file)
@@ -42,7 +42,7 @@ send_ldap_disconnect(
 }
 
 void
-send_ldap_extended(
+slap_send_ldap_extended(
     Connection *conn,
     Operation  *op,
     ber_int_t  err,
@@ -73,7 +73,7 @@ send_ldap_sasl(
 }
 
 void
-send_ldap_result(
+slap_send_ldap_result(
        Connection  *conn, 
        Operation   *op,
        ber_int_t     err,
@@ -87,7 +87,7 @@ send_ldap_result(
 }
 
 void
-send_search_result(
+slap_send_search_result(
        Connection  *conn, 
        Operation   *op,
        ber_int_t     err,
@@ -102,7 +102,7 @@ send_search_result(
 }
 
 int
-send_search_entry(
+slap_send_search_entry(
        Backend *be,
        Connection  *conn, 
        Operation   *op,
@@ -116,7 +116,8 @@ send_search_entry(
        return -1;
 }
 
-int send_search_reference(
+int
+slap_send_search_reference(
        Backend *be,
        Connection  *conn, 
        Operation   *op,
@@ -270,6 +271,17 @@ slap_modrdn2mods(
        return 0;
 }
 
+int
+slap_mods2entry(
+       Modifications *mods,
+       Entry **e,
+       int repl_user,
+       const char **text,
+       char *textbuf, size_t textlen )
+{
+       return 0;
+}
+
 int slap_sasl_getdn( Connection *conn, char *id, int len,
        char *user_realm, struct berval *dn, int flags )
 {