Index: configure.in =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/configure.in,v retrieving revision 1.444 diff -u -r1.444 configure.in --- configure.in 9 Nov 2002 16:03:07 -0000 1.444 +++ configure.in 10 Nov 2002 19:02:23 -0000 @@ -181,6 +181,8 @@ 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, @@ -242,6 +244,9 @@ # 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 @@ -346,6 +351,7 @@ fi # force settings to no + ol_enable_slapi=no ol_enable_bdb=no ol_enable_dnssrv=no ol_enable_ldap=no @@ -516,6 +522,8 @@ BUILD_THREAD=no +BUILD_SLAPI=no + BUILD_BDB=no BUILD_DNSSRV=no BUILD_LDAP=no @@ -564,10 +572,13 @@ TERMCAP_LIBS= TLS_LIBS= MODULES_LIBS= +SLAPI_LIBS= AUTH_LIBS= SLAPD_SLP_LIBS= +LDAP_SLAPI_DEF= + dnl ================================================================ dnl Checks for programs @@ -2504,6 +2515,23 @@ 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 ]) + 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]) + dnl LDAP_SLAPI_DEF="-DLDAP_SLAPI" dnl redundant ... +fi + if test "$ol_enable_debug" != no ; then AC_DEFINE(LDAP_DEBUG,1, [define this to add debugging code]) @@ -2764,6 +2792,11 @@ BUILD_REWRITE=yes fi +if test "$ol_enable_slapi" != no ; then + AC_DEFINE(ENABLE_SLAPI,1,[define to enable slapi library]) + BUILD_SLAPI=yes +fi + dnl ---------------------------------------------------------------- dnl @@ -2789,6 +2822,7 @@ AC_SUBST(BUILD_LIBS_DYNAMIC) AC_SUBST(BUILD_SLAPD) + AC_SUBST(BUILD_SLAPI) AC_SUBST(BUILD_BDB) AC_SUBST(BUILD_DNSSRV) AC_SUBST(BUILD_LDAP) @@ -2843,6 +2877,7 @@ 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) @@ -2851,6 +2886,8 @@ AC_SUBST(SLAPD_SQL_LIBS) AC_SUBST(SLAPD_SQL_INCLUDES) +AC_SUBST(LDAP_SLAPI_DEF) + dnl ---------------------------------------------------------------- dnl final help output AC_ARG_WITH(xxinstall,[ @@ -2896,6 +2933,7 @@ 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 \ Index: include/Makefile.in =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/include/Makefile.in,v retrieving revision 1.19 diff -u -r1.19 Makefile.in --- include/Makefile.in 18 May 2002 00:12:04 -0000 1.19 +++ include/Makefile.in 10 Nov 2002 19:02:24 -0000 @@ -11,7 +11,7 @@ for header in $(srcdir)/lber.h lber_types.h \ $(srcdir)/ldap.h $(srcdir)/ldap_cdefs.h \ $(srcdir)/ldap_schema.h $(srcdir)/ldap_utf8.h \ - ldap_features.h; \ + $(srcdir)/slapi-plugin.h ldap_features.h; \ do \ $(INSTALL) $(INSTALLFLAGS) -m 644 $$header $(DESTDIR)$(includedir); \ done Index: servers/slapd/Makefile.in =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/Makefile.in,v retrieving revision 1.107 diff -u -r1.107 Makefile.in --- servers/slapd/Makefile.in 28 Oct 2002 22:57:54 -0000 1.107 +++ servers/slapd/Makefile.in 10 Nov 2002 19:02:24 -0000 @@ -35,7 +35,7 @@ limits.o backglue.o operational.o matchedValues.o \ $(@PLAT@_OBJS) -LDAP_INCDIR= ../../include +LDAP_INCDIR= ../../include -Islapi LDAP_LIBDIR= ../../libraries SLAP_DIR= @@ -43,12 +43,14 @@ SLAPD_STATIC_BACKENDS=@SLAPD_STATIC_BACKENDS@ SLAPD_DYNAMIC_BACKENDS=@SLAPD_DYNAMIC_BACKENDS@ -XDEFS = $(MODULES_CPPFLAGS) +LDAP_SLAPI_DEF=@LDAP_SLAPI_DEF@ + +XDEFS = $(MODULES_CPPFLAGS) $(LDAP_SLAPI_DEF) 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@ @@ -225,7 +227,11 @@ --base-file slapd.base --output-exp $@ slapd: $(SLAPD_DEPENDS) - $(LTLINK) -o $@ $(SLAPD_OBJECTS) $(LIBS) $(WRAP_LIBS) + $(AR) ruv slapi/libtmpslapd.a $(OBJS) + (cd slapi; $(MAKE) $(MFLAGS) all) + $(LTLINK) -o $@ $(SLAPD_OBJECTS) $(LIBS) \ + slapi/.libs/libslapi.a slapi/libtmpslapd.a \ + $(WRAP_LIBS) sslapd: version.o $(LTLINK) -static -o $@ $(OBJS) version.o $(LIBS) $(WRAP_LIBS) @@ -280,7 +286,7 @@ $(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 +299,7 @@ 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 +309,7 @@ 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 +323,7 @@ -$(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: servers/slapd/add.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/add.c,v retrieving revision 1.117 diff -u -r1.117 add.c --- servers/slapd/add.c 29 Sep 2002 02:30:38 -0000 1.117 +++ servers/slapd/add.c 10 Nov 2002 19:02:24 -0000 @@ -16,6 +16,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include #include @@ -24,13 +25,7 @@ #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 @@ 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,26 @@ 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( (Slapi_PBlock *)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( (Slapi_PBlock *)pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls ); + + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_PRE_ADD_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no preOp (add) plugins or a plugin failed. Just log it */ +#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 +331,19 @@ NULL, "operation not supported within namingContext", NULL, NULL ); } +#if defined( LDAP_SLAPI ) + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_POST_ADD_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no postOp (Add) plugins or a plugin failed. Just log it */ +#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 +355,8 @@ return rc; } -static int slap_mods2entry( +int +slap_mods2entry( Modifications *mods, Entry **e, int repl_user, Index: servers/slapd/backend.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/backend.c,v retrieving revision 1.171 diff -u -r1.171 backend.c --- servers/slapd/backend.c 26 Oct 2002 08:05:35 -0000 1.171 +++ servers/slapd/backend.c 10 Nov 2002 19:02:24 -0000 @@ -7,6 +7,7 @@ #include "portable.h" +#include "slapi_common.h" #include @@ -16,6 +17,7 @@ #include #include "slap.h" +#include "slapi.h" #include "lutil.h" #include "lber_pvt.h" @@ -686,12 +688,44 @@ 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]); + if(!((rc=doPluginFNs(&backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no preOp (unbind) plugins or a plugin failed. Just log it. */ +#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 ) + if(!((rc=doPluginFNs(&backends[i], SLAPI_PLUGIN_POST_UNBIND_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no postOp (unbind) plugins or a plugin failed. Just log it. */ +#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: servers/slapd/bind.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/bind.c,v retrieving revision 1.127 diff -u -r1.127 bind.c --- servers/slapd/bind.c 8 Oct 2002 17:03:48 -0000 1.127 +++ servers/slapd/bind.c 10 Nov 2002 19:02:24 -0000 @@ -18,6 +18,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include @@ -26,6 +27,7 @@ #include "ldap_pvt.h" #include "slap.h" +#include "slapi.h" int do_bind( @@ -47,6 +49,8 @@ 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 @@ -512,6 +516,25 @@ 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)); + + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_PRE_BIND_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no preOp (bind) plugins or a plugin failed. Just log it */ +#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; @@ -571,6 +594,20 @@ NULL, "operation not supported within namingContext", NULL, NULL ); } + +#if defined( LDAP_SLAPI ) + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_POST_BIND_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no pretOp (bind) plugins or a plugin failed. Just log it */ +#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: servers/slapd/compare.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/compare.c,v retrieving revision 1.81 diff -u -r1.81 compare.c --- servers/slapd/compare.c 9 Oct 2002 05:11:50 -0000 1.81 +++ servers/slapd/compare.c 10 Nov 2002 19:02:25 -0000 @@ -16,12 +16,14 @@ */ #include "portable.h" +#include "slapi_common.h" #include #include #include "ldap_pvt.h" #include "slap.h" +#include "slapi.h" static int compare_entry( Connection *conn, @@ -48,6 +50,8 @@ const char *text = NULL; int manageDSAit; + Slapi_PBlock *pb = op->o_pb; + ava.aa_desc = NULL; #ifdef NEW_LOGGING @@ -267,6 +271,28 @@ /* 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 ); + + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_PRE_COMPARE_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no preOp (compare) plugins or a plugin failed. Just log it */ +#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 { @@ -274,6 +300,19 @@ NULL, "operation not supported within namingContext", NULL, NULL ); } + +#if defined( LDAP_SLAPI ) + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_POST_COMPARE_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no postOp (compare) plugins or a plugin failed. Just log it */ +#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 ); Index: servers/slapd/config.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/config.c,v retrieving revision 1.196 diff -u -r1.196 config.c --- servers/slapd/config.c 1 Nov 2002 17:59:52 -0000 1.196 +++ servers/slapd/config.c 10 Nov 2002 19:02:25 -0000 @@ -6,6 +6,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include @@ -18,6 +19,7 @@ #include "lutil.h" #include "ldap_pvt.h" #include "slap.h" +#include "slapi.h" #define ARGS_STEP 512 @@ -2310,6 +2312,62 @@ fname, lineno, 0 ); #endif #endif /* !SLAPD_RLOOKUPS */ + + /* Netscape plugins */ + } else if ( strcasecmp( cargv[0], "plugin" ) == 0 ) { +#if defined( LDAP_SLAPI ) + + /* + * FIXME: is this correct? + */ + 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 ( !SLAP_SLAPI( be ) ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, INFO, + "%s: line %d: plugin not supported " + "by this backend.\n", + fname, lineno, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "%s: line %d: plugin " + "not supported by this backend.\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 { Index: servers/slapd/connection.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/connection.c,v retrieving revision 1.195 diff -u -r1.195 connection.c --- servers/slapd/connection.c 26 Oct 2002 20:41:26 -0000 1.195 +++ servers/slapd/connection.c 10 Nov 2002 19:02:25 -0000 @@ -411,6 +411,12 @@ 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: servers/slapd/controls.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/controls.c,v retrieving revision 1.42 diff -u -r1.42 controls.c --- servers/slapd/controls.c 25 Oct 2002 15:51:30 -0000 1.42 +++ servers/slapd/controls.c 10 Nov 2002 19:02:25 -0000 @@ -100,6 +100,12 @@ 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: servers/slapd/delete.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/delete.c,v retrieving revision 1.74 diff -u -r1.74 delete.c --- servers/slapd/delete.c 29 Sep 2002 02:30:39 -0000 1.74 +++ servers/slapd/delete.c 10 Nov 2002 19:02:26 -0000 @@ -16,6 +16,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include @@ -24,6 +25,7 @@ #include "ldap_pvt.h" #include "slap.h" +#include "slapi.h" int do_delete( @@ -39,6 +41,8 @@ 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,26 @@ /* 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( (Slapi_PBlock *)pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls ); + + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_PRE_DELETE_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no preOp (delete) plugins or a plugin failed. Just log it */ +#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; @@ -192,6 +216,19 @@ send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, NULL, "operation not supported within namingContext", NULL, NULL ); } + +#if defined( LDAP_SLAPI ) + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_POST_DELETE_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no postOp (delete) plugins or a plugin failed. Just log it */ +#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 ); Index: servers/slapd/extended.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/extended.c,v retrieving revision 1.32 diff -u -r1.32 extended.c --- servers/slapd/extended.c 2 Sep 2002 17:39:06 -0000 1.32 +++ servers/slapd/extended.c 10 Nov 2002 19:02:26 -0000 @@ -26,14 +26,18 @@ */ #include "portable.h" +#include "slapi_common.h" #include #include #include #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 @@ 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 @@ 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", @@ -200,29 +213,72 @@ 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) { /* open LDAP 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 ) } +#endif /* !defined( LDAP_SLAPI ) */ +#if 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: servers/slapd/modify.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/modify.c,v retrieving revision 1.135 diff -u -r1.135 modify.c --- servers/slapd/modify.c 29 Sep 2002 02:30:39 -0000 1.135 +++ servers/slapd/modify.c 10 Nov 2002 19:02:26 -0000 @@ -16,6 +16,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include @@ -27,6 +28,7 @@ #include "ldap_pvt.h" #include "slap.h" +#include "slapi.h" int do_modify( @@ -49,6 +51,8 @@ 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,26 @@ /* 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( (Slapi_PBlock *)pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls ); + slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, (void *)(1)); + + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_PRE_MODIFY_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no preOp (modify) plugins or a plugin failed. Just log it */ +#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; @@ -379,6 +403,19 @@ NULL, "operation not supported within namingContext", NULL, NULL ); } + +#if defined( LDAP_SLAPI ) + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_POST_MODIFY_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no postOp (modify) plugins or a plugin failed. Just log it */ +#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 ); Index: servers/slapd/modrdn.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/modrdn.c,v retrieving revision 1.88 diff -u -r1.88 modrdn.c --- servers/slapd/modrdn.c 29 Sep 2002 02:30:39 -0000 1.88 +++ servers/slapd/modrdn.c 10 Nov 2002 19:02:26 -0000 @@ -29,6 +29,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include @@ -37,6 +38,7 @@ #include "ldap_pvt.h" #include "slap.h" +#include "slapi.h" int do_modrdn( @@ -64,6 +66,8 @@ 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,29 @@ /* 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( (Slapi_PBlock *)pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls ); + slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, (void *)(1)); + + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_PRE_MODRDN_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no preOp (modrdn) plugins or a plugin failed. Just log it */ +#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; @@ -369,6 +396,19 @@ NULL, "operation not supported within namingContext", NULL, NULL ); } + +#if defined( LDAP_SLAPI ) + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_POST_MODRDN_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no postOp (modrdn) plugins or a plugin failed. Just log it */ +#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 ); Index: servers/slapd/operation.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/operation.c,v retrieving revision 1.30 diff -u -r1.30 operation.c --- servers/slapd/operation.c 13 Sep 2002 22:29:06 -0000 1.30 +++ servers/slapd/operation.c 10 Nov 2002 19:02:26 -0000 @@ -6,6 +6,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include @@ -13,6 +14,7 @@ #include #include "slap.h" +#include "slapi.h" void @@ -42,6 +44,12 @@ } #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 ); } @@ -63,6 +71,10 @@ 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: servers/slapd/proto-slap.h =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/proto-slap.h,v retrieving revision 1.378 diff -u -r1.378 proto-slap.h --- servers/slapd/proto-slap.h 10 Nov 2002 18:48:36 -0000 1.378 +++ servers/slapd/proto-slap.h 10 Nov 2002 19:02:26 -0000 @@ -84,7 +84,13 @@ 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 (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 @@ /* * 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 @@ 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 @@ 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: servers/slapd/result.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/result.c,v retrieving revision 1.156 diff -u -r1.156 result.c --- servers/slapd/result.c 8 Nov 2002 16:13:20 -0000 1.156 +++ servers/slapd/result.c 10 Nov 2002 19:02:26 -0000 @@ -429,7 +429,7 @@ } void -send_ldap_result( +slap_send_ldap_result( Connection *conn, Operation *op, ber_int_t err, @@ -545,7 +545,7 @@ } void -send_ldap_extended( +slap_send_ldap_extended( Connection *conn, Operation *op, ber_int_t err, @@ -584,7 +584,7 @@ void -send_search_result( +slap_send_search_result( Connection *conn, Operation *op, ber_int_t err, @@ -662,7 +662,7 @@ } int -send_search_entry( +slap_send_search_entry( Backend *be, Connection *conn, Operation *op, @@ -1220,7 +1220,7 @@ } int -send_search_reference( +slap_send_search_reference( Backend *be, Connection *conn, Operation *op, Index: servers/slapd/root_dse.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/root_dse.c,v retrieving revision 1.70 diff -u -r1.70 root_dse.c --- servers/slapd/root_dse.c 10 Nov 2002 05:48:55 -0000 1.70 +++ servers/slapd/root_dse.c 10 Nov 2002 19:02:26 -0000 @@ -11,13 +11,18 @@ */ #include "portable.h" +#include "slapi_common.h" #include #include #include "slap.h" +#include "slapi.h" #include #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 ("+") */ @@ -133,6 +138,14 @@ if( attr_merge( e, ad_supportedExtension, vals ) ) 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 ) ) Index: servers/slapd/search.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/search.c,v retrieving revision 1.93 diff -u -r1.93 search.c --- servers/slapd/search.c 25 Oct 2002 15:51:31 -0000 1.93 +++ servers/slapd/search.c 10 Nov 2002 19:02:26 -0000 @@ -16,6 +16,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include @@ -24,6 +25,7 @@ #include "ldap_pvt.h" #include "slap.h" +#include "slapi.h" int do_search( @@ -44,6 +46,8 @@ 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,34 @@ /* 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( (Slapi_PBlock *)pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls ); + slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, (void *)(1)); + + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_PRE_SEARCH_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no preOp (search) plugins or a plugin failed. Just log it */ +#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, @@ -320,6 +352,20 @@ NULL, "operation not supported within namingContext", NULL, NULL ); } + +#if defined( LDAP_SLAPI ) + if(!((rc=doPluginFNs(be, SLAPI_PLUGIN_POST_SEARCH_FN, + (Slapi_PBlock *)pb)) == 0 || rc == LDAP_OTHER )) { + /* either there is no postOp (search) plugins or a plugin failed. Just log it */ +#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 Index: servers/slapd/slap.h =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/slap.h,v retrieving revision 1.373 diff -u -r1.373 slap.h --- servers/slapd/slap.h 10 Nov 2002 18:48:36 -0000 1.373 +++ servers/slapd/slap.h 10 Nov 2002 19:02:27 -0000 @@ -1241,6 +1241,7 @@ #define SLAP_BFLAG_SUBENTRIES 0x0400U #define SLAP_BFLAG_MONITOR 0x1000U #define SLAP_BFLAG_DYNAMIC 0x2000U +#define SLAP_BFLAG_SLAPI 0x4000U slap_mask_t be_flags; #define SLAP_LASTMOD(be) (!((be)->be_flags & SLAP_BFLAG_NOLASTMOD)) #define SLAP_ALIASES(be) ((be)->be_flags & SLAP_BFLAG_ALIASES) @@ -1248,6 +1249,7 @@ #define SLAP_SUBENTRIES(be) ((be)->be_flags & SLAP_BFLAG_SUBENTRIES) #define SLAP_MONITOR(be) ((be)->be_flags & SLAP_BFLAG_MONITOR) #define SLAP_DYNAMIC(be) ((be)->be_flags & SLAP_BFLAG_DYNAMIC) +#define SLAP_SLAPI(be) ((be)->be_flags & SLAP_BFLAG_SLAPI) slap_mask_t be_restrictops; /* restriction operations */ #define SLAP_RESTRICT_OP_ADD 0x0001U @@ -1317,6 +1319,8 @@ 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; @@ -1676,12 +1680,89 @@ 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) #define get_subentries(op) ((int)(op)->o_subentries) #define get_subentries_visibility(op) ((int)(op)->o_subentries_visibility) + +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 */ @@ -1762,6 +1843,20 @@ 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) Index: servers/slapd/back-bdb/Makefile.in =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/back-bdb/Makefile.in,v retrieving revision 1.17 diff -u -r1.17 Makefile.in --- servers/slapd/back-bdb/Makefile.in 25 Oct 2002 15:51:31 -0000 1.17 +++ servers/slapd/back-bdb/Makefile.in 10 Nov 2002 19:02:27 -0000 @@ -4,16 +4,25 @@ add.c bind.c compare.c delete.c modify.c modrdn.c search.c \ extended.c passwd.c referral.c attribute.c group.c operational.c \ attr.c index.c key.c dbcache.c filterindex.c \ - dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c lcup.c + dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c \ + lcup.c \ + ../slapi/plugin.c ../slapi/slapi_pblock.c ../slapi/slapi_utils.c \ + ../slapi/ldapload.c ../slapi/slapi_ops.c OBJS = init.lo tools.lo config.lo \ add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \ extended.lo passwd.lo referral.lo attribute.lo group.lo operational.lo \ attr.lo index.lo key.lo dbcache.lo filterindex.lo \ - dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo lcup.lo + dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo \ + lcup.lo \ + dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo \ + plugin.lo slapi_pblock.lo slapi_utils.lo ldapload.lo slapi_ops.lo +VPATH=../slapi: LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries +LDAP_SLAPI_DEF=@LDAP_SLAPI_DEF@ + BUILD_OPT = "--enable-bdb" BUILD_MOD = @BUILD_BDB@ BUILD_MOD_DYNAMIC = @BUILD_BDB_DYNAMIC@ @@ -27,11 +36,15 @@ LIBBASE = back_bdb -XINCPATH = -I.. -I$(srcdir)/.. -XDEFS = $(MODULES_CPPFLAGS) +XINCPATH = -I.. -I$(srcdir)/.. -I../slapi +XDEFS = $(MODULES_CPPFLAGS) $(LDAP_SLAPI_DEF) all-local-lib: ../.backend ../.backend: lib$(LIBBASE).a @touch $@ - + @touch ../slapi/plugin.c \ + ../slapi/slapi_pblock.c \ + ../slapi/slapi_utils.c \ + ../slapi/ldapload.c \ + ../slapi/slapi_ops.c Index: servers/slapd/back-bdb/init.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/back-bdb/init.c,v retrieving revision 1.101 diff -u -r1.101 init.c --- servers/slapd/back-bdb/init.c 10 Nov 2002 19:00:44 -0000 1.101 +++ servers/slapd/back-bdb/init.c 10 Nov 2002 19:02:27 -0000 @@ -79,6 +79,7 @@ #ifdef BDB_ALIASES SLAP_BFLAG_ALIASES | #endif + SLAP_BFLAG_SLAPI | SLAP_BFLAG_REFERRALS; /* allocate backend-database-specific stuff */ Index: servers/slapd/back-ldbm/Makefile.in =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/back-ldbm/Makefile.in,v retrieving revision 1.29 diff -u -r1.29 Makefile.in --- servers/slapd/back-ldbm/Makefile.in 28 Aug 2002 00:50:30 -0000 1.29 +++ servers/slapd/back-ldbm/Makefile.in 10 Nov 2002 19:02:27 -0000 @@ -5,17 +5,22 @@ compare.c group.c modify.c modrdn.c delete.c init.c \ config.c bind.c attr.c filterindex.c close.c \ alias.c tools.c key.c extended.c passwd.c sasl.c \ - referral.c attribute.c operational.c + referral.c attribute.c operational.c \ + ../slapi/ldapload.c ../slapi/slapi_ops.c OBJS = idl.lo add.lo search.lo cache.lo dbcache.lo dn2id.lo entry.lo \ id2entry.lo index.lo id2children.lo nextid.lo \ compare.lo group.lo modify.lo modrdn.lo delete.lo init.lo \ config.lo bind.lo attr.lo filterindex.lo close.lo \ alias.lo tools.lo key.lo extended.lo passwd.lo sasl.lo \ - referral.lo attribute.lo operational.lo $(@BUILD_LDBM@_OBJS) + referral.lo attribute.lo operational.lo $(@BUILD_LDBM@_OBJS) \ + plugin.lo slapi_pblock.lo slapi_utils.lo ldapload.lo slapi_ops.lo +VPATH=../slapi: LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries +LDAP_SLAPI_DEF=@LDAP_SLAPI_DEF@ + BUILD_OPT = "--enable-ldbm" BUILD_MOD = @BUILD_LDBM@ BUILD_MOD_DYNAMIC = @BUILD_LDBM_DYNAMIC@ @@ -32,14 +37,19 @@ LIBBASE = back_ldbm -XINCPATH = -I.. -I$(srcdir)/.. -XDEFS = $(MODULES_CPPFLAGS) +XINCPATH = -I.. -I$(srcdir)/.. -I../slapi +XDEFS = $(MODULES_CPPFLAGS) $(LDAP_SLAPI_DEF) XXSRCS = $(@BUILD_LDBM@_SRCS) all-local-lib: ../.backend ../.backend: lib$(LIBBASE).a @touch $@ + @touch ../slapi/plugin.c \ + ../slapi/slapi_pblock.c \ + ../slapi/slapi_utils.c \ + ../slapi/ldapload.c \ + ../slapi_ops.c ldbm.c : $(srcdir)/../../../libraries/libldbm/ldbm.c $(RM) $@; $(LN_S) $(srcdir)/../../../libraries/libldbm/ldbm.c $@ Index: servers/slapd/back-ldbm/init.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/back-ldbm/init.c,v retrieving revision 1.81 diff -u -r1.81 init.c --- servers/slapd/back-ldbm/init.c 10 Nov 2002 18:48:36 -0000 1.81 +++ servers/slapd/back-ldbm/init.c 10 Nov 2002 19:02:27 -0000 @@ -129,7 +129,10 @@ struct ldbminfo *li; /* indicate system schema supported */ - be->be_flags |= SLAP_BFLAG_ALIASES|SLAP_BFLAG_REFERRALS; + be->be_flags |= + SLAP_BFLAG_ALIASES | + SLAP_BFLAG_REFERRALS | + SLAP_BFLAG_SLAPI; /* allocate backend-database-specific stuff */ li = (struct ldbminfo *) ch_calloc( 1, sizeof(struct ldbminfo) ); Index: servers/slapd/tools/Makefile.in =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/tools/Makefile.in,v retrieving revision 1.75 diff -u -r1.75 Makefile.in --- servers/slapd/tools/Makefile.in 29 Oct 2002 07:05:45 -0000 1.75 +++ servers/slapd/tools/Makefile.in 10 Nov 2002 19:02:27 -0000 @@ -27,7 +27,8 @@ XXLIBS = $(SLAPD_LIBS) \ $(LDBM_LIBS) $(SECURITY_LIBS) \ $(LDIF_LIBS) $(LUTIL_LIBS) -XXXLIBS = $(MODULES_LIBS) $(LTHREAD_LIBS) +XXXLIBS = $(MODULES_LIBS) $(LTHREAD_LIBS) \ + $(SLAPI_LIBS) ../slapi/.libs/libslapi.a STATIC_DEPENDS=@SLAPD_NO_STATIC@ ../libbackends.a Index: servers/slapd/tools/mimic.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/tools/mimic.c,v retrieving revision 1.56 diff -u -r1.56 mimic.c --- servers/slapd/tools/mimic.c 16 Aug 2002 14:35:17 -0000 1.56 +++ servers/slapd/tools/mimic.c 10 Nov 2002 19:02:27 -0000 @@ -42,7 +42,7 @@ } void -send_ldap_extended( +slap_send_ldap_extended( Connection *conn, Operation *op, ber_int_t err, @@ -73,7 +73,7 @@ } void -send_ldap_result( +slap_send_ldap_result( Connection *conn, Operation *op, ber_int_t err, @@ -87,7 +87,7 @@ } void -send_search_result( +slap_send_search_result( Connection *conn, Operation *op, ber_int_t err, @@ -102,7 +102,7 @@ } int -send_search_entry( +slap_send_search_entry( Backend *be, Connection *conn, Operation *op, @@ -116,7 +116,8 @@ return -1; } -int send_search_reference( +int +slap_send_search_reference( Backend *be, Connection *conn, Operation *op, @@ -266,6 +267,17 @@ LDAPRDN *newrdn, int deleteoldrdn, Modifications **pmod ) +{ + return 0; +} + +int +slap_mods2entry( + Modifications *mods, + Entry **e, + int repl_user, + const char **text, + char *textbuf, size_t textlen ) { return 0; } ===================================================== This is the newly added directory servers/slapd/slapi ===================================================== diff -uNr servers/slapd/slapi/Makefile.in servers/slapd/slapi/Makefile.in --- servers/slapd/slapi/Makefile.in Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/Makefile.in Sun Nov 3 22:11:19 2002 @@ -0,0 +1,47 @@ +## 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 ldapload.c slapi_ops.c + +NT_SRCS = nt_err.c +NT_OBJS = nt_err.lo + +LDAP_SLAPI_DEF=@LDAP_SLAPI_DEF@ + +LIB_DEFS = -DSLAPI_LIBRARY + +SRCS= ldapload.c plugin.c slapi_pblock.c slapi_utils.c printmsg.c slapi_ops.c $(@PLAT@_SRCS) +OBJS= ldapload.lo 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) $(LDAP_SLAPI_DEF) + +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 -uNr servers/slapd/slapi/README servers/slapd/slapi/README --- servers/slapd/slapi/README Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/README Sat Sep 7 19:27:19 2002 @@ -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 -uNr servers/slapd/slapi/ibm_pblock_params.h servers/slapd/slapi/ibm_pblock_params.h --- servers/slapd/slapi/ibm_pblock_params.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/ibm_pblock_params.h Sat Sep 7 19:27:19 2002 @@ -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 -uNr servers/slapd/slapi/ldapload.c servers/slapd/slapi/ldapload.c --- servers/slapd/slapi/ldapload.c Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/ldapload.c Sun Nov 10 20:03:45 2002 @@ -0,0 +1,84 @@ +/* + * 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 +#include + +#include +#include +#include + +#include +#include + +#ifdef HAVE_LTDL_H + +pLoadHandle +ldapLoadLib( + const char *pLibName, + int loadFlags ) +{ + pLoadHandle pLoad; + + if ( lt_dlinit() ) { + return NULL; + } + + pLoad = (pLoadHandle)ch_malloc( sizeof( loadHandle ) ); + if (pLoad == NULL) { + return NULL; + } + + memset( pLoad, 0, sizeof( loadHandle ) ); + + pLoad->pModule = lt_dlopen( pLibName ); + if ( !pLoad->pModule ) { + ch_free( pLoad ); + return NULL; + } + + return pLoad; +} + +int +ldapUnloadLib( pLoadHandle pLoad ) +{ + if ( !pLoad ) { + return LDAP_OTHER; + } + + lt_dlclose( pLoad->pModule ); + memset( pLoad, 0, sizeof( loadHandle ) ); + ch_free( pLoad ); + + return LDAP_SUCCESS; +} + +void * +ldapGetSymAddress( + pLoadHandle pLoad, + const char *pFunctName ) +{ + void *pRet = NULL; + + if ( pLoad && pFunctName ) { + pRet = lt_dlsym( pLoad->pModule, pFunctName ); + } + + return pRet; +} + +#endif /* HAVE_LTDL_H */ + diff -uNr servers/slapd/slapi/ldapload.h servers/slapd/slapi/ldapload.h --- servers/slapd/slapi/ldapload.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/ldapload.h Sun Nov 10 18:54:19 2002 @@ -0,0 +1,32 @@ +/* + * 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 _LDAPLOAD_H +#define _LDAPLOAD_H + +#ifdef HAVE_LTDL_H +#include + +typedef struct loadhandle { + lt_dlhandle pModule; +} loadHandle; + +typedef loadHandle *pLoadHandle; + +extern pLoadHandle ldapLoadLib( const char *pLibName, int loadFlags ); +extern int ldapUnloadLib( pLoadHandle ); +extern void *ldapGetSymAddress( pLoadHandle, const char * ); + +#endif /* HAVE_LTDL_H */ + +#endif /* _LDAPLOAD_H */ diff -uNr servers/slapd/slapi/plugin.c servers/slapd/slapi/plugin.c --- servers/slapd/slapi/plugin.c Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/plugin.c Sun Nov 10 20:03:45 2002 @@ -0,0 +1,568 @@ +/* + * 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 +#include +#include + +static int loadPlugin( Slapi_PBlock *, char *, char *, int, + SLAPI_FUNC *, pLoadHandle ); + +/* pointer to link list of extended objects */ +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 arguements + * 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, + char *path, + char *initfunc, + int argc, + char *argv[] ) +{ + Slapi_PBlock *pPlugin = NULL; + loadHandle hdLoadHandle; + int rc; + + pPlugin = slapi_pblock_new(); + if ( pPlugin == NULL ) { + rc = LDAP_NO_MEMORY; + } else { + rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, + (void *)type ); + if ( rc == LDAP_SUCCESS ) { + rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, + (void *)argc ); + if ( rc == LDAP_SUCCESS ) { + rc = slapi_pblock_set( pPlugin, + SLAPI_PLUGIN_ARGV, + (void *)argv ); + if ( rc == LDAP_SUCCESS ) { + rc = loadPlugin( pPlugin, path, + initfunc, TRUE, + NULL, &hdLoadHandle ); + } + } + } + + if ( rc != LDAP_SUCCESS ) { + 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; + + pCurrentPB = (Slapi_PBlock *)(be->be_pb); + + if ( pCurrentPB == NULL ) { + rc = LDAP_OTHER; + } else { + 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 ) { + if ( numPB == 0 ) { + *ppFuncPtrs = NULL; + } else { + *ppFuncPtrs = pTmpFuncPtr = (SLAPI_FUNC *)malloc( (numPB+1) * sizeof(SLAPI_FUNC) ); + if ( ppFuncPtrs == NULL ) { + rc = LDAP_NO_MEMORY; + } else { + 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 ; + } + } + } + + 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; + + if((ret = (ExtendedOp *)malloc(sizeof(ExtendedOp))) == NULL){ + ret = NULL; + } else{ + 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 (*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; + for (pTmpExtOp = *opList; pTmpExtOp != NULL; pTmpExtOp = pTmpExtOp->ext_next) { + if (strcasecmp(pTmpExtOp->ext_oid.bv_val, pTmpOIDs[i]) == 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 != 0) { + 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; + int rc=LDAP_OTHER; + char *funcName; + + funcName = reqoid->bv_val; + + if ( pGExtendedOps != NULL ) { + pTmpExtOp = pGExtendedOps; + while ( pTmpExtOp != NULL ) { + if ( (rc = strcasecmp( funcName, pTmpExtOp->ext_oid.bv_val )) == 0 ) { + *pFuncAddr = pTmpExtOp->ext_func; + break; + } else { + pTmpExtOp = pTmpExtOp->ext_next; + } + } + } else { + rc = LDAP_OTHER; + } + + return( rc ); +} + +/*************************************************************************** + * 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 ldapLoadLib() + * + * Return Values: LDAP_SUCCESS, LDAP_LOCAL_ERROR + * + * Messages: None + *********************************************************************/ + +static int +loadPlugin( Slapi_PBlock *pPlugin, char *path, char *initfunc, + int doInit, SLAPI_FUNC *pInitFunc, pLoadHandle pLdHandle ) +{ + int rc = LDAP_SUCCESS; + SLAPI_FUNC fpInitFunc = NULL; + + /* load in the module */ + pLdHandle = ldapLoadLib( path, 0 ); + + if ( pLdHandle == NULL ) { + rc = LDAP_LOCAL_ERROR; + } else { + fpInitFunc = (SLAPI_FUNC)ldapGetSymAddress( pLdHandle, initfunc ); + if ( fpInitFunc == NULL ) { + rc = LDAP_LOCAL_ERROR; + } else { + if ( doInit == TRUE ) { + rc = ( fpInitFunc )( pPlugin ); + } 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,&pGetPlugin); + if ( rc == LDAP_SUCCESS && pGetPlugin != NULL ) { + tmpPlugin = pGetPlugin; + while ( pGetPlugin != NULL && *pGetPlugin != NULL ) { + rc = (*pGetPlugin)(pPB); + pGetPlugin++; + } + } + if(tmpPlugin != NULL) + free(tmpPlugin); + + return( rc ); +} + +int +netscape_plugin( + Backend *be, + const char *fname, + int lineno, + int argc, + char **argv ) +{ + int rc; + int iType; + int numPluginArgc; + char **ppPluginArgv; + char *savefname; + Slapi_PBlock *pPlugin=NULL; + + if ( argc < 4 ) { + fprintf( stderr, + "%s: line %d: missing arguments in \"plugin []\" 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 { + /*invalid Plugin type*/ + return (1); + } + numPluginArgc = argc - 4; + if ( numPluginArgc > 0 ) { + ppPluginArgv = &(argv[4]); + } else { + ppPluginArgv = NULL; + } + savefname = strdup( argv[2] ); + + if (iType == SLAPI_PLUGIN_PREOPERATION || + iType == SLAPI_PLUGIN_EXTENDEDOP || + iType == SLAPI_PLUGIN_POSTOPERATION ) { + pPlugin = newPlugin(iType, savefname, 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; +} + diff -uNr servers/slapd/slapi/plugin.h servers/slapd/slapi/plugin.h --- servers/slapd/slapi/plugin.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/plugin.h Mon Nov 4 03:50:28 2002 @@ -0,0 +1,27 @@ +/* + * 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, char *path, 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 ); + +#endif /* _PLUGIN_H_ */ + diff -uNr servers/slapd/slapi/printmsg.c servers/slapd/slapi/printmsg.c --- servers/slapd/slapi/printmsg.c Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/printmsg.c Mon Nov 4 08:12:13 2002 @@ -0,0 +1,123 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* Single threads access to routine */ +static pthread_mutex_t PrintMessage_mutex; + +/* all mutexes will use same attributes */ +static pthread_mutexattr_t mutex_attributes; + +static void +InitMutexOnce( void) +{ + pthread_mutexattr_init(&mutex_attributes); + pthread_mutex_init(&PrintMessage_mutex, &mutex_attributes); +} + +static void +InitMutex () +{ + static pthread_once_t initMutexOnceFlag = PTHREAD_ONCE_INIT; + (void)pthread_once (&initMutexOnceFlag, InitMutexOnce); +} + +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*)calloc(strlen(subsystem) + strlen(tmpFmt) + 3, 1); + sprintf(fmt, "%s: %s", subsystem, tmpFmt); + + InitMutex() ; + pthread_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 (¤tTime); + ltm = localtime( ¤tTime ); + strftime( timeStr, 100, "%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 { + int save_errno = (int)errno; + rc = ( -1); + } + } else { + rc = ( -1); + } + + pthread_mutex_unlock( &PrintMessage_mutex ); + free(fmt); + + return (rc); +} diff -uNr servers/slapd/slapi/slapi-plugin.h servers/slapd/slapi/slapi-plugin.h --- servers/slapd/slapi/slapi-plugin.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi-plugin.h Sat Sep 7 19:27:19 2002 @@ -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 diff -uNr servers/slapd/slapi/slapi.h servers/slapd/slapi/slapi.h --- servers/slapd/slapi/slapi.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi.h Sun Nov 10 19:14:46 2002 @@ -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 + +typedef struct slapi_pblock Slapi_PBlock; +typedef struct slap_entry Slapi_Entry; +typedef struct slap_attr Slapi_Attr; +typedef Filter Slapi_Filter; + +#include +#ifndef NO_PBLOCK_CLASS +#include +#endif /* NO_PBLOCK_CLASS */ +#include +#include +#include + +/* + * 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 -uNr servers/slapd/slapi/slapi_cl.h servers/slapd/slapi/slapi_cl.h --- servers/slapd/slapi/slapi_cl.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_cl.h Sun Nov 10 19:15:31 2002 @@ -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 -uNr servers/slapd/slapi/slapi_common.h servers/slapd/slapi/slapi_common.h --- servers/slapd/slapi/slapi_common.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_common.h Sat Sep 7 19:27:19 2002 @@ -0,0 +1,39 @@ +/* + * 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 diff -uNr servers/slapd/slapi/slapi_ops.c servers/slapd/slapi/slapi_ops.c --- servers/slapd/slapi/slapi_ops.c Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_ops.c Sun Nov 10 20:03:45 2002 @@ -0,0 +1,1269 @@ +/* + * 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 +#include +#include +#include "../../../libraries/liblber/lber-int.h" + + +int bvptr2obj( struct berval **bvptr, struct berval **bvobj ); + +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; + + ent2str = slapi_entry2str( e, &len ); + if ( ent2str == 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 ) { + tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) ); + if ( tp == NULL ) { + return SLAPD_NO_MEMORY; + } + + tp[ 0 ] = (Slapi_Entry *)str2entry( ent2str ); + if ( tp[ 0 ] == NULL ) { + return SLAPD_NO_MEMORY; + } + + } else { + tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head, + sizeof(Slapi_Entry *) * ( i + 1 ) ); + if ( tp == NULL ) { + return SLAPD_NO_MEMORY; + } + tp[ i - 1 ] = (Slapi_Entry *)str2entry( ent2str ); + if ( tp[ i - 1 ] == 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; +} + +static Connection * +fakeConnection( + char *DN, + int OpType ) +{ + Connection *pConn, *c; + ber_len_t max = sockbuf_max_incoming; + + pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection)); + if (pConn == NULL) { + return (Connection *)NULL; + } + + LDAP_STAILQ_INIT( &pConn->c_pending_ops ); + + pConn->c_pending_ops.stqh_first = + (Operation *) slapi_ch_calloc( 1, sizeof(Operation) ); + if ( pConn->c_pending_ops.stqh_first == NULL ) { + slapi_ch_free( pConn ); + return (Connection *)NULL; + } + + pConn->c_pending_ops.stqh_first->o_pb = + (Slapi_PBlock *) slapi_pblock_new(); + if ( pConn->c_pending_ops.stqh_first->o_pb == NULL ) { + slapi_ch_free( pConn->c_pending_ops.stqh_first ); + slapi_ch_free( pConn ); + return (Connection *)NULL; + } + + c = pConn; + + /* operation object */ + c->c_pending_ops.stqh_first->o_tag = OpType; + c->c_pending_ops.stqh_first->o_protocol = LDAP_VERSION3; + c->c_pending_ops.stqh_first->o_authmech.bv_val = NULL; + c->c_pending_ops.stqh_first->o_authmech.bv_len = 0; + c->c_pending_ops.stqh_first->o_time = slap_get_time(); + + /* connection object */ + 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_groups = NULL; + + c->c_listener = NULL; + 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; + + LDAP_STAILQ_INIT( &c->c_ops ); + + 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( ); + + ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); + + c->c_currentber = NULL; + + /* should check status of thread calls */ + ldap_pvt_thread_mutex_init( &c->c_mutex ); + ldap_pvt_thread_mutex_init( &c->c_write_mutex ); + ldap_pvt_thread_cond_init( &c->c_write_cv ); + + c->c_n_ops_received = 0; + c->c_n_ops_executing = 0; + c->c_n_ops_pending = 0; + c->c_n_ops_completed = 0; + + c->c_n_get = 0; + c->c_n_read = 0; + c->c_n_write = 0; + + c->c_protocol = LDAP_VERSION3; + + c->c_activitytime = c->c_starttime = slap_get_time(); + + c->c_connid = 0; + + c->c_conn_state = 0x01; /* SLAP_C_ACTIVE */ + c->c_struct_state = 0x02; /* SLAP_C_USED */ + + c->c_ssf = c->c_transport_ssf = 0; + c->c_tls_ssf = 0; + + backend_connection_init( c ); + + 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 : 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 ) +{ + struct berval dn = { 0, NULL }; + Entry *pEntry=NULL; + LDAPMod *pMod; + struct berval *bv; + struct berval **ppBV; + Backend *be; + Operation *op; + + Modifications *modlist = NULL; + Modifications **modtail = &modlist; + Modifications tmp; + + int rc = LDAP_SUCCESS; + int i; + + const char *text = NULL; + + + op = (Operation *) slapi_ch_calloc(1, sizeof(Operation)); + if ( pEntry == NULL) { + rc = LDAP_NO_MEMORY; + goto cleanup; + } + op->o_tag = LDAP_REQ_ADD; + + pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) ); + if ( pEntry == NULL) { + rc = LDAP_NO_MEMORY; + goto cleanup; + } + + dn.bv_val = slapi_ch_strdup(ldn); + dn.bv_len = strlen(ldn); + + rc = dnPrettyNormal( NULL, &dn, &pEntry->e_name, &pEntry->e_nname ); + if (rc != LDAP_SUCCESS) goto cleanup; + + 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) goto cleanup; + tmp.sml_type.bv_val = slapi_ch_strdup(pMod->mod_type); + tmp.sml_type.bv_len = slapi_ch_stlen(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) goto cleanup; + rc = bvptr2obj(ppBV, &bv); + if (rc != LDAP_SUCCESS) goto cleanup; + tmp.sml_type.bv_val = slapi_ch_strdup(pMod->mod_type); + tmp.sml_type.bv_len = slapi_ch_stlen(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 */ + } + + be = select_backend(&dn, 0, 0); + if ( be == NULL ) { + rc = LDAP_PARTIAL_RESULTS; + goto cleanup; + } + + if ( be ) { + int repl_user = be_isupdate(be, &be->be_rootdn ); + if ( !be->be_update_ndn.bv_len || repl_user ) { + int update = be->be_update_ndn.bv_len; + char textbuf[SLAP_TEXT_BUFLEN]; + size_t textlen = sizeof textbuf; + + rc = slap_mods_check( modlist, update, &text, + textbuf, textlen ); + if ( rc != LDAP_SUCCESS) { + goto cleanup; + } + + if ( !repl_user ) { + rc = slap_mods_opattrs( be, op, + modlist, modtail, &text, + textbuf, textlen ); + if ( rc != LDAP_SUCCESS) { + goto cleanup; + } + } + + /* + * FIXME: slap_mods2entry is declared static + * in servers/slapd/add.c + */ + rc = slap_mods2entry( modlist, &pEntry, repl_user, + &text, textbuf, textlen ); + if (rc != LDAP_SUCCESS) { + goto cleanup; + } + + } else { + rc = LDAP_REFERRAL; + } + } else { + rc = LDAP_UNWILLING_TO_PERFORM; + } + +cleanup: + + if ( dn.bv_val ) slapi_ch_free( dn.bv_val ); + if ( op ) slapi_ch_free( op ); + if ( modlist != NULL ) slap_mods_free( modlist ); + if ( rc != LDAP_SUCCESS ) { + if ( pEntry != NULL ) { + slapi_entry_free( pEntry ); + } + pEntry = NULL; + } + + return( pEntry ); +} + +/* 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 ) +{ +#if defined(LDAP_SLAPI) + Backend *be; + Connection *pConn = NULL; + Operation *op = NULL; + Slapi_PBlock *pPB = NULL; + Slapi_PBlock *pSavePB = NULL; + + struct berval dn = { 0, NULL }; + struct berval pdn = { 0, NULL }; + struct berval ndn = { 0, NULL }; + + int rc=LDAP_SUCCESS; + int manageDsaIt = 0; + int isCritical; + + if ( ldn == NULL ) { + rc = LDAP_OPERATIONS_ERROR; + goto cleanup; + } + + pConn = fakeConnection( NULL, LDAP_REQ_DELETE ); + if (pConn == NULL) { + rc = LDAP_NO_MEMORY; + goto cleanup; + } + + op = (Operation *)pConn->c_pending_ops.stqh_first; + pPB = (Slapi_PBlock *)op->o_pb; + op->o_ctrls = controls; + + dn.bv_val = slapi_ch_strdup(ldn); + dn.bv_len = slapi_strlen(ldn); + rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn ); + if ( rc != LDAP_SUCCESS ) goto cleanup; + + if ( slapi_control_present( controls, + SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical) ) { + manageDsaIt = 1; + } + + be = select_backend( &dn, manageDsaIt, 0 ); + if ( be == NULL ) { + rc = LDAP_PARTIAL_RESULTS; + goto cleanup; + } + + op->o_ndn.bv_val = slapi_ch_strdup(be->be_rootdn.bv_val); + op->o_ndn.bv_len = be->be_rootdn.bv_len; + pConn->c_dn.bv_val = slapi_ch_strdup(be->be_rootdn.bv_val); + pConn->c_dn.bv_len = be->be_rootdn.bv_len; + + suffix_alias( be, &ndn ); + + if ( be->be_delete ) { + int repl_user = be_isupdate( be, &op->o_ndn ); + if ( !be->be_update_ndn.bv_len || repl_user ) { + rc = (*be->be_delete)( be, pConn, op, &pdn, &ndn ); + if ( rc == 0 ) { + if (log_change) { + replog( be, op, &pdn, &ndn, NULL ); + } + rc = LDAP_SUCCESS; + } else { + rc = LDAP_OPERATIONS_ERROR; + } + } else { + rc = LDAP_REFERRAL; + } + } else { + rc = LDAP_UNWILLING_TO_PERFORM; + } + +cleanup: + if (pPB != NULL) + slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc ); + + 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); + + if ( pConn != NULL ) { + if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val ); + if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val ); + if ( op ) slapi_ch_free( op ); + pSavePB = pPB; + free( pConn ); + } + + return (pSavePB); +#endif /* LDAP_SLAPI */ + return NULL; +} + +Slapi_PBlock * +slapi_add_entry_internal( + Slapi_Entry *e, + LDAPControl **controls, + int log_changes ) +{ +#if defined(LDAP_SLAPI) + Connection *pConn = NULL; + Operation *op = NULL; + Slapi_PBlock *pPB = NULL, *pSavePB = NULL; + Backend *be; + + int manageDsaIt = 0; + int isCritical; + int rc = LDAP_SUCCESS; + + if ( e == NULL ) { + rc = LDAP_OPERATIONS_ERROR; + goto cleanup; + } + + pConn = fakeConnection( NULL, LDAP_REQ_ADD ); + if ( pConn == NULL ) { + rc = LDAP_NO_MEMORY; + goto cleanup; + } + + if ( slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT, + NULL, &isCritical ) ) { + manageDsaIt = 1; + } + + op = (Operation *)pConn->c_pending_ops.stqh_first; + pPB = (Slapi_PBlock *)op->o_pb; + op->o_ctrls = controls; + + be = select_backend( &e->e_nname, manageDsaIt, 0 ); + if ( be == NULL ) { + rc = LDAP_PARTIAL_RESULTS; + goto cleanup; + } + + op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val ); + op->o_ndn.bv_len = be->be_rootdn.bv_len; + pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val ); + pConn->c_dn.bv_len = be->be_rootdn.bv_len; + + if ( be->be_add ) { + int repl_user = be_isupdate( be, &op->o_ndn ); + if ( !be->be_update_ndn.bv_len || repl_user ){ + if ( (*be->be_add)( be, pConn, op, e ) == 0 ) { + if ( log_changes ) { + replog( be, op, &e->e_name, + &e->e_nname, e ); + } + rc = LDAP_SUCCESS; + } + } else { + rc = LDAP_REFERRAL; + } + } else { + rc = LDAP_UNWILLING_TO_PERFORM; + } + +cleanup: + + 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 ( op ) { + if ( op->o_ndn.bv_val ) { + slapi_ch_free( op->o_ndn.bv_val ); + } + free(op); + } + pSavePB = pPB; + free( pConn ); + } + return( pSavePB ); +#endif /* LDAP_SLAPI */ + return NULL; +} + + +Slapi_PBlock * +slapi_add_internal( + char *dn, + LDAPMod **mods, + LDAPControl **controls, + int log_changes ) +{ +#if defined(LDAP_SLAPI) + LDAPMod *pMod = NULL; + Slapi_PBlock *pb = NULL; + Entry *pEntry = NULL; + int i, rc=LDAP_SUCCESS; + + if ( mods == NULL || *mods == NULL || dn == NULL || *dn == '\0' ) { + 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); +#endif /* LDAP_SLAPI */ + return NULL; +} + +/* 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 + * + * NOTE: This function does not support the "newSuperior" option from LDAP V3. + */ +Slapi_PBlock * +slapi_modrdn_internal( + char *olddn, + char *lnewrdn, + int deloldrdn, + LDAPControl **controls, + int log_change ) +{ +#if defined(LDAP_SLAPI) + int rc = LDAP_SUCCESS; + + struct berval dn = { 0, NULL }; + struct berval pdn = { 0, NULL }; + struct berval ndn = { 0, NULL }; + + struct berval newrdn = { 0, NULL }; + struct berval pnewrdn = { 0, NULL }; + struct berval nnewrdn = { 0, NULL }; + +#if 0 /* currently unused */ + struct berval newSuperior = { 0, NULL }; +#endif + struct berval pnewSuperior = { 0, NULL }; +#if 0 /* currently unused */ + struct berval nnewSuperior = { 0, NULL }; +#endif + + struct berval *pnewS = NULL; + struct berval *nnewS = NULL; + + Connection *pConn = NULL; + Operation *op = NULL; + Slapi_PBlock *pPB = NULL; + Slapi_PBlock *pSavePB = NULL; + + Backend *be; +#if 0 /* currently unused */ + Backend *newSuperior_be = NULL; +#endif + + int manageDsaIt = 0; + int isCritical; +#if 0 /* currently unused */ + const char *text = NULL; +#endif + + dn.bv_val = slapi_ch_strdup(olddn); + dn.bv_len = slapi_ch_stlen(olddn); + + rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn ); + + if ( rc != LDAP_SUCCESS ) goto cleanup; + + if ( ndn.bv_len == 0 ) { + rc = LDAP_UNWILLING_TO_PERFORM; + goto cleanup; + } + + newrdn.bv_val = slapi_ch_strdup( lnewrdn ); + newrdn.bv_len = slapi_ch_stlen( lnewrdn ); + + rc = dnPrettyNormal( NULL, &newrdn, &pnewrdn, &nnewrdn ); + + if ( rc != LDAP_SUCCESS ) goto cleanup; + + if ( rdnValidate( &pnewrdn ) != LDAP_SUCCESS ) goto cleanup; + + pConn = fakeConnection( NULL, LDAP_REQ_MODRDN); + if ( pConn == NULL) { + rc = LDAP_NO_MEMORY; + goto cleanup; + } + + op = (Operation *)pConn->c_pending_ops.stqh_first; + pPB = (Slapi_PBlock *)op->o_pb; + op->o_ctrls = controls; + + if ( slapi_control_present( controls, + SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) { + manageDsaIt = 1; + } + + be = select_backend( &dn, manageDsaIt, 0 ); + if ( be == NULL ) { + rc = LDAP_PARTIAL_RESULTS; + goto cleanup; + } + + op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val ); + op->o_ndn.bv_len = be->be_rootdn.bv_len; + pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val ); + pConn->c_dn.bv_len = be->be_rootdn.bv_len; + + suffix_alias( be, &ndn ); + + if ( be->be_modrdn ) { + int repl_user = be_isupdate( be, &op->o_ndn ); + if ( !be->be_update_ndn.bv_len || repl_user ) { + rc = (*be->be_modrdn)( be, pConn, op, &pdn, &ndn, + &pnewrdn, &nnewrdn, deloldrdn, pnewS, + nnewS ); + if ( rc == 0 ) { + struct slap_replog_moddn moddn; + moddn.newrdn = &pnewrdn; + moddn.deloldrdn = deloldrdn; + moddn.newsup = &pnewSuperior; + if ( log_change ) { + replog( be, op, &pdn, &ndn, &moddn ); + } + rc = LDAP_SUCCESS; + + } else { + rc = LDAP_OPERATIONS_ERROR; + } + + } else { + rc = LDAP_REFERRAL; + } + + } else { + rc = LDAP_UNWILLING_TO_PERFORM; + } + +cleanup: + + if ( pPB != NULL ) { + slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc ); + } + + 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 ( newrdn.bv_val ) ch_free( newrdn.bv_val ); + if ( pnewrdn.bv_val ) ch_free( newrdn.bv_val ); + if ( nnewrdn.bv_val ) ch_free( newrdn.bv_val ); + + if ( pConn != NULL ) { + if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val ); + if ( op ) { + if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val ); + slapi_ch_free( op ); + } + pSavePB = pPB; + free( pConn ); + } + + return( pSavePB ); +#endif /* LDAP_SLAPI */ + return NULL; +} + +/* 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 *ldn, + LDAPMod **mods, + LDAPControl **controls, + int log_change ) +{ +#if defined(LDAP_SLAPI) + int i, rc = LDAP_SUCCESS; + Connection *pConn = NULL; + Operation *op = NULL; + Slapi_PBlock *pPB = NULL; + Slapi_PBlock *pSavePB = NULL; + + struct berval dn = { 0, NULL }; + struct berval pdn = { 0, NULL }; + struct berval ndn = { 0, NULL }; + + int manageDsaIt = 0; + int isCritical; + Backend *be; + struct berval *bv; + struct berval **ppBV; + LDAPMod *pMod; + + Modifications *modlist = NULL; + Modifications **modtail = &modlist; + Modifications tmp; + + if ( mods == NULL || *mods == NULL || ldn == NULL ) { + rc = LDAP_OPERATIONS_ERROR ; + goto cleanup; + } + + pConn = fakeConnection( NULL, LDAP_REQ_MODIFY ); + if ( pConn == NULL ) { + rc = LDAP_NO_MEMORY; + goto cleanup; + } + + op = (Operation *)pConn->c_pending_ops.stqh_first; + pPB = (Slapi_PBlock *)op->o_pb; + op->o_ctrls = controls; + + dn.bv_val = slapi_ch_strdup( ldn ); + dn.bv_len = slapi_strlen( ldn ); + rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn ); + if ( rc != LDAP_SUCCESS ) goto cleanup; + + if ( slapi_control_present( controls, + SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) { + manageDsaIt = 1; + } + + be = select_backend( &dn, manageDsaIt, 0 ); + if ( be == NULL ) { + rc = LDAP_PARTIAL_RESULTS; + goto cleanup; + } + + op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val ); + op->o_ndn.bv_len = be->be_rootdn.bv_len; + pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val ); + pConn->c_dn.bv_len = be->be_rootdn.bv_len; + + suffix_alias( be, &ndn ); + + 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 ) goto cleanup; + tmp.sml_type.bv_val = slapi_ch_strdup( pMod->mod_type ); + tmp.sml_type.bv_len = slapi_ch_stlen( pMod->mod_type ); + tmp.sml_bvalues = bv; + + mod = (Modifications *)ch_malloc( sizeof(Modifications) ); + + mod->sml_op = pMod->mod_op; + mod->sml_next = NULL; + mod->sml_desc = NULL; + mod->sml_type = tmp.sml_type; + mod->sml_bvalues = tmp.sml_bvalues; + } else { + rc = ValuesToBValues( pMod->mod_values, &ppBV ); + if ( rc != LDAP_SUCCESS ) goto cleanup; + rc = bvptr2obj( ppBV, &bv ); + if ( rc != LDAP_SUCCESS ) goto cleanup; + tmp.sml_type.bv_val = slapi_ch_strdup( pMod->mod_type ); + tmp.sml_type.bv_len = slapi_ch_stlen( pMod->mod_type ); + tmp.sml_bvalues = bv; + + mod = (Modifications *) ch_malloc( sizeof(Modifications) ); + + mod->sml_op = pMod->mod_op; + mod->sml_next = NULL; + mod->sml_desc = NULL; + mod->sml_type = tmp.sml_type; + mod->sml_bvalues = tmp.sml_bvalues; + + if ( ppBV != NULL ) { + ber_bvecfree( ppBV ); + } + } + *modtail = mod; + modtail = &mod->sml_next; + + switch( pMod->mod_op ) { + case LDAP_MOD_ADD: + if ( mod->sml_bvalues == NULL ) { + rc = LDAP_PROTOCOL_ERROR; + goto cleanup; + } + + /* fall through */ + case LDAP_MOD_DELETE: + case LDAP_MOD_REPLACE: + break; + + default: + rc = LDAP_PROTOCOL_ERROR; + goto cleanup; + } + } + *modtail = NULL; + + if ( ndn.bv_len == 0 ) { + rc = LDAP_UNWILLING_TO_PERFORM; + goto cleanup; + } + + if ( be->be_modify ) { + int repl_user = be_isupdate( be, &op->o_ndn ); + if ( !be->be_update_ndn.bv_len || repl_user ) { + int update = be->be_update_ndn.bv_len; + const char *text = NULL; + char textbuf[SLAP_TEXT_BUFLEN]; + size_t textlen = sizeof( textbuf ); + + rc = slap_mods_check( modlist, update, + &text, textbuf, textlen ); + if (rc != LDAP_SUCCESS) { + goto cleanup; + } + + if ( !repl_user ) { + rc = slap_mods_opattrs( be, op, modlist, + modtail, &text, textbuf, + textlen ); + if (rc != LDAP_SUCCESS) { + goto cleanup; + } + } + rc = (*be->be_modify)( be, pConn, op, + &pdn, &ndn, modlist ); + if ( rc == 0 ) { + if ( log_change ) { + replog( be, op, &pdn, &ndn, modlist ); + } + rc = LDAP_SUCCESS; + } else { + rc = LDAP_OPERATIONS_ERROR; + } + } else { + rc = LDAP_REFERRAL; + } + } else { + rc = LDAP_UNWILLING_TO_PERFORM; + } + +cleanup: + + if ( pPB != NULL ) + slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc ); + + 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 ( modlist != NULL ) slap_mods_free( modlist ); + + if ( pConn != NULL ) { + if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val ); + if ( op ) { + if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val ); + slapi_ch_free( op ); + } + pSavePB = pPB; + free( pConn ); + } + + return ( pSavePB ); + +#endif /* LDAP_SLAPI */ + return NULL; +} + +Slapi_PBlock * +slapi_search_internal_bind( + char *bindDN, + char *ldn, + int scope, + char *filStr, + LDAPControl **controls, + char **attrs, + int attrsonly ) +{ +#if defined(LDAP_SLAPI) + Backend *be; + Connection *c; + Operation *op = NULL; + Slapi_PBlock *ptr = NULL; + Slapi_PBlock *pSavePB = NULL; + struct berval dn = { 0, NULL }; + struct berval pdn = { 0, NULL }; + struct berval ndn = { 0, NULL }; + Filter *filter=NULL; + struct berval fstr = { 0, NULL }; + AttributeName *an = NULL; + const char *text = NULL; + + int deref=0; + int sizelimit=-1, timelimit=-1; + + int manageDsaIt = 0; + int isCritical; + + int i, rc = LDAP_SUCCESS; + + c = fakeConnection( NULL, LDAP_REQ_SEARCH ); + if (c == NULL) { + rc = LDAP_NO_MEMORY; + goto cleanup; + } + + op = (Operation *)c->c_pending_ops.stqh_first; + ptr = (Slapi_PBlock *)op->o_pb; + op->o_ctrls = controls; + + dn.bv_val = slapi_ch_strdup(ldn); + dn.bv_len = slapi_strlen(ldn); + + rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn ); + if (rc != LDAP_SUCCESS) goto cleanup; + + if ( scope != LDAP_SCOPE_BASE && + scope != LDAP_SCOPE_ONELEVEL && + scope != LDAP_SCOPE_SUBTREE ) { + rc = LDAP_PROTOCOL_ERROR; + goto cleanup; + } + + filter = slapi_str2filter(filStr); + if ( filter == NULL ) { + rc = LDAP_PROTOCOL_ERROR; + goto cleanup; + } + + filter2bv( filter, &fstr ); + + for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) { + ; /* count the number of attributes */ + } + + if (i > 0) { + an = (AttributeName *)slapi_ch_calloc(1, sizeof(AttributeName)); + for (i = 0; attrs[i] != 0; i++) { + an[i].an_desc = NULL; + an[i].an_oc = 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 ); + } + } + + if ( scope == LDAP_SCOPE_BASE ) { + Entry *entry = NULL; + + if ( ndn.bv_len == 0 ) { + rc = root_dse_info( c, &entry, &text ); + } + + if( rc != LDAP_SUCCESS ) { + send_ldap_result( c, op, rc, NULL, text, NULL, NULL ); + goto cleanup; + } else if ( entry != NULL ) { + rc = test_filter( NULL, c, op, entry, filter ); + + if( rc == LDAP_COMPARE_TRUE ) { + send_search_entry( NULL, c, op, entry, + an, attrsonly, NULL ); + } + + entry_free( entry ); + + send_ldap_result( c, op, LDAP_SUCCESS, + NULL, NULL, NULL, NULL ); + + rc = LDAP_SUCCESS; + + goto cleanup; + } + } + + if ( !ndn.bv_len && default_search_nbase.bv_len ) { + ch_free( pdn.bv_val ); + ch_free( ndn.bv_val ); + + ber_dupbv( &pdn, &default_search_base ); + ber_dupbv( &ndn, &default_search_nbase ); + } + + if ( slapi_control_present( controls, + LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) { + manageDsaIt = 1; + } + + be = select_backend( &dn, manageDsaIt, 0 ); + if ( be == NULL ) { + if ( manageDsaIt == 1 ) { + rc = LDAP_NO_SUCH_OBJECT; + } else { + rc = LDAP_PARTIAL_RESULTS; + } + goto cleanup; + } + + op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val ); + op->o_ndn.bv_len = be->be_rootdn.bv_len; + c->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val ); + c->c_dn.bv_len = be->be_rootdn.bv_len; + + if ( be->be_search ) { + rc = (*be->be_search)( be, c, op, &pdn, &ndn, + scope, deref, sizelimit, timelimit, + filter, &fstr, an, attrsonly ); + if ( rc == 0 ) { + rc = LDAP_SUCCESS; + } else { + rc = LDAP_OPERATIONS_ERROR; + } + } else { + rc = LDAP_UNWILLING_TO_PERFORM; + } + +cleanup: + + if ( ptr != NULL ) + slapi_pblock_set( ptr, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc ); + + if ( dn.bv_val ) free( dn.bv_val ); + if ( ndn.bv_val ) free( ndn.bv_val ); + if ( pdn.bv_val ) free( pdn.bv_val ); + + if ( filter ) slapi_filter_free( filter, 1 ); + if ( fstr.bv_val ) free ( fstr.bv_val ); + + if ( an != NULL ) free( an ); + + if ( c != NULL ) { + if ( c->c_dn.bv_val ) slapi_ch_free( c->c_dn.bv_val ); + if ( op ) { + if ( op->o_ndn.bv_val ) slapi_ch_free( op->o_ndn.bv_val ); + free( op ); + } + pSavePB = ptr; + free( c ); + } + return( pSavePB ); +#endif /* LDAP_SLAPI */ + return NULL; +} + +Slapi_PBlock * +slapi_search_internal( + char *base, + int scope, + char *filStr, + LDAPControl **controls, + char **attrs, + int attrsonly ) +{ +#if defined(LDAP_SLAPI) + return slapi_search_internal_bind( NULL, base, scope, filStr, + controls, attrs, attrsonly ); +#endif + return NULL; +} + diff -uNr servers/slapd/slapi/slapi_ops.c.all servers/slapd/slapi/slapi_ops.c.all --- servers/slapd/slapi/slapi_ops.c.all Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_ops.c.all Sat Sep 7 19:27:19 2002 @@ -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 +#include +#include +#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 -uNr servers/slapd/slapi/slapi_ops.c.save servers/slapd/slapi/slapi_ops.c.save --- servers/slapd/slapi/slapi_ops.c.save Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_ops.c.save Sat Sep 7 19:27:19 2002 @@ -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 +#include +#include +#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 -uNr servers/slapd/slapi/slapi_ops.h servers/slapd/slapi/slapi_ops.h --- servers/slapd/slapi/slapi_ops.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_ops.h Sun Nov 3 22:54:26 2002 @@ -0,0 +1,33 @@ +/* + * 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 diff -uNr servers/slapd/slapi/slapi_pblock.c servers/slapd/slapi/slapi_pblock.c --- servers/slapd/slapi/slapi_pblock.c Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_pblock.c Sun Nov 10 20:03:45 2002 @@ -0,0 +1,437 @@ +/* + * 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 +#include + +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 ) +{ + pthread_mutex_lock(&pb->pblockMutex); +} + +static void +unLock( Slapi_PBlock *pb ) +{ + pthread_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 ); + + for ( i = 0; i < pb->numParams; i++ ) { + if ( pb->curParams[i] == param ) { + *val=pb->curVals[i]; + unLock(pb); + return LDAP_SUCCESS; + } + } + *val = NULL; + 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 *) malloc(sizeof(Slapi_PBlock)); + if ( pb != NULL ) { + pb->ckParams = TRUE; + pthread_mutex_init( &pb->pblockMutex, NULL ); + 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 ) { + free( str ); + str = NULL; + } + + get( pb, SLAPI_CONN_AUTHTYPE, (void **)&str ); + if ( str != NULL ) { + free( str ); + str = NULL; + } + + get( pb, SLAPI_IBM_CONN_DN_ALT, (void **)&str ); + if ( str != NULL ) { + free( str ); + str = NULL; + } + + get( pb, SLAPI_IBM_CONN_DN_ORIG, (void **)&str ); + if ( str != NULL ) { + free( str ); + } + + pthread_mutex_destroy( &pb->pblockMutex ); + + 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 -uNr servers/slapd/slapi/slapi_pblock.h servers/slapd/slapi/slapi_pblock.h --- servers/slapd/slapi/slapi_pblock.h Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_pblock.h Sat Sep 7 19:27:19 2002 @@ -0,0 +1,39 @@ +/* + * 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 { + pthread_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 diff -uNr servers/slapd/slapi/slapi_utils.c servers/slapd/slapi/slapi_utils.c --- servers/slapd/slapi/slapi_utils.c Thu Jan 1 01:00:00 1970 +++ servers/slapd/slapi/slapi_utils.c Sun Nov 10 20:03:45 2002 @@ -0,0 +1,947 @@ +/* + * 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 +#include +#include +#include +#include +#include + +struct berval *ns_get_supported_extop (int); + +#ifdef _SPARC +#include +#endif + +#include + +static struct timeval base_time; + +/* + * This function converts an array of pointers to berval objects to + * an array of berval objects. + */ + +int +bvptr2obj( + struct berval **bvptr, + struct berval **bvobj ) +{ + int rc = LDAP_SUCCESS; + int i; + struct berval *tmpberval; + + if (bvptr == NULL || *bvptr == NULL) { + rc = LDAP_OTHER; + } else { + for ( i=0; bvptr != NULL && bvptr[i] != NULL; i++ ) { + ; /* EMPTY */ + } + tmpberval = (struct berval *)slapi_ch_malloc( (i+1)*sizeof(struct berval)); + if (tmpberval == NULL) + rc = LDAP_NO_MEMORY; + else { + for (i = 0; bvptr[i] != NULL; i++) { + tmpberval[i].bv_val = ch_strdup(bvptr[i]->bv_val); + if (tmpberval[i].bv_val == NULL) { + while(--i >= 0) { + ch_free(tmpberval[i].bv_val); + tmpberval[i].bv_val = NULL; + } + ch_free(tmpberval); + rc = LDAP_NO_MEMORY; + break; + } + 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; + char *pTmpS; + + pTmpS = slapi_ch_strdup( s ); + if ( pTmpS != NULL ) { + e=str2entry(pTmpS); + slapi_ch_free( pTmpS ); + } else { + e= NULL; + } + return e; +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +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; +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +char * +slapi_entry_get_dn( Slapi_Entry *e ) +{ +#if defined(LDAP_SLAPI) + return(e->e_name.bv_val); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +void +slapi_entry_set_dn( + Slapi_Entry *e, + char *ldn ) +{ +#if defined(LDAP_SLAPI) + struct berval dn = { 0, NULL }; + + dn.bv_val = strdup(ldn); + if (dn.bv_val == NULL) + return; + dn.bv_len = strlen(ldn); + + dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname ); + free(dn.bv_val); +#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; + + if((tmp=slapi_entry2str(e,&len)) == NULL) { + return (Slapi_Entry *)NULL; + } + if((tmpEnt=(Slapi_Entry *)str2entry(tmp)) == NULL) { + slapi_ch_free(tmp); + return (Slapi_Entry *)NULL; + } + if(tmp != NULL) slapi_ch_free(tmp); + + return tmpEnt; +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +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 */ +#endif /* defined(LDAP_SLAPI) */ + return -1; +} + +Slapi_Entry * +slapi_entry_alloc( void ) +{ +#if defined(LDAP_SLAPI) + Slapi_Entry *ent; + + if((ent=(Slapi_Entry *)slapi_ch_calloc(1,sizeof(Slapi_Entry))) == NULL) { + return (Slapi_Entry *)NULL; + } + return ent; +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +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; + struct berval *bv; + int rc = LDAP_SUCCESS; + + rc = bvptr2obj(vals, &bv); + if (rc != LDAP_SUCCESS) return -1; + rc = slap_str2ad(type, &ad, &text ); + if (rc != LDAP_SUCCESS) return -1; + return(attr_merge(e, ad ,bv)); +#endif /* defined(LDAP_SLAPI) */ + return -1; +} + +int +slapi_entry_attr_find( + Slapi_Entry *e, + char *type, + Slapi_Attr **attr ) +{ +#if defined(LDAP_SLAPI) + + AttributeDescription *ad; + const char *text; + int rc = LDAP_SUCCESS; + + rc = slap_str2ad(type, &ad, &text ); + if( rc != LDAP_SUCCESS ) return -1; + if((*attr=attr_find(e->e_attrs, ad)) == NULL) + return -1; + else + return 0; +#endif /* defined(LDAP_SLAPI) */ + return -1; +} + +/* + * 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; +#endif /* defined(LDAP_SLAPI) */ + return -1; +} + +char * +slapi_dn_normalize( char *dn ) +{ +#if defined(LDAP_SLAPI) + struct berval *base = NULL; + struct berval *nbase = NULL; + + base->bv_val = ch_strdup(dn); + base->bv_len = strlen(dn); + + dnNormalize( NULL, base, &nbase ); + + free(dn); + dn = ch_strdup(nbase->bv_val); + ch_free(base->bv_val); + ch_free(nbase->bv_val); + + return(dn); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +char * +slapi_dn_normalize_case( char *dn ) +{ +#if defined(LDAP_SLAPI) + char *s; + + slapi_dn_normalize(dn); + for ( s = dn; *s; s++ ) { + *s = tolower(*s); + } + return( dn ); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +int +slapi_dn_issuffix( + char *dn, + char *suffix ) +{ +#if defined(LDAP_SLAPI) + int rtn; + struct berval ldn; + struct berval lsuffix; + + ldn.bv_val = ch_strdup(dn); + ldn.bv_len = strlen(dn); + + lsuffix.bv_val = ch_strdup(suffix); + lsuffix.bv_len = strlen(suffix); + + slapi_dn_normalize( ldn.bv_val ); + slapi_dn_normalize( lsuffix.bv_val ); + + rtn = dnIsSuffix(&ldn, &lsuffix); + ch_free(ldn.bv_val); + ch_free(lsuffix.bv_val); + + return rtn; +#endif /* defined(LDAP_SLAPI) */ + return 0; +} + +char * +slapi_dn_ignore_case( char *dn ) +{ +#if defined(LDAP_SLAPI) + char *s; + + slapi_dn_normalize(dn); + for ( s = dn; *s; s++ ) { + *s = tolower(*s); + } + + return( dn ); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +char * +slapi_ch_malloc( unsigned long size ) +{ +#if defined(LDAP_SLAPI) + return(ch_malloc(size)); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +void +slapi_ch_free( void *ptr ) +{ +#if defined(LDAP_SLAPI) + if(ptr != NULL) + 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)); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +char * +slapi_ch_realloc( + char *block, + unsigned long size ) +{ +#if defined(LDAP_SLAPI) + return(ch_realloc(block,size)); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +char * +slapi_ch_strdup( char *s ) +{ +#if defined(LDAP_SLAPI) + return(ch_strdup((const char *)s )); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +size_t +slapi_ch_stlen( char *s ) +{ +#if defined(LDAP_SLAPI) + return(strlen((const char *)s )); +#endif /* defined(LDAP_SLAPI) */ + return 0; +} + +int +slapi_control_present( + LDAPControl **controls, + char *oid, + struct berval **val, + int *iscritical ) +{ +#if defined(LDAP_SLAPI) + int i; + int rc = 0; + struct berval *pTmpBval; + + 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 ) { + rc = 1; + if ( controls[i]->ldctl_value.bv_len != 0 ) { + 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; + } + } + } else { + if ( val ) { + *val = NULL; + } + } + if ( iscritical ) { + *iscritical = controls[i]->ldctl_iscritical; + } + } + } + return ( rc ); +#endif /* defined(LDAP_SLAPI) */ + return 0; +} + +void +slapi_register_supported_control( + char *controloid, + unsigned long controlops ) +{ +#if defined(LDAP_SLAPI) + /* FIXME -- can not add controls to openLDAP dynamically */ +#endif /* defined(LDAP_SLAPI) */ +} + +int +slapi_get_supported_controls( + char ***ctrloidsp, + unsigned long **ctrlopsp ) +{ +#if defined(LDAP_SLAPI) + int i; + int rc = 1; + char **oids; + unsigned long *masks; + + for (i = 0; (get_supported_ctrl(i) != NULL); i++) + ; /* count them */ + + if (i == 0) { /* not controls */ + *ctrloidsp = NULL; + *ctrlopsp = NULL; + rc = LDAP_SUCCESS; + } else { + oids = (char **)slapi_ch_malloc( (i+1) * sizeof(char *) ); + masks = (unsigned long *)slapi_ch_malloc((i+ 1) * sizeof(int)); + for (i = 0; (get_supported_ctrl(i) != NULL); i++) { + oids[i] = strdup(get_supported_ctrl(i)); + masks[i] = (unsigned long)get_supported_ctrl_mask(i); + } + oids[i] = NULL; + *ctrloidsp = oids; + *ctrlopsp = masks; + rc = LDAP_SUCCESS; + } + return rc; +#endif /* defined(LDAP_SLAPI) */ + return 1; +} + +void +slapi_register_supported_saslmechanism( char *mechanism ) +{ +#if defined(LDAP_SLAPI) + /* FIXME -- can not add saslmechanism to openLDAP dynamically */ +#endif /* defined(LDAP_SLAPI) */ +} + +char ** +slapi_get_supported_saslmechanisms( void ) +{ +#if defined(LDAP_SLAPI) + /* FIXME -- can not get the saslmechanism wihtout a connection. */ + return NULL; +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +char ** +slapi_get_supported_extended_ops( void ) +{ +#if defined(LDAP_SLAPI) + int i, j, k; + char **ppExtOpOID = NULL; + int numExtOps = 0; + struct berval *bv; + + 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 ) { + k = 0; + ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps + 1) * sizeof(char *) ); + if (i > 0) { + for ( ; (bv = get_supported_extop(k)) != NULL; k++ ) { + ppExtOpOID[k] = bv->bv_val; + } + } + if (j > 0) { + for ( j = 0; (bv = ns_get_supported_extop(j)) != NULL; j++ ) { + ppExtOpOID[k++] = bv->bv_val; + } + } + ppExtOpOID[k] = NULL; + } + + return ( ppExtOpOID ); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +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 *) 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_OPERATIONS_ERROR; + } else { + rc = send_search_entry( be, pConn, pOp, e, an, attrsonly, NULL ); + } + + return( rc ); + +#endif /* defined(LDAP_SLAPI) */ + return -1; +} + + +Slapi_Filter * +slapi_str2filter( char *str ) +{ +#if defined(LDAP_SLAPI) + return(str2filter(str)); +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +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 ); +#endif /* defined(LDAP_SLAPI) */ + return -1; /* invalid filter type */ +} + +int +slapi_filter_get_ava( Slapi_Filter *f, + char **type, + struct berval **bval ) +{ +#if defined(LDAP_SLAPI) + int ftype; + int rc=LDAP_SUCCESS; + + 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; + } else { + *bval = (struct berval *)slapi_ch_malloc(sizeof(struct berval)); + if ( *bval == NULL ) { + rc = LDAP_NO_MEMORY; + slapi_ch_free( *type ); + } else { + (*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; + slapi_ch_free( *type ); + slapi_ch_free( *bval ); + } + } + } + } else { /* filter type not supported */ + rc = -1; + } + + return( rc ); +#endif /* defined(LDAP_SLAPI) */ + return -1; +} + +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 ); + } +#endif /* defined(LDAP_SLAPI) */ + return (NULL); +} + +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 ); +#endif /* defined(LDAP_SLAPI) */ + return (NULL); +} + +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; +#endif /* defined(LDAP_SLAPI) */ + return -1; +} + +int +slapi_pw_find( + struct berval **vals, + struct berval *v ) +{ +#if defined(LDAP_SLAPI) + return 1; +#endif /* defined(LDAP_SLAPI) */ + return 1; +} + +char * +slapi_get_hostname( void ) +{ +#if defined(LDAP_SLAPI) + char *hn=NULL; + + /* + * FIXME: I'd prefer a different check ... + */ +#if defined _SPARC + if((hn=(char *)slapi_ch_malloc(MAX_HOSTNAME)) == NULL) { + printf("can't malloc memory for hostname\n"); + hn=NULL; + } else if (sysinfo(SI_HOSTNAME, hn, MAX_HOSTNAME) <0) { + printf("can't get hostname"); + slapi_ch_free(hn); + hn=NULL; + } +#else /* !_SPARC */ + static int been_here = 0; + static char* static_hn = NULL; + if (!been_here) { + if((static_hn=(char *)slapi_ch_malloc(MAX_HOSTNAME)) == NULL) { + printf("can't malloc memory for hostname\n"); + static_hn=NULL; + return hn; + } else { + if (gethostname(static_hn,MAX_HOSTNAME) !=0) { + printf("can't get hostname"); + slapi_ch_free(static_hn); + static_hn=NULL; + return hn; + } else + been_here = 1; + } + } + hn = strdup(static_hn); + if (hn == NULL) + return hn; +#endif /* !_SPARC */ + + return(hn); + +#endif /* defined(LDAP_SLAPI) */ + return NULL; +} + +/* + * 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); +#endif /* defined(LDAP_SLAPI) */ + return -1; + +} + + +unsigned +long slapi_timer_current_time( void ) +{ +#if defined(LDAP_SLAPI) + static int first_time = 1; +#if !defined (_WIN32) + struct timeval now; + + if (first_time) { + first_time = 0; + gettimeofday(&base_time, NULL); + } + gettimeofday(&now, NULL); + return (now.tv_sec - base_time.tv_sec ) * 1000000 + + (now.tv_usec - base_time.tv_usec); +#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 */ +#endif /* defined(LDAP_SLAPI) */ + return 0; +} + +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; +#endif /* defined(LDAP_SLAPI) */ + return 0; +} + +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