From c5a9ffa62ea4036361d992d3cc3c5ec78110bce4 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 19 May 2001 17:02:39 +0000 Subject: [PATCH] pseudo-root dn bind; a couple of minor fixes --- servers/slapd/back-meta/Documentation | 15 +++++- servers/slapd/back-meta/back-meta.h | 8 ++- servers/slapd/back-meta/bind.c | 49 +++++++++++++++---- servers/slapd/back-meta/compare.c | 3 +- servers/slapd/back-meta/config.c | 36 ++++++++++++++ servers/slapd/back-meta/conn.c | 27 +++++++++- .../back-meta/data/slapd-meta-rewrite.conf | 6 +++ 7 files changed, 130 insertions(+), 14 deletions(-) diff --git a/servers/slapd/back-meta/Documentation b/servers/slapd/back-meta/Documentation index b3d1f65165..c03927dc69 100644 --- a/servers/slapd/back-meta/Documentation +++ b/servers/slapd/back-meta/Documentation @@ -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 + 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> diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 4d3689f0eb..212425e546 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -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, diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index e3fdad5027..6d2188359e 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -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; diff --git a/servers/slapd/back-meta/compare.c b/servers/slapd/back-meta/compare.c index 9b0e9a43f7..8a5a31cb43 100644 --- a/servers/slapd/back-meta/compare.c +++ b/servers/slapd/back-meta/compare.c @@ -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, diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index c6783247a8..b19134db7b 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -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 ) { diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index bc0e572531..e703f57698 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -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 ... */ diff --git a/servers/slapd/back-meta/data/slapd-meta-rewrite.conf b/servers/slapd/back-meta/data/slapd-meta-rewrite.conf index fef9fb91a8..2134ef0dde 100644 --- a/servers/slapd/back-meta/data/slapd-meta-rewrite.conf +++ b/servers/slapd/back-meta/data/slapd-meta-rewrite.conf @@ -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" -- 2.39.5