Documentation   [plain text]


Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
COPYING RESTRICTIONS APPLY, see COPYRIGHT file

Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>



   Metadirectory backend.

This is a brief introduction to the core functionalities of back-meta.



 - Introduction.

Back-meta implements a backend for OpenLDAP's slapd.  It performs basic
LDAP proxying with respect to a set of remote LDAP servers, called
"targets".  The information contained in these servers can be presented
as belonging to a single Directory Information Tree (DIT).

A basic knowledge of the functionality of back-ldap is recommended.
This backend has been designed as an enhancement of back-ldap.
The two backends share many features (actually they also share portions
of code).  While back-ldap is intended to proxy operations directed
to a single server, back-meta is mainly intended for proxying
of multiple servers and possibly naming context masquerading.
These features, although useful in many scenarios, may result in
excessive overhead for some applications, so its use should be
carefully considered.

In the examples section, some typical scenarios will be discussed.



 - Common configuration directives

The backend uses most of the common configuration directives.  Its
configuration block starts with the "database" directive:

	database	meta

At least a "suffix" directive is required.

Note: as with back-ldap, operational attributes related to entry
creation/modification should not be used, as they would be passed
to the target servers, generating an error.  Moreover, it makes
little sense to use such attributes in proxying, as the proxy
server doesn't actually store data, so it should have no knowledge
of such attributes.  While code to strip the modification attributes
has been put in place (and #ifdef'd), it implies unmotivated overhead.
So it is strongly recommended to set

	lastmod		off

for every back-ldap/back-meta backend.



 - Special configuration directives

Target configuration starts with the "uri" directive.  All the 
configuration directives that are not specific to targets should
be defined first for clarity, including those that are common to
all backends.  They are:

	default-target	none

This directive forces the backend to reject all those operations
that must resolve to a single target in case none or multiple
targets are selected.  They include: add, delete, modify, modrdn;
compare is not included, as well as bind since, as they don't
alter entries, in case of multiple matches an attempt is made
to perform the operation on any candidate target, with the
constraint that at most on must succeed.  This directive can also
be used when processing targets to mark a specific target as default.

	dncache-ttl	{forever|disabled|<ttl>}

This directive sets the time-to-live of the dn cache.  This caches
the target that holds a given dn to speed up target selection
in case multiple targets would result from an uncached search;
forever means cache never expires; disabled means no dn caching;
otherwise a valid ( > 0 ) ttl in seconds is required.



 - Target specification

Target specification starts with a "uri" directive:

	uri		<protocol>://[<host>[:<port>]]/<naming context>

The "server" directive that was allowed in back-ldap (although deprecated)
has been discarded in back-meta.  The <protocol> part can be anything
ldap_initialize(3) accepts ({ldap|ldaps|ldapi} and variants); <host>
and <port> may be omitted, defaulting to whatever is set in
/etc/ldap.conf (correct me!?!).
The <naming context> part is mandatory.  It must end with one of the
naming contexts defined for the backend, e.g.:

		suffix		"dc=foo,dc=com"
		uri		"ldap://x.foo.com/dc=x,dc=foo,dc=com"

The <naming context> part doesn't need to be unique across the targets;
it may also match one of the values of the "suffix" directive.

	default-target	[<target>]

the "default-target" directive can also be used during target 
specification.  With no arguments it marks the current target as
the default.  The optional number marks target <target> as the
default one, starting from 1.  Target <target> must be defined.

	binddn		<administrative dn for ac purposes>

This directive, as in back-ldap, allows to define the dn that is
used to query the target server for acl checking; it should have
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		<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>

All the directives starting with "rewrite" refer to the rewrite engine
that has been added to slapd.  The "suffixmassage" directive was
introduced in back-ldap to allow suffix massaging while proxying.
It has been obsoleted by the rewriting tools.  However, both for
backward compatibility and for ease of configuration when simple
suffix massage is required, it has been preserved.  It wraps the
basic rewriting instructions that perform suffix massaging.

Note: this also fixes a flaw in suffix massaging, which operated
on (case insensitive) DNs instead of normalized DNs,
so "dc=foo, dc=com" would not match "dc=foo,dc=com".

See the "rewrite" section.

	map		{objectClass|attribute} {<source>|*} [<dest>|*]

objectClass/attribute mapping stuff.  This has been inherited from
the work made by Mark Valence on the back-ldap backend.
See the mapping section.



 - Scenarios

A powerful (and in some sense dangerous) rewrite engine has been added
to both back-ldap and back-meta.  While the former can gain limited
beneficial effects from rewriting stuff, the latter can become
an amazingly powerful tool.

Consider a couple of scenarios first.

1) Two directory servers share two levels of naming context;
say "dc=a,dc=foo,dc=com" and "dc=b,dc=foo,dc=com".  Then, an
unambiguous back-meta can be configured as:

	database	meta
	suffix		"dc=foo,dc=com"

	uri		"ldap://a.foo.com/dc=a,dc=foo,dc=com"

	uri		"ldap://b.foo.com/dc=b,dc=foo,dc=com"

Operations directed to a specific target can be easily resolved
because there are no ambiguities.  The only operation that may
resolve to multiple targets is a search with base "dc=foo,dc=com" 
and scope at least "one", which results in spawning two searches
to the targets.

2a) Two directory servers don't share any portion of naming context,
but they'd present as a single DIT.  [Caveat: uniqueness of
(massaged) entries among the two servers is assumed; integrity 
checks risk to incurr in excessive overhead and have not been implemented.]
Say we have "dc=bar,dc=org" and "o=Foo,c=US", and we'd like them to
appear as branches of "dc=foo,dc=com", say "dc=a,dc=foo,dc=com"
and "dc=b,dc=foo,dc=com".  Then we need to configure our back-meta as:

	database	meta
	suffix		"dc=foo,dc=com"

	uri		"ldap://a.bar.com/dc=a,dc=foo,dc=com"
	suffixmassage	"dc=a,dc=foo,dc=com" "dc=bar,dc=org"
	
	uri		"ldap://b.foo.com/dc=b,dc=foo,dc=com"
	suffixmassage	"dc=b,dc=foo,dc=com" "o=Foo,c=US"

Again, operations can be resolved without ambiguity, although
some rewriting is required.  Notice that the virtual naming context
of each target is a branch of the database's naming context; it
is rewritten back and forth when operations are performed towards
the target servers.  What "back and forth" means will be clarified
later.

When a search with base "dc=foo,dc=com" is attempted, if the 
scope is "base" it fails with "no such object"; in fact, the
common root of the two targets (prior to massaging) does not
exist.  If the scope is "one", both targets are contacted with
the base replaced by each target's base; the scope is derated
to "base".  In general, a scope "one" search is honored,
and the scope is derated, only when the incoming base is
at most one level lower of a target's naming context (prior
to massaging).
Finally, if the scope is "sub" the incoming base is replaced
by each target's unmassaged naming context, and the scope
is not altered.

2b) Consider the above reported scenario with the two servers
sharing the same naming context:

	database	meta
	suffix		"dc=foo,dc=com"

	uri		"ldap://a.bar.com/dc=foo,dc=com"
	suffixmassage	"dc=foo,dc=com" "dc=bar,dc=org"
	
	uri		"ldap://b.foo.com/dc=foo,dc=com"
	suffixmassage	"dc=foo,dc=com" "o=Foo,c=US"
	
All the previous considerations hold, except that now there is
no way to unambiguously resolve a dn.  In this case, all the
operations that require an unambiguous target selection will
fail unless the dn is already cached or a default target has
been set.



 - Rewriting

This part of the document is being prepared.  At present you may consult
the RATIONALE in libraries/librewrite.



 - Objectclass/attribute mapping

This part of the document is being prepared.  At present you may stick with 

http://www.openldap.org/lists/openldap-devel/200102/msg00006.html



 - ACL
Note on ACLs: at present you may add whatever ACL rule you desire
to back-meta (as well as to back-ldap).  However, the meaning of an ACL
on a proxy may require some considerations.  Two philosophies may be
considered:

a) the remote server dictates the permissions; the proxy simply passes
back what it gets from the remote server.

b) the remote server unveils "everything"; the proxy is responsible
for protecting data from unauthorized access.

Of course the latter sounds unreasonable, but it is not.  It is possible
to imagine scenarios in which a remote host discloses data that can
be considered "public" inside an intranet, and a proxy that connects it
to the internet may impose additional constraints.  To this purpose, the
proxy should be able to comply with all the ACL matching criteria that
the server supports.  This has been achieved with regard to all the
criteria supported by slapd except a special subtle case (please drop
me a note if you can find other exceptions: <ando@openldap.org>).
The rule

access to dn="<dn>" attr=<attr>
	by dnattr=<dnattr> read
	by * none

cannot be matched IFF:
- the attribute that is being requested, <attr>, is NOT <dnattr>, and
- the attribute that determines membership, <dnattr>, has not
  been requested (e.g. in a search)

In fact this ACL is resolved by slapd using the portion of entry it retrieved
from the remote server without requiring any further intervention of the
backend, so, if the <dnattr> attribute has not been fetched, the match
cannot be assessed because the attribute is not present, not because
no value matches the requirement!


Note on ACLS and attribute mapping: ACLs are applied to the mapped
attributes; for instance, if the attribute locally known as "foo" 
is mapped to "bar" on a remote server, then local ACLs apply to 
attribute "foo" and are totally unaware of its remote name.  The 
remote server will check permissions for "bar", and the local server 
will possibly enforce additional restrictions to "foo".