]> git.sur5r.net Git - openldap/commitdiff
More overlay tweaks. Added LDAP chaining overlay.
authorHoward Chu <hyc@openldap.org>
Wed, 11 Jun 2003 04:36:35 +0000 (04:36 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 11 Jun 2003 04:36:35 +0000 (04:36 +0000)
servers/slapd/back-ldap/Makefile.in
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/chain.c [new file with mode: 0644]
servers/slapd/back-ldap/init.c
servers/slapd/backover.c
servers/slapd/slap.h

index bbeba6b0c7e25c0f49bf9086171b460adb6c1985..554bdf69cf70b59b8d8816aee846a1624e4de93f 100644 (file)
@@ -4,10 +4,10 @@
 
 SRCS   = init.c config.c search.c bind.c unbind.c add.c compare.c \
                delete.c modify.c modrdn.c \
-               suffixmassage.c map.c extended.c
+               suffixmassage.c map.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 \
-               suffixmassage.lo map.lo extended.lo
+               suffixmassage.lo map.lo extended.lo chain.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries
index dc67f7e1586c0a964f097e8cf992bec23afd4723..97cc6eff86d5e8f27a02c88bad80fb10130d3cdf 100644 (file)
@@ -194,6 +194,8 @@ extern int suffix_massage_config( struct rewrite_info *info,
 extern int ldap_dnattr_rewrite( dncookie *dc, BerVarray a_vals );
 extern int ldap_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals );
 
+extern int ldap_chain_setup();
+
 LDAP_END_DECL
 
 #endif /* SLAPD_LDAP_H */
diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c
new file mode 100644 (file)
index 0000000..214a250
--- /dev/null
@@ -0,0 +1,166 @@
+/* chain.c - chain LDAP operations */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * Copyright 2003, Howard Chu, All rights reserved. <hyc@highlandsun.com>
+ * 
+ * Permission is granted to anyone to use this software for any purpose
+ * on any computer system, and to alter it and redistribute it, subject
+ * to the following restrictions:
+ * 
+ * 1. The author is not responsible for the consequences of use of this
+ *    software, no matter how awful, even if they arise from flaws in it.
+ * 
+ * 2. The origin of this software must not be misrepresented, either by
+ *    explicit claim or by omission.  Since few users ever read sources,
+ *    credits should appear in the documentation.
+ * 
+ * 3. Altered versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.  Since few users
+ *    ever read sources, credits should appear in the documentation.
+ * 
+ * 4. This notice may not be removed or altered.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-ldap.h"
+
+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;
+       LDAPControl **prev = op->o_ctrls;
+       LDAPControl **ctrls, authz;
+       int i, nctrls, rc;
+       int cache = op->o_do_not_cache;
+
+       if ( rs->sr_err != LDAP_REFERRAL )
+               return SLAP_CB_CONTINUE;
+
+       op->o_bd->be_private = on->on_bi.bi_private;
+       for (i=0; prev && prev[i]; i++);
+       nctrls = 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;
+
+       /* Chaining is performed by a privileged user on behalf
+        * of a normal user
+        */
+       op->o_do_not_cache = 1;
+       op->o_ctrls = ctrls;
+
+       switch( op->o_tag ) {
+       case LDAP_REQ_BIND:
+               rc = ldap_back_bind( op, rs );
+               break;
+       case LDAP_REQ_ADD:
+               rc = ldap_back_add( op, rs );
+               break;
+       case LDAP_REQ_DELETE:
+               rc = ldap_back_delete( op, rs );
+               break;
+       case LDAP_REQ_MODRDN:
+               rc = ldap_back_modrdn( op, rs );
+               break;
+       case LDAP_REQ_MODIFY:
+               rc = ldap_back_modify( op, rs );
+               break;
+       case LDAP_REQ_COMPARE:
+               rc = ldap_back_compare( op, rs );
+               break;
+       case LDAP_REQ_SEARCH:
+               rc = ldap_back_search( op, rs );
+               break;
+       case LDAP_REQ_EXTENDED:
+               rc = ldap_back_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_tmpfree( ctrls, op->o_tmpmemctx );
+
+       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;
+       int rc;
+
+       be->be_private = on->on_bi.bi_private;
+       rc = ldap_back_db_config( be, fname, lineno, argc, argv );
+       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 = ldap_back_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 = ldap_back_db_destroy( be );
+       on->on_bi.bi_private = be->be_private;
+       be->be_private = private;
+       return rc;
+}
+
+static slap_overinst ldapchain;
+
+int ldap_chain_setup()
+{
+       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;
+       ldapchain.on_response = ldap_chain_response;
+
+       return overlay_register( &ldapchain );
+}
index 5bf32766f276f1d0d5953880892204e8a86af27c..58585303ce7f418ff856f13115df022879c6b490 100644 (file)
@@ -96,6 +96,8 @@ ldap_back_initialize(
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = ldap_back_conn_destroy;
 
+       ldap_chain_setup();
+
        return 0;
 }
 
index 61f8acbe35ac4290cf711bc0178661285c1e2e0a..6b29007eb19cee2b2f9655d1bb01e476aa3969fd 100644 (file)
@@ -127,7 +127,7 @@ over_back_response ( Operation *op, SlapReply *rs )
 {
        slap_overinfo *oi = (slap_overinfo *) op->o_bd->bd_info;
        slap_overinst *on = oi->oi_list;
-       int rc = 0;
+       int rc = SLAP_CB_CONTINUE;
        BackendDB *be = op->o_bd, db = *op->o_bd;
        slap_callback *sc = op->o_callback->sc_private;
 
@@ -136,14 +136,15 @@ over_back_response ( Operation *op, SlapReply *rs )
                if ( on->on_response ) {
                        db.bd_info = (BackendInfo *)on;
                        rc = on->on_response( op, rs );
-                       if ( rc ) break;
+                       if ( ! (rc & SLAP_CB_CONTINUE) ) break;
                }
        }
        op->o_callback = sc;
-       if ( rc == 0 && sc ) {
+       if ( sc && (rc & SLAP_CB_CONTINUE) ) {
                rc = sc->sc_response( op, rs );
        }
        op->o_bd = be;
+       rc &= ~SLAP_CB_CONTINUE;
        return rc;
 }
 
@@ -282,6 +283,9 @@ overlay_config( BackendDB *be, const char *ov )
                return 1;
        }
 
+       /* If this is the first overlay on this backend, set up the
+        * overlay info structure
+        */
        if ( be->bd_info->bi_type != overtype ) {
                oi = ch_malloc( sizeof(slap_overinfo) );
                oi->oi_bd = *be;
@@ -311,6 +315,9 @@ overlay_config( BackendDB *be, const char *ov )
                be->bd_info = bi;
        }
 
+       /* Walk to the end of the list of overlays, add the new
+        * one onto the end
+        */
        oi = (slap_overinfo *) be->bd_info;
        for ( prev=NULL, on2 = oi->oi_list; on2; prev=on2, on2=on2->on_next );
        on2 = ch_malloc( sizeof(slap_overinst) );
@@ -321,6 +328,13 @@ overlay_config( BackendDB *be, const char *ov )
        }
        *on2 = *on;
 
+       /* Any initialization needed? */
+       if ( on->on_bi.bi_db_init ) {
+               be->bd_info = (BackendInfo *)on2;
+               on2->on_bi.bi_db_init( be );
+               be->bd_info = (BackendInfo *)oi;
+       }
+
        return 0;
 }
 
index e453346cf897477dc15a6a7f0be6d42324e1818e..47d245321029b01aff68deeb322d4aeee25af087 100644 (file)
@@ -1768,7 +1768,6 @@ struct slap_overinfo;
 typedef struct slap_overinst {
        BackendInfo on_bi;
        slap_response *on_response;
-       void *on_private;
        struct slap_overinfo *on_info;
        struct slap_overinst *on_next;
 } slap_overinst;
@@ -1779,6 +1778,9 @@ typedef struct slap_overinfo {
        slap_overinst *oi_list;
 } slap_overinfo;
 
+/* Should successive callbacks in a chain be processed? */
+#define        SLAP_CB_CONTINUE        0x8000
+
 /*
  * Paged Results state
  */