]> git.sur5r.net Git - openldap/commitdiff
put back chain overlay into back-ldap
authorPierangelo Masarati <ando@openldap.org>
Sun, 9 Jan 2005 21:26:32 +0000 (21:26 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 9 Jan 2005 21:26:32 +0000 (21:26 +0000)
servers/slapd/back-ldap/Makefile.in
servers/slapd/back-ldap/chain.c [new file with mode: 0644]
servers/slapd/back-ldap/init.c
servers/slapd/overlays/Makefile.in
servers/slapd/overlays/chain.c [deleted file]
servers/slapd/overlays/overlays.c

index 2512bd3c3be44880eb408801cdebf8dcd5985bc0..8b05a86db8881cffbde6f4a3753097179659bf0a 100644 (file)
@@ -14,9 +14,9 @@
 ## <http://www.OpenLDAP.org/license.html>.
 
 SRCS   = init.c config.c search.c bind.c unbind.c add.c compare.c \
-               delete.c modify.c modrdn.c extended.c
+               delete.c modify.c modrdn.c extended.c chain.c
 OBJS   = init.lo config.lo search.lo bind.lo unbind.lo add.lo compare.lo \
-               delete.lo modify.lo modrdn.lo extended.lo
+               delete.lo modify.lo modrdn.lo extended.lo chain.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries
diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c
new file mode 100644 (file)
index 0000000..a580c52
--- /dev/null
@@ -0,0 +1,483 @@
+/* chain.c - chain LDAP operations */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2003-2005 The OpenLDAP Foundation.
+ * Portions Copyright 2003 Howard Chu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by the Howard Chu for inclusion
+ * in OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-ldap.h"
+
+static BackendInfo *lback;
+
+static int
+ldap_chain_chk_referrals( Operation *op, SlapReply *rs )
+{
+       return LDAP_SUCCESS;
+}
+
+static int
+ldap_chain_operational( Operation *op, SlapReply *rs )
+{
+       /* trap entries generated by back-ldap.
+        * FIXME: we need a better way to recognize them; a cleaner
+        * solution would be to be able to intercept the response
+        * of be_operational(), so that we can divert only those
+        * calls that fail because operational attributes were
+        * requested for entries that do not belong to the underlying
+        * database.  This fix is likely to intercept also entries
+        * generated by back-perl and so. */
+       if ( rs->sr_entry->e_private == NULL ) {
+               return 0;
+       }
+
+       return SLAP_CB_CONTINUE;
+}
+
+static int
+ldap_chain_cb_response( Operation *op, SlapReply *rs )
+{
+       assert( op->o_tag == LDAP_REQ_SEARCH );
+
+       if ( rs->sr_type == REP_SEARCH ) {
+               Attribute       **ap = &rs->sr_entry->e_attrs;
+
+               for ( ; *ap != NULL; ap = &(*ap)->a_next ) {
+                       /* will be generated later by frontend
+                        * (a cleaner solution would be that
+                        * the frontend checks if it already exists */
+                       if ( ad_cmp( (*ap)->a_desc, slap_schema.si_ad_entryDN ) == 0 )
+                       {
+                               Attribute *a = *ap;
+
+                               *ap = (*ap)->a_next;
+                               attr_free( a );
+
+                               /* there SHOULD be one only! */
+                               break;
+                       }
+               }
+               
+               return SLAP_CB_CONTINUE;
+       }
+
+       return 0;
+}
+
+static int
+ldap_chain_response( Operation *op, SlapReply *rs )
+{
+       slap_overinst   *on = (slap_overinst *) op->o_bd->bd_info;
+       void            *private = op->o_bd->be_private;
+       slap_callback   *sc = op->o_callback;
+       LDAPControl     **prev = op->o_ctrls;
+       LDAPControl     **ctrls = NULL, authz;
+       int             i, nctrls, rc = 0;
+       int             cache = op->o_do_not_cache;
+       char            *authzid = NULL;
+       BerVarray       ref;
+       struct berval   ndn = op->o_ndn;
+
+       struct ldapinfo li, *lip = (struct ldapinfo *)on->on_bi.bi_private;
+
+       if ( rs->sr_err != LDAP_REFERRAL && rs->sr_type != REP_SEARCHREF )
+               return SLAP_CB_CONTINUE;
+
+       ref = rs->sr_ref;
+       rs->sr_ref = NULL;
+
+       op->o_callback = NULL;
+
+       if ( lip->url == NULL ) {
+               /* if we parse the URI then by no means 
+                * we can cache stuff or reuse connections, 
+                * because in back-ldap there's no caching
+                * based on the URI value, which is supposed
+                * to be set once for all (correct?) */
+               op->o_do_not_cache = 1;
+
+               /* FIXME: we're setting the URI of the first referral;
+                * what if there are more?  Is this something we should
+                * worry about? */
+               li = *lip;
+               op->o_bd->be_private = &li;
+
+               if ( rs->sr_type != REP_SEARCHREF ) {
+                       LDAPURLDesc     *srv;
+                       char            *save_dn;
+
+                       /* parse reference and use 
+                        * proto://[host][:port]/ only */
+                       rc = ldap_url_parse_ext( ref[0].bv_val, &srv );
+                       if ( rc != LDAP_URL_SUCCESS) {
+                               /* error */
+                               return 1;
+                       }
+
+                       /* remove DN essentially because later on 
+                        * ldap_initialize() will parse the URL 
+                        * as a comma-separated URL list */
+                       save_dn = srv->lud_dn;
+                       srv->lud_dn = "";
+                       srv->lud_scope = LDAP_SCOPE_DEFAULT;
+                       li.url = ldap_url_desc2str( srv );
+                       srv->lud_dn = save_dn;
+                       ldap_free_urldesc( srv );
+
+                       if ( li.url == NULL ) {
+                               /* error */
+                               return 1;
+                       }
+               }
+
+       } else {
+               op->o_bd->be_private = on->on_bi.bi_private;
+       }
+
+       /* Chaining is performed by a privileged user on behalf
+        * of a normal user, using the ProxyAuthz control. However,
+        * Binds are done separately, on an anonymous session.
+        */
+       if ( op->o_tag != LDAP_REQ_BIND ) {
+               for ( i = 0; prev && prev[i]; i++ )
+                       /* count and set prev to the last one */ ;
+               nctrls = i;
+
+               /* Add an extra NULL slot */
+               if ( !prev ) {
+                       i++;
+               }
+
+               ctrls = op->o_tmpalloc((i + 1)*sizeof(LDAPControl *),
+                       op->o_tmpmemctx);
+               for ( i = 0; i < nctrls; i++ ) {
+                       ctrls[i] = prev[i];
+               }
+               ctrls[nctrls] = &authz;
+               ctrls[nctrls + 1] = NULL;
+               authz.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
+               authz.ldctl_iscritical = 1;
+               authz.ldctl_value = op->o_dn;
+               if ( !BER_BVISEMPTY( &op->o_dn ) ) {
+                       authzid = op->o_tmpalloc( op->o_dn.bv_len + STRLENOF("dn:"),
+                               op->o_tmpmemctx );
+                       strcpy(authzid, "dn:");
+                       strcpy(authzid + STRLENOF("dn:"), op->o_dn.bv_val);
+                       authz.ldctl_value.bv_len = op->o_dn.bv_len + STRLENOF("dn:");
+                       authz.ldctl_value.bv_val = authzid;
+               }
+               op->o_ctrls = ctrls;
+               op->o_ndn = op->o_bd->be_rootndn;
+       }
+
+       switch ( op->o_tag ) {
+       case LDAP_REQ_BIND: {
+               struct berval   rndn = op->o_req_ndn;
+               Connection      *conn = op->o_conn;
+
+               op->o_req_ndn = slap_empty_bv;
+
+               op->o_conn = NULL;
+               rc = lback->bi_op_bind( op, rs );
+               op->o_req_ndn = rndn;
+               op->o_conn = conn;
+               }
+               break;
+       case LDAP_REQ_ADD:
+               {
+               int             cleanup_attrs = 0;
+
+               if ( op->ora_e->e_attrs == NULL ) {
+                       char            textbuf[ SLAP_TEXT_BUFLEN ];
+                       size_t          textlen = sizeof( textbuf );
+
+                       /* global overlay; create entry */
+                       /* NOTE: this is a hack to use the chain overlay
+                        * as global.  I expect to be able to remove this
+                        * soon by using slap_mods2entry() earlier in
+                        * do_add(), adding the operational attrs later
+                        * if required. */
+                       rs->sr_err = slap_mods2entry( op->ora_modlist,
+                                       &op->ora_e, 0, 1,
+                                       &rs->sr_text, textbuf, textlen );
+                       if ( rs->sr_err != LDAP_SUCCESS ) {
+                               send_ldap_result( op, rs );
+                               rc = 1;
+                               break;
+                       }
+               }
+               rc = lback->bi_op_add( op, rs );
+               if ( cleanup_attrs ) {
+                       attrs_free( op->ora_e->e_attrs );
+                       op->ora_e->e_attrs = NULL;
+               }
+               break;
+               }
+       case LDAP_REQ_DELETE:
+               rc = lback->bi_op_delete( op, rs );
+               break;
+       case LDAP_REQ_MODRDN:
+               rc = lback->bi_op_modrdn( op, rs );
+               break;
+       case LDAP_REQ_MODIFY:
+               rc = lback->bi_op_modify( op, rs );
+               break;
+       case LDAP_REQ_COMPARE:
+               rc = lback->bi_op_compare( op, rs );
+               break;
+       case LDAP_REQ_SEARCH:
+               if ( rs->sr_type == REP_SEARCHREF ) {
+                       struct berval   *curr = ref,
+                                       odn = op->o_req_dn,
+                                       ondn = op->o_req_ndn;
+                       slap_callback   sc2 = { 0 };
+                       int             tmprc = 0;
+                       ber_len_t       refcnt = 0;
+                       BerVarray       newref = NULL;
+
+                       sc2.sc_response = ldap_chain_cb_response;
+                       op->o_callback = &sc2;
+
+                       rs->sr_type = REP_SEARCH;
+
+                       /* copy the private info because we need to modify it */
+                       for ( ; !BER_BVISNULL( &curr[0] ); curr++ ) {
+                               LDAPURLDesc     *srv;
+                               char            *save_dn;
+
+                               /* parse reference and use
+                                * proto://[host][:port]/ only */
+                               tmprc = ldap_url_parse_ext( curr[0].bv_val, &srv );
+                               if ( tmprc != LDAP_URL_SUCCESS ) {
+                                       /* error */
+                                       rc = 1;
+                                       goto end_of_searchref;
+                               }
+
+                               /* remove DN essentially because later on 
+                                * ldap_initialize() will parse the URL 
+                                * as a comma-separated URL list */
+                               save_dn = srv->lud_dn;
+                               srv->lud_dn = "";
+                               srv->lud_scope = LDAP_SCOPE_DEFAULT;
+                               li.url = ldap_url_desc2str( srv );
+                               if ( li.url != NULL ) {
+                                       ber_str2bv_x( save_dn, 0, 1, &op->o_req_dn,
+                                                       op->o_tmpmemctx );
+                                       ber_dupbv_x( &op->o_req_ndn, &op->o_req_dn,
+                                                       op->o_tmpmemctx );
+                               }
+
+                               srv->lud_dn = save_dn;
+                               ldap_free_urldesc( srv );
+
+                               if ( li.url == NULL ) {
+                                       /* error */
+                                       rc = 1;
+                                       goto end_of_searchref;
+                               }
+
+
+                               /* FIXME: should we also copy filter and scope?
+                                * according to RFC3296, no */
+                               tmprc = lback->bi_op_search( op, rs );
+
+                               ldap_memfree( li.url );
+                               li.url = NULL;
+
+                               op->o_tmpfree( op->o_req_dn.bv_val,
+                                               op->o_tmpmemctx );
+                               op->o_tmpfree( op->o_req_ndn.bv_val,
+                                               op->o_tmpmemctx );
+
+                               if ( tmprc ) {
+                                       /* error */
+                                       rc = 1;
+                                       goto end_of_searchref;
+                               }
+
+                               if ( rs->sr_err != LDAP_SUCCESS ) {
+                                       /* if search was not successful,
+                                        * at least return the referral! */
+                                       /* FIXME: assumes referrals 
+                                        * are always created via
+                                        * referral_rewrite() and freed via
+                                        * ber_bvarray_free( rs->sr_ref ) */
+                                       newref = ch_realloc( newref, sizeof( struct berval ) * (refcnt + 2) );
+                                       ber_dupbv( &newref[ refcnt ], &curr[ 0 ] );
+                                       refcnt++;
+                                       BER_BVZERO( &newref[ refcnt ] );
+                               }
+                       }
+
+end_of_searchref:;
+                       op->o_req_dn = odn;
+                       op->o_req_ndn = ondn;
+                       rs->sr_type = REP_SEARCHREF;
+                       rs->sr_entry = NULL;
+
+                       /* if the error was bad, it was already returned
+                        * by back-ldap; destroy the referrals left;
+                        * otherwise, let the frontend return them. */
+                       if ( newref ) {
+                               if ( rc == 0 ) {
+                                       rc = SLAP_CB_CONTINUE;
+                                       if ( ref != default_referral ) {
+                                               ber_bvarray_free( ref );
+                                       }
+                                       ref = newref;
+
+                               } else {
+                                       ber_bvarray_free( newref );
+                               }
+                       }
+                       
+               } else {
+                       rc = lback->bi_op_search( op, rs );
+               }
+               break;
+       case LDAP_REQ_EXTENDED:
+               rc = lback->bi_extended( op, rs );
+               break;
+       default:
+               rc = SLAP_CB_CONTINUE;
+               break;
+       }
+       op->o_do_not_cache = cache;
+       op->o_ctrls = prev;
+       op->o_bd->be_private = private;
+       op->o_callback = sc;
+       op->o_ndn = ndn;
+       if ( ctrls ) {
+               op->o_tmpfree( ctrls, op->o_tmpmemctx );
+       }
+       if ( authzid ) {
+               op->o_tmpfree( authzid, op->o_tmpmemctx );
+       }
+       rs->sr_ref = ref;
+       if ( lip->url == NULL && li.url != NULL ) {
+               ldap_memfree( li.url );
+       }
+
+       return rc;
+}
+
+static int
+ldap_chain_db_config(
+       BackendDB       *be,
+       const char      *fname,
+       int             lineno,
+       int             argc,
+       char    **argv
+)
+{
+       slap_overinst   *on = (slap_overinst *) be->bd_info;
+       void            *private = be->be_private;
+       char            *argv0 = NULL;
+       int             rc;
+
+       be->be_private = on->on_bi.bi_private;
+       if ( strncasecmp( argv[ 0 ], "chain-", sizeof( "chain-" ) - 1 ) == 0 ) {
+               argv0 = argv[ 0 ];
+               argv[ 0 ] = &argv[ 0 ][ sizeof( "chain-" ) - 1 ];
+       }
+       rc = lback->bi_db_config( be, fname, lineno, argc, argv );
+       if ( argv0 ) {
+               argv[ 0 ] = argv0;
+       }
+       
+       be->be_private = private;
+       return rc;
+}
+
+static int
+ldap_chain_db_init(
+       BackendDB *be
+)
+{
+       slap_overinst *on = (slap_overinst *) be->bd_info;
+       void *private = be->be_private;
+       int rc;
+
+       if ( lback == NULL ) {
+               lback = backend_info( "ldap" );
+
+               if ( lback == NULL ) {
+                       return -1;
+               }
+       }
+
+       be->be_private = NULL;
+       rc = lback->bi_db_init( be );
+       on->on_bi.bi_private = be->be_private;
+       be->be_private = private;
+
+       return rc;
+}
+
+static int
+ldap_chain_db_destroy(
+       BackendDB *be
+)
+{
+       slap_overinst *on = (slap_overinst *) be->bd_info;
+       void *private = be->be_private;
+       int rc;
+
+       be->be_private = on->on_bi.bi_private;
+       rc = lback->bi_db_destroy( be );
+       on->on_bi.bi_private = be->be_private;
+       be->be_private = private;
+       return rc;
+}
+
+static slap_overinst ldapchain;
+
+int
+chain_init( void )
+{
+       ldapchain.on_bi.bi_type = "chain";
+       ldapchain.on_bi.bi_db_init = ldap_chain_db_init;
+       ldapchain.on_bi.bi_db_config = ldap_chain_db_config;
+       ldapchain.on_bi.bi_db_destroy = ldap_chain_db_destroy;
+       
+       /* ... otherwise the underlying backend's function would be called,
+        * likely passing an invalid entry; on the contrary, the requested
+        * operational attributes should have been returned while chasing
+        * the referrals.  This all in all is a bit messy, because part
+        * of the operational attributes are generated by they backend;
+        * part by the frontend; back-ldap should receive all the available
+        * ones from the remote server, but then, on it own, it strips those
+        * it assumes will be (re)generated by the frontend (e.g.
+        * subschemaSubentry.) */
+       ldapchain.on_bi.bi_operational = ldap_chain_operational;
+       
+       ldapchain.on_response = ldap_chain_response;
+
+
+       ldapchain.on_bi.bi_chk_referrals = ldap_chain_chk_referrals;
+
+       return overlay_register( &ldapchain );
+}
+
index f3ebb20da237aeded222288ef49d2f0f43ccae05..90604606f066b6d8aaa8339c259ec10d81cd3cd2 100644 (file)
@@ -70,6 +70,10 @@ ldap_back_initialize( BackendInfo *bi )
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = ldap_back_conn_destroy;
 
+       if ( chain_init( ) ) {
+               return -1;
+       }
+
        return 0;
 }
 
index e40ed9971e24dc973e736907f3a178943fe2a95a..9f95972edc29e1c6eed49e797d7890c39224122e 100644 (file)
@@ -14,7 +14,6 @@
 ## <http://www.OpenLDAP.org/license.html>.
 
 SRCS = overlays.c \
-       chain.c \
        denyop.c \
        dyngroup.c \
        glue.c \
@@ -26,7 +25,6 @@ SRCS = overlays.c \
        syncprov.c \
        unique.c
 OBJS = overlays.lo \
-       chain.lo \
        denyop.lo \
        dyngroup.lo \
        glue.lo \
@@ -53,9 +51,6 @@ PROGRAMS = @SLAPD_DYNAMIC_OVERLAYS@
 XINCPATH = -I.. -I$(srcdir)/..
 XDEFS = $(MODULES_CPPFLAGS)
 
-chain.la : chain.lo $(@PLAT@_LINK_LIBS)
-       $(LTLINK_MOD) -module -o $@ chain.lo version.lo $(LINK_LIBS)
-
 denyop.la : denyop.lo $(@PLAT@_LINK_LIBS)
        $(LTLINK_MOD) -module -o $@ denyop.lo version.lo $(LINK_LIBS)
 
diff --git a/servers/slapd/overlays/chain.c b/servers/slapd/overlays/chain.c
deleted file mode 100644 (file)
index bc703da..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/* chain.c - chain LDAP operations */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2003-2005 The OpenLDAP Foundation.
- * Portions Copyright 2003 Howard Chu.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was initially developed by the Howard Chu for inclusion
- * in OpenLDAP Software.
- */
-
-#include "portable.h"
-
-#if defined(SLAPD_LDAP) 
-
-#ifdef SLAPD_OVER_CHAIN
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "../back-ldap/back-ldap.h"
-
-static BackendInfo *lback;
-
-static int
-ldap_chain_chk_referrals( Operation *op, SlapReply *rs )
-{
-       return LDAP_SUCCESS;
-}
-
-static int
-ldap_chain_operational( Operation *op, SlapReply *rs )
-{
-       /* trap entries generated by back-ldap.
-        * FIXME: we need a better way to recognize them; a cleaner
-        * solution would be to be able to intercept the response
-        * of be_operational(), so that we can divert only those
-        * calls that fail because operational attributes were
-        * requested for entries that do not belong to the underlying
-        * database.  This fix is likely to intercept also entries
-        * generated by back-perl and so. */
-       if ( rs->sr_entry->e_private == NULL ) {
-               return 0;
-       }
-
-       return SLAP_CB_CONTINUE;
-}
-
-static int
-ldap_chain_cb_response( Operation *op, SlapReply *rs )
-{
-       assert( op->o_tag == LDAP_REQ_SEARCH );
-
-       if ( rs->sr_type == REP_SEARCH ) {
-               Attribute       **ap = &rs->sr_entry->e_attrs;
-
-               for ( ; *ap != NULL; ap = &(*ap)->a_next ) {
-                       /* will be generated later by frontend
-                        * (a cleaner solution would be that
-                        * the frontend checks if it already exists */
-                       if ( ad_cmp( (*ap)->a_desc, slap_schema.si_ad_entryDN ) == 0 )
-                       {
-                               Attribute *a = *ap;
-
-                               *ap = (*ap)->a_next;
-                               attr_free( a );
-
-                               /* there SHOULD be one only! */
-                               break;
-                       }
-               }
-               
-               return SLAP_CB_CONTINUE;
-       }
-
-       return 0;
-}
-
-static int
-ldap_chain_response( Operation *op, SlapReply *rs )
-{
-       slap_overinst   *on = (slap_overinst *) op->o_bd->bd_info;
-       void            *private = op->o_bd->be_private;
-       slap_callback   *sc = op->o_callback;
-       LDAPControl     **prev = op->o_ctrls;
-       LDAPControl     **ctrls = NULL, authz;
-       int             i, nctrls, rc = 0;
-       int             cache = op->o_do_not_cache;
-       char            *authzid = NULL;
-       BerVarray       ref;
-       struct berval   ndn = op->o_ndn;
-
-       struct ldapinfo li, *lip = (struct ldapinfo *)on->on_bi.bi_private;
-
-       if ( rs->sr_err != LDAP_REFERRAL && rs->sr_type != REP_SEARCHREF )
-               return SLAP_CB_CONTINUE;
-
-       ref = rs->sr_ref;
-       rs->sr_ref = NULL;
-
-       op->o_callback = NULL;
-
-       if ( lip->url == NULL ) {
-               /* if we parse the URI then by no means 
-                * we can cache stuff or reuse connections, 
-                * because in back-ldap there's no caching
-                * based on the URI value, which is supposed
-                * to be set once for all (correct?) */
-               op->o_do_not_cache = 1;
-
-               /* FIXME: we're setting the URI of the first referral;
-                * what if there are more?  Is this something we should
-                * worry about? */
-               li = *lip;
-               op->o_bd->be_private = &li;
-
-               if ( rs->sr_type != REP_SEARCHREF ) {
-                       LDAPURLDesc     *srv;
-                       char            *save_dn;
-
-                       /* parse reference and use 
-                        * proto://[host][:port]/ only */
-                       rc = ldap_url_parse_ext( ref[0].bv_val, &srv );
-                       if ( rc != LDAP_URL_SUCCESS) {
-                               /* error */
-                               return 1;
-                       }
-
-                       /* remove DN essentially because later on 
-                        * ldap_initialize() will parse the URL 
-                        * as a comma-separated URL list */
-                       save_dn = srv->lud_dn;
-                       srv->lud_dn = "";
-                       srv->lud_scope = LDAP_SCOPE_DEFAULT;
-                       li.url = ldap_url_desc2str( srv );
-                       srv->lud_dn = save_dn;
-                       ldap_free_urldesc( srv );
-
-                       if ( li.url == NULL ) {
-                               /* error */
-                               return 1;
-                       }
-               }
-
-       } else {
-               op->o_bd->be_private = on->on_bi.bi_private;
-       }
-
-       /* Chaining is performed by a privileged user on behalf
-        * of a normal user, using the ProxyAuthz control. However,
-        * Binds are done separately, on an anonymous session.
-        */
-       if ( op->o_tag != LDAP_REQ_BIND ) {
-               for ( i = 0; prev && prev[i]; i++ )
-                       /* count and set prev to the last one */ ;
-               nctrls = i;
-
-               /* Add an extra NULL slot */
-               if ( !prev ) {
-                       i++;
-               }
-
-               ctrls = op->o_tmpalloc((i + 1)*sizeof(LDAPControl *),
-                       op->o_tmpmemctx);
-               for ( i = 0; i < nctrls; i++ ) {
-                       ctrls[i] = prev[i];
-               }
-               ctrls[nctrls] = &authz;
-               ctrls[nctrls + 1] = NULL;
-               authz.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
-               authz.ldctl_iscritical = 1;
-               authz.ldctl_value = op->o_dn;
-               if ( !BER_BVISEMPTY( &op->o_dn ) ) {
-                       authzid = op->o_tmpalloc( op->o_dn.bv_len + STRLENOF("dn:"),
-                               op->o_tmpmemctx );
-                       strcpy(authzid, "dn:");
-                       strcpy(authzid + STRLENOF("dn:"), op->o_dn.bv_val);
-                       authz.ldctl_value.bv_len = op->o_dn.bv_len + STRLENOF("dn:");
-                       authz.ldctl_value.bv_val = authzid;
-               }
-               op->o_ctrls = ctrls;
-               op->o_ndn = op->o_bd->be_rootndn;
-       }
-
-       switch ( op->o_tag ) {
-       case LDAP_REQ_BIND: {
-               struct berval   rndn = op->o_req_ndn;
-               Connection      *conn = op->o_conn;
-
-               op->o_req_ndn = slap_empty_bv;
-
-               op->o_conn = NULL;
-               rc = lback->bi_op_bind( op, rs );
-               op->o_req_ndn = rndn;
-               op->o_conn = conn;
-               }
-               break;
-       case LDAP_REQ_ADD:
-               {
-               int             cleanup_attrs = 0;
-
-               if ( op->ora_e->e_attrs == NULL ) {
-                       char            textbuf[ SLAP_TEXT_BUFLEN ];
-                       size_t          textlen = sizeof( textbuf );
-
-                       /* global overlay; create entry */
-                       /* NOTE: this is a hack to use the chain overlay
-                        * as global.  I expect to be able to remove this
-                        * soon by using slap_mods2entry() earlier in
-                        * do_add(), adding the operational attrs later
-                        * if required. */
-                       rs->sr_err = slap_mods2entry( op->ora_modlist,
-                                       &op->ora_e, 0, 1,
-                                       &rs->sr_text, textbuf, textlen );
-                       if ( rs->sr_err != LDAP_SUCCESS ) {
-                               send_ldap_result( op, rs );
-                               rc = 1;
-                               break;
-                       }
-               }
-               rc = lback->bi_op_add( op, rs );
-               if ( cleanup_attrs ) {
-                       attrs_free( op->ora_e->e_attrs );
-                       op->ora_e->e_attrs = NULL;
-               }
-               break;
-               }
-       case LDAP_REQ_DELETE:
-               rc = lback->bi_op_delete( op, rs );
-               break;
-       case LDAP_REQ_MODRDN:
-               rc = lback->bi_op_modrdn( op, rs );
-               break;
-       case LDAP_REQ_MODIFY:
-               rc = lback->bi_op_modify( op, rs );
-               break;
-       case LDAP_REQ_COMPARE:
-               rc = lback->bi_op_compare( op, rs );
-               break;
-       case LDAP_REQ_SEARCH:
-               if ( rs->sr_type == REP_SEARCHREF ) {
-                       struct berval   *curr = ref,
-                                       odn = op->o_req_dn,
-                                       ondn = op->o_req_ndn;
-                       slap_callback   sc2 = { 0 };
-                       int             tmprc = 0;
-                       ber_len_t       refcnt = 0;
-                       BerVarray       newref = NULL;
-
-                       sc2.sc_response = ldap_chain_cb_response;
-                       op->o_callback = &sc2;
-
-                       rs->sr_type = REP_SEARCH;
-
-                       /* copy the private info because we need to modify it */
-                       for ( ; !BER_BVISNULL( &curr[0] ); curr++ ) {
-                               LDAPURLDesc     *srv;
-                               char            *save_dn;
-
-                               /* parse reference and use
-                                * proto://[host][:port]/ only */
-                               tmprc = ldap_url_parse_ext( curr[0].bv_val, &srv );
-                               if ( tmprc != LDAP_URL_SUCCESS ) {
-                                       /* error */
-                                       rc = 1;
-                                       goto end_of_searchref;
-                               }
-
-                               /* remove DN essentially because later on 
-                                * ldap_initialize() will parse the URL 
-                                * as a comma-separated URL list */
-                               save_dn = srv->lud_dn;
-                               srv->lud_dn = "";
-                               srv->lud_scope = LDAP_SCOPE_DEFAULT;
-                               li.url = ldap_url_desc2str( srv );
-                               if ( li.url != NULL ) {
-                                       ber_str2bv_x( save_dn, 0, 1, &op->o_req_dn,
-                                                       op->o_tmpmemctx );
-                                       ber_dupbv_x( &op->o_req_ndn, &op->o_req_dn,
-                                                       op->o_tmpmemctx );
-                               }
-
-                               srv->lud_dn = save_dn;
-                               ldap_free_urldesc( srv );
-
-                               if ( li.url == NULL ) {
-                                       /* error */
-                                       rc = 1;
-                                       goto end_of_searchref;
-                               }
-
-
-                               /* FIXME: should we also copy filter and scope?
-                                * according to RFC3296, no */
-                               tmprc = lback->bi_op_search( op, rs );
-
-                               ldap_memfree( li.url );
-                               li.url = NULL;
-
-                               op->o_tmpfree( op->o_req_dn.bv_val,
-                                               op->o_tmpmemctx );
-                               op->o_tmpfree( op->o_req_ndn.bv_val,
-                                               op->o_tmpmemctx );
-
-                               if ( tmprc ) {
-                                       /* error */
-                                       rc = 1;
-                                       goto end_of_searchref;
-                               }
-
-                               if ( rs->sr_err != LDAP_SUCCESS ) {
-                                       /* if search was not successful,
-                                        * at least return the referral! */
-                                       /* FIXME: assumes referrals 
-                                        * are always created via
-                                        * referral_rewrite() and freed via
-                                        * ber_bvarray_free( rs->sr_ref ) */
-                                       newref = ch_realloc( newref, sizeof( struct berval ) * (refcnt + 2) );
-                                       ber_dupbv( &newref[ refcnt ], &curr[ 0 ] );
-                                       refcnt++;
-                                       BER_BVZERO( &newref[ refcnt ] );
-                               }
-                       }
-
-end_of_searchref:;
-                       op->o_req_dn = odn;
-                       op->o_req_ndn = ondn;
-                       rs->sr_type = REP_SEARCHREF;
-                       rs->sr_entry = NULL;
-
-                       /* if the error was bad, it was already returned
-                        * by back-ldap; destroy the referrals left;
-                        * otherwise, let the frontend return them. */
-                       if ( newref ) {
-                               if ( rc == 0 ) {
-                                       rc = SLAP_CB_CONTINUE;
-                                       if ( ref != default_referral ) {
-                                               ber_bvarray_free( ref );
-                                       }
-                                       ref = newref;
-
-                               } else {
-                                       ber_bvarray_free( newref );
-                               }
-                       }
-                       
-               } else {
-                       rc = lback->bi_op_search( op, rs );
-               }
-               break;
-       case LDAP_REQ_EXTENDED:
-               rc = lback->bi_extended( op, rs );
-               break;
-       default:
-               rc = SLAP_CB_CONTINUE;
-               break;
-       }
-       op->o_do_not_cache = cache;
-       op->o_ctrls = prev;
-       op->o_bd->be_private = private;
-       op->o_callback = sc;
-       op->o_ndn = ndn;
-       if ( ctrls ) {
-               op->o_tmpfree( ctrls, op->o_tmpmemctx );
-       }
-       if ( authzid ) {
-               op->o_tmpfree( authzid, op->o_tmpmemctx );
-       }
-       rs->sr_ref = ref;
-       if ( lip->url == NULL && li.url != NULL ) {
-               ldap_memfree( li.url );
-       }
-
-       return rc;
-}
-
-static int
-ldap_chain_config(
-       BackendDB       *be,
-       const char      *fname,
-       int             lineno,
-       int             argc,
-       char    **argv
-)
-{
-       slap_overinst   *on = (slap_overinst *) be->bd_info;
-       void            *private = be->be_private;
-       char            *argv0 = NULL;
-       int             rc;
-
-       be->be_private = on->on_bi.bi_private;
-       if ( strncasecmp( argv[ 0 ], "chain-", sizeof( "chain-" ) - 1 ) == 0 ) {
-               argv0 = argv[ 0 ];
-               argv[ 0 ] = &argv[ 0 ][ sizeof( "chain-" ) - 1 ];
-       }
-       rc = lback->bi_db_config( be, fname, lineno, argc, argv );
-       if ( argv0 ) {
-               argv[ 0 ] = argv0;
-       }
-       
-       be->be_private = private;
-       return rc;
-}
-
-static int
-ldap_chain_init(
-       BackendDB *be
-)
-{
-       slap_overinst *on = (slap_overinst *) be->bd_info;
-       void *private = be->be_private;
-       int rc;
-
-       be->be_private = NULL;
-       rc = lback->bi_db_init( be );
-       on->on_bi.bi_private = be->be_private;
-       be->be_private = private;
-
-       return rc;
-}
-
-static int
-ldap_chain_destroy(
-       BackendDB *be
-)
-{
-       slap_overinst *on = (slap_overinst *) be->bd_info;
-       void *private = be->be_private;
-       int rc;
-
-       be->be_private = on->on_bi.bi_private;
-       rc = lback->bi_db_destroy( be );
-       on->on_bi.bi_private = be->be_private;
-       be->be_private = private;
-       return rc;
-}
-
-static slap_overinst ldapchain;
-
-int
-chain_init()
-{
-       lback = backend_info( "ldap" );
-
-       if ( !lback ) {
-               return -1;
-       }
-
-       ldapchain.on_bi.bi_type = "chain";
-       ldapchain.on_bi.bi_db_init = ldap_chain_init;
-       ldapchain.on_bi.bi_db_config = ldap_chain_config;
-       ldapchain.on_bi.bi_db_destroy = ldap_chain_destroy;
-       
-       /* ... otherwise the underlying backend's function would be called,
-        * likely passing an invalid entry; on the contrary, the requested
-        * operational attributes should have been returned while chasing
-        * the referrals.  This all in all is a bit messy, because part
-        * of the operational attributes are generated by they backend;
-        * part by the frontend; back-ldap should receive all the available
-        * ones from the remote server, but then, on it own, it strips those
-        * it assumes will be (re)generated by the frontend (e.g.
-        * subschemaSubentry.) */
-       ldapchain.on_bi.bi_operational = ldap_chain_operational;
-       
-       ldapchain.on_response = ldap_chain_response;
-
-
-       ldapchain.on_bi.bi_chk_referrals = ldap_chain_chk_referrals;
-
-       return overlay_register( &ldapchain );
-}
-
-#if SLAPD_OVER_CHAIN == SLAPD_MOD_DYNAMIC
-int init_module(int argc, char *argv[]) {
-       return chain_init();
-}
-#endif /* SLAPD_OVER_CHAIN == SLAPD_MOD_DYNAMIC */
-
-#endif /* SLAPD_OVER_CHAIN */
-
-#endif /* ! defined(SLAPD_LDAP) */
index 632bff232b5ab04fcc9951749a1f43fa4a0e890c..3e73167b208b315af15cafa3c1b8e23e3caa6959 100644 (file)
@@ -23,9 +23,6 @@
 
 #include "slap.h"
 
-#if SLAPD_OVER_CHAIN == SLAPD_MOD_STATIC
-extern int chain_init();
-#endif
 #if SLAPD_OVER_DENYOP == SLAPD_MOD_STATIC
 extern int denyop_init();
 #endif
@@ -61,9 +58,6 @@ static struct {
        char *name;
        int (*func)();
 } funcs[] = {
-#if SLAPD_OVER_CHAIN == SLAPD_MOD_STATIC
-       { "LDAP Chain Response", chain_init },
-#endif
 #if SLAPD_OVER_DENYOP == SLAPD_MOD_STATIC
        { "Deny Operation", denyop_init },
 #endif