]> git.sur5r.net Git - openldap/commitdiff
pseudo-root dn bind; a couple of minor fixes
authorPierangelo Masarati <ando@openldap.org>
Sat, 19 May 2001 17:02:39 +0000 (17:02 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 19 May 2001 17:02:39 +0000 (17:02 +0000)
servers/slapd/back-meta/Documentation
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/compare.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/data/slapd-meta-rewrite.conf

index b3d1f651657c93cd37655cf28876435c504e2df7..c03927dc69806285c1c9da55ac8c8222187095b6 100644 (file)
@@ -119,11 +119,24 @@ read access on the target server to attributes used on the proxy
 for acl checking.  There is no risk of giving away such values;
 they are only used to check permissions.
 
-       bindpw          <plaintext password for ac purposes>
+       bindpw          <password for ac purposes>
 
 This directive sets the password for acl checking in conjunction
 with the above mentioned "binddn" directive.
 
+       pseudorootdn    <substitute dn in case of rootdn bind>
+
+This directive, if present, sets the dn that will be substituted
+to the bind dn if a bind with the backend's "rootdn" succeeds.  The true
+"rootdn" of the target server ought not be used; an arbitrary administrative
+dn should used instead.
+
+       pseudorootpw    <substitute password in case of rootdn bind>
+
+This directive sets the credential that will be used in case a bind
+with the backend's "rootdn" succeeds, and the bind is propagated to
+the target using the "pseudorootdn" dn.
+
        rewrite*        ...
 
        suffixmassage   <virtual naming context> <real naming context>
index 4d3689f0ebae491ed37d1e58a4b91999683b63a0..212425e546628282b58b37ce19b8bcf96da03766 100644 (file)
@@ -105,6 +105,8 @@ struct metaconn {
         * of course only one target actually is ...
         */
        int             bound_target;
+#define META_BOUND_NONE                -1
+#define META_BOUND_ALL         -2
        /* supersedes the connection stuff */
        struct metasingleconn **conns;
 };
@@ -115,6 +117,9 @@ struct metatarget {
        char                    *binddn;
        char                    *bindpw;
 
+       char                    *pseudorootdn;
+       char                    *pseudorootpw;
+
        struct rewrite_info     *rwinfo;
 
        struct ldapmap          oc_map;
@@ -148,7 +153,7 @@ meta_back_do_single_bind(
                struct metaconn         *lc,
                const char              *dn,
                const char              *ndn,
-               struct berval           *cred,
+               const char              *cred,
                int                     method,
                int                     candidate
 );
@@ -156,6 +161,7 @@ meta_back_do_single_bind(
 
 #define META_OP_ALLOW_MULTIPLE         0x00
 #define META_OP_REQUIRE_SINGLE         0x01
+#define META_OP_REQUIRE_ALL            0x02
 extern struct metaconn *
 meta_back_getconn(
                struct                  metainfo *li,
index e3fdad50278fbef4496cb35169469ff313eab7bc..6d2188359e344581cf0396d329e54a4e0bce0d41 100644 (file)
@@ -92,7 +92,14 @@ meta_back_bind(
        struct metainfo *li = ( struct metainfo * )be->be_private;
        struct metaconn *lc;
 
-       int rc = -1, i, gotit = 0, ndnlen, err = LDAP_SUCCESS;
+       int rc = -1, i, gotit = 0, ndnlen, isroot = 0;
+       int op_type = META_OP_ALLOW_MULTIPLE;
+       int err = LDAP_SUCCESS;
+
+       char *realdn = (char *)dn;
+       char *realndn = (char *)ndn;
+       char *realcred = cred->bv_val;
+       int realmethod = method;
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
@@ -103,8 +110,13 @@ meta_back_bind(
 
        *edn = NULL;
 
-       lc = meta_back_getconn( li, conn, op, META_OP_ALLOW_MULTIPLE,
-                       ndn, NULL );
+       if ( method == LDAP_AUTH_SIMPLE 
+                       && be_isroot_pw( be, conn, ndn, cred ) ) {
+               isroot = 1;
+               *edn = ch_strdup( be_root_dn( be ) );
+               op_type = META_OP_REQUIRE_ALL;
+       }
+       lc = meta_back_getconn( li, conn, op, op_type, ndn, NULL );
        if ( !lc ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_NOTICE,
@@ -121,7 +133,7 @@ meta_back_bind(
        /*
         * Each target is scanned ...
         */
-       lc->bound_target = -1;
+       lc->bound_target = META_BOUND_NONE;
        ndnlen = strlen( ndn );
        for ( i = 0; i < li->ntargets; i++ ) {
                int lerr;
@@ -154,9 +166,15 @@ meta_back_bind(
 #endif /* !NEW_LOGGING */
                }
 
-
-               lerr = meta_back_do_single_bind( li, lc, dn, ndn, cred,
-                               method, i );
+               if ( isroot && li->targets[ i ]->pseudorootdn != NULL ) {
+                       realdn = li->targets[ i ]->pseudorootdn;
+                       realndn = li->targets[ i ]->pseudorootdn;
+                       realcred = li->targets[ i ]->pseudorootpw;
+                       realmethod = LDAP_AUTH_SIMPLE;
+               }
+               
+               lerr = meta_back_do_single_bind( li, lc,
+                               realdn, realndn, realcred, realmethod, i );
                if ( lerr != LDAP_SUCCESS ) {
                        err = lerr;
                        ( void )meta_clear_one_candidate( lc->conns[ i ], 1 );
@@ -165,6 +183,10 @@ meta_back_bind(
                }
        }
 
+       if ( isroot ) {
+               lc->bound_target = META_BOUND_ALL;
+       }
+
        /*
         * rc is LDAP_SUCCESS if at least one bind succeeded,
         * err is the last error that occurred during a bind;
@@ -177,6 +199,7 @@ meta_back_bind(
                 */
                err = ldap_back_map_result( err );
                send_ldap_result( conn, op, err, NULL, "", NULL, NULL );
+               return -1;
        }
 
        return 0;
@@ -193,7 +216,7 @@ meta_back_do_single_bind(
                struct metaconn         *lc,
                const char              *dn,
                const char              *ndn,
-               struct berval           *cred,
+               const char              *cred,
                int                     method,
                int                     candidate
 )
@@ -227,8 +250,7 @@ meta_back_do_single_bind(
                return LDAP_OPERATIONS_ERROR;
        }
 
-       rc = ldap_bind_s( lc->conns[ candidate ]->ld, mdn,
-                       cred->bv_val, method );
+       rc = ldap_bind_s( lc->conns[ candidate ]->ld, mdn, cred, method );
        if ( rc != LDAP_SUCCESS ) {
                rc = ldap_back_map_result( rc );
        } else {
@@ -259,6 +281,13 @@ meta_back_dobind( struct metaconn *lc, Operation *op )
        struct metasingleconn **lsc;
        int bound = 0, i;
 
+       /*
+        * all the targets are bound as pseudoroot
+        */
+       if ( lc->bound_target == META_BOUND_ALL ) {
+               return 1;
+       }
+
        for ( i = 0, lsc = lc->conns; lsc[ 0 ] != NULL; ++i, ++lsc ) {
                int rc;
 
index 9b0e9a43f70fcd26aeeb27005c6e7f4e176fdb73..8a5a31cb43e5f538dde7f8d8b3ad6e930ae74d47 100644 (file)
@@ -89,7 +89,8 @@ meta_back_compare(
        struct metaconn *lc;
        struct metasingleconn **lsc;
        char *match = NULL, *err = NULL, *mmatch = NULL;
-       int candidates = 0, last = 0, i, count, rc, cres, rres;
+       int candidates = 0, last = 0, i, count, rc;
+               int cres = LDAP_SUCCESS, rres = LDAP_SUCCESS;
        int *msgid;
 
        lc = meta_back_getconn( li, conn, op, META_OP_ALLOW_MULTIPLE,
index c6783247a8b6b9fbd43369f7ccd09323917f552a..b19134db7b26f0bdc2b68743d6867b81fa6f94fd 100644 (file)
@@ -349,6 +349,42 @@ meta_back_db_config(
                        return 1;
                }
                li->targets[ i ]->bindpw = ch_strdup( argv[ 1 ] );
+               
+       /* name to use as pseudo-root dn */
+       } else if ( strcasecmp( argv[ 0 ], "pseudorootdn" ) == 0 ) {
+               int i = li->ntargets-1;
+
+               if ( i < 0 ) {
+                       fprintf( stderr,
+       "%s: line %d: need \"uri\" directive first\n",
+                               fname, lineno );
+               }
+               
+               if ( argc != 2 ) {
+                       fprintf( stderr,
+       "%s: line %d: missing name in \"pseudorootdn <name>\" line\n",
+                               fname, lineno );
+                       return 1;
+               }
+               li->targets[ i ]->pseudorootdn = ch_strdup( argv[ 1 ] );
+
+       /* password to use as pseudo-root */
+       } else if ( strcasecmp( argv[ 0 ], "pseudorootpw" ) == 0 ) {
+               int i = li->ntargets-1;
+
+               if ( i < 0 ) {
+                       fprintf( stderr,
+       "%s: line %d: need \"uri\" directive first\n",
+                               fname, lineno );
+               }
+               
+               if ( argc != 2 ) {
+                       fprintf( stderr,
+       "%s: line %d: missing password in \"pseudorootpw <password>\" line\n",
+                           fname, lineno );
+                       return 1;
+               }
+               li->targets[ i ]->pseudorootpw = ch_strdup( argv[ 1 ] );
        
        /* dn massaging */
        } else if ( strcasecmp( argv[ 0 ], "suffixmassage" ) == 0 ) {
index bc0e572531e0fc0f003470a919a11436d65434d4..e703f57698bd50b013a46064346116acfba6eab5 100644 (file)
@@ -199,7 +199,7 @@ metaconn_alloc( int ntargets )
                }
        }
 
-       lc->bound_target = -1;
+       lc->bound_target = META_BOUND_NONE;
 
        return lc;
 }
@@ -438,6 +438,31 @@ meta_back_getconn(
                        *candidate = i;
                }
 
+       /*
+        * require all connections ...
+        */
+       } else if (op_type == META_OP_REQUIRE_ALL) {
+               for ( i = 0; i < li->ntargets; i++ ) {
+
+                       /*
+                        * The target is activated; if needed, it is
+                        * also init'd
+                        */
+                       int lerr = init_one_conn( conn, op, li->targets[ i ],
+                                       vers, lc->conns[ i ] );
+                       if ( lerr != LDAP_SUCCESS ) {
+                               
+                               /*
+                                * FIXME: in case one target cannot
+                                * be init'd, should the other ones
+                                * be tried?
+                                */
+                               ( void )meta_clear_one_candidate( lc->conns[ i ], 1 );
+                               err = lerr;
+                               continue;
+                       }
+               }
+
        /*
         * if no unique candidate ...
         */
index fef9fb91a84e43ddfdb8a698cb958938f4038385..2134ef0ddee9a7c48fccf016c6d395efd20bdd1b 100644 (file)
@@ -50,8 +50,12 @@ database     meta
 suffix         "o=Foo Bar, c=US"
 dncache-ttl    forever
 lastmod                off
+rootdn         "cn=root,o=Foo Bar,c=US"
+rootpw         foo
 
 uri            "ldap://localhost:@PORT@/ou=People, dc=foo, o=Foo Bar, c=US"
+pseudorootdn   "cn=Root, ou=People, dc=foo, dc=example, dc=com"
+pseudorootpw   ldap
 rewriteEngine  on
 rewriteContext default
 rewriteRule    "(.*)o=Foo Bar,[ ]?c=US" "%1dc=example, dc=com"
@@ -61,6 +65,8 @@ rewriteContext        searchFilter
 rewriteRule    "(.*)member=([^)]+),o=Foo Bar,[ ]?c=US(.*)" "%1member=%2,dc=example,dc=com%3"
 
 uri            "ldap://localhost:@PORT@/ou=People, dc=bar, o=Foo Bar, c=US"
+pseudorootdn   "cn=Root, ou=People, dc=bar, dc=example, dc=com"
+pseudorootpw   ldap
 rewriteEngine  on
 rewriteContext default
 rewriteRule    "(.*)o=Foo Bar,[ ]?c=US" "%1dc=example, dc=com"