(Answer) (Category) OpenLDAP Faq-O-Matic : (Category) OpenLDAP Software FAQ : (Category) Configuration : (Category) SLAPD Configuration : (Category) Backends : (Answer) The LDAP backend (How do I setup/configure back-ldap?)
The ldap backend redirects requests to another server, thus acting as a LDAP proxy. It allows the common configuration directives as suffix, which is used to select it when a request is received by the server, ACLs, which are applied to search results, size and time limits, and so on.

The ldap database requires a few dedicated configuration lines. The initial syntax allowed a "server" directive for the host name the operations are redirected to:

        server <list of server[:port] entries>
This syntax is now superseded by the "uri" directive, which is honored also in the protocol part, e.g.:
    uri ldap://host[:port]/
    uri ldaps://host[:port]/
    uri ldapi:///
These entries cannot have multiple values; the last supplied silently overrides the previous ones; the
    server <hostname>
directive is automatically cast into ldap://<hostname>.

The server and the uri directives can contain a whitespace or comma separated list of values, that are passed to the underlying client library. The library tries to connect to each member of the list until one succeeds.

The directives binddn and bindpw are used by an internal operation related to ACLs, that checks if the dn related to an operation is member of a groupOfNames. As this attribute might be read-protected on the target server, a pair "bind dn/credentials" can be supplied to gain read privileges on the attribute. The syntax is:

    binddn "dn"
    bindpw "credentials"
At present a simple bind, with plain text credentials, is performed.

Note: since the name of the above directives led many users to believe they would be used by back-ldap as bind DN/cred to proxy anonymous requests, their name from 2.3 will change into acl-authcDN and acl-passwd which better describes the fact that they are only used internally by the proxy to perform searches related to the application of local ACLs.

A recent feature is the suffixmassage directive. It allows to rewrite the naming context of requests from a virtual naming context, i.e. the naming context recognized by the local server as related to the LDAP database, to a real naming context, i.e. the naming context that is accepted by the target server. Multiple lines are allowed, to allow the same database to handle requests for different naming contexts that must reside on the same target server. The suffixmassage directive is tightly related to the suffix directive. Search results have the real naming context rewritten back to the virtual naming context as well, so the client does is not directly aware of the real naming context of the server it is contacting. Its syntax is

    suffixmassage <virtual naming context> <real naming context>
which requires a suffix directive of the form
    suffix  <virtual naming context>

Note: the suffixmassage directive is currently (2.2) emulated in back-ldap by means of the rewrite feature. See slapd-meta(5) for details on how to write custom rewrite rules.

Note: in 2.3 the rewrite/remap features moved into the rwm overlay (see slapo-rwm(5) for details). Back-ldap does no longer recognize the rewrite/remap related statements. The migration should be very smooth: simply make sure the rwm overlay is built (configure --help for details); the add

    overlay rwm
and prefix all rewrite/map related statements with rwm-.

Note: with the 2.3 release, many deprecated config directives will be obsoleted and thus will no longer be available. Also, note that the syntax of some directives changed, although backwards compatibility will be preserved for a while. See the man page slapd-ldap(5) for an up-to-date description of the configuration syntax.

About "lastmod" config directive

This backend does not own the information it contains, so the "lastmod" config statement is meaningless; however, if it is on (or undefined, defaulting to the global "lastmod on"), an add/modify operation will result in the addition of the lastmod operational attributes (modifiersName, modifyTimeStamp, ...) to the desired adds/changes. When they're passed to the target directory server, an error may arise, preventing modifications through the ldap backend. To avoid this problem, it is recommended to always force "lastmod off" when using the ldap backend.

Note: by default, lastmod is off in back-ldap and back-meta; the above comment is correct, but no action is required any longer (at least since 2.2) to obtain the default behavior.

About virtual backends

The LDAP backend can be used to implement so-called virtual backends, i.e. databases that remap the naming context and the schema of an existing DSA. For this purpose, it can use OpenLDAP's rewrite engine, which requires --enable-rewrite at configure time, or simple string comparison rewriting, to massage the DN and the appropriate arguments of every operation. It also uses OpenLDAP's schema mapping engine to map the attributeTypes and the objectClass names.

Usually virtual backends are used when proxying a remote server; however, another use is that of presenting data in a DSA under a modified form; to this purpose, the uri directive is set to

    uri ldap:///
(of course one could use ldapi for more efficient and intrinsically secure communication), and the suffixmassage directive is set to
    suffixmassage "<virtual naming context> <real naming context>
Requests rooted at virtual naming context are directed to real naming context, and returned as if they were answered by virtual naming context.

More powerful rules can be written if using the rewrite engine (see slapd-meta(5) for further details). AttributeTypes and objectClasses are mapped by means of the map statement (see slapd-ldap(5) for further details). Note that if the virtual and the real backend are on the same machine, slapd(8) must be compiled with threads; in general, twice the threads required by a normal operatin will be actually used, so be careful when determining the appropriate value of threads; see slapd.conf(5) for details.

Note: with 2.3, virtual databases that are managed by the same DSA can be implemented more efficiently using the relay backend. See slapd-relay(5) for details.
ando@sys-net.it

Identity Assertion

Introduction

Starting from OpenLDAP 2.3, the LDAP backend supports the identity assertion feature, which means that, if instructed to do so, it will bind to the remote server it is proxying to with an administrative identity, and possibly assert some other identity, in all cases where operations are performed on behalf of a client that is correctly authenticated with respect to another backend.

The simplest scenario is that of a remote server which is proxied by a DSA. The proxy is being used by users whose identity is not present on the remote server, and thus cannot authenticate on it, nor their bind operation is even proxied; however, the remote server requires authentication to disclose data.

As soon as the local users can somehow authenticate, e.g. because their identity is stored locally, the proxy backend can be instructed to assert their identity, or even some derived identity, to the remote server on their behalf, by using an administrative identity that is stored on the remote server and is granted appropriate authorization privileges.

The scenario is summarized in this schematic proxy-side slapd.conf:

    # local naming context
    database bdb
    suffix   "dc=local,dc=example,dc=com"

    # remote server
    database ldap
    suffix   "dc=remote,dc=example,dc=com"
    uri      ldap://remote.naming.context/
In this baseline scenario, the local database is authorizing the client while performing operations that are proxied to the remote database.

Identity assertion configuration

The identity assertion feature uses the following configure statements, whose synopsis is detailed in slapd-ldap(5).
idassert-bind the parameters used to bind to the remote server and optionally authorize another identity;
idassert-authzFrom what local identities can access the identity assertion feature; see identity assertion access
    idassert-bind bindmethod=<method>
        [binddn=<simple DN>]
        [credentials=<simple password>]
        [saslmech=<SASL mech>]
        [secprops=<properties>]
        [realm=<realm>]
        [authcID=<authentication ID>]
        [authzID=<authorization ID>]
        [mode=<mode>]
        [authz=<how>]
        [flags=<flags>]

    idassert-authzFrom <authzRule>

Identity assertion modes

Different identity assertion modes are supported. They are selected by the
    mode={anonymous|none|self}
parameter to the idassert-bind statement, or optionally by the
    authzID=<Authorization ID>
parameter to the idassert-bind statement.
  • The simplest case is anonymous, i.e. the empty identity is asserted. This is useful when, on the one hand, the remote server requires that connections are bound, which is performed with the administrative identity, but, on the other hand, the desired information can then be obtained anonymously, and it is desirable that the client is not granted any significant privilege.
  • A slightly more sophisticated mode is none, i.e. no identity is asserted, and the administrative identity is maintained; of course, it is recommended that the administrative identity is granted limited privileges.
  • A variant of the above results by providing no mode parameter, and a specific identity, by means of either an u:<id> or a [dn:]<dn> value to the authzID parameter, where the dn: prefix is optional. This allows the administrative identity used for authentication to be granted higher privileges than those that will be granted to the client, while the authorized identity will act as a sort of a sandbox, i.e. another administrative identity with very limited privileges.
  • The last possibility is self, which essentially means that the identity of the client is asserted.
If no mode and no authzID is specified, the identity assertion mechanism is used internally for a slightly different purpose. This behavior is under development and should not be used unintendedly, so the identity assertion mode should always be explicitly set when enabling identity assertion.

Examples:
Authorize anonmymously

    idassert-bind mode=anonymous
Authorize using the client's identity
    idassert-bind mode=self
Authorize using a given identity
    idassert-bind authzID=u:proxy
    idassert-bind authzID=dn:cn=Proxy,dc=example,dc=com
    idassert-bind authzID=cn=Sandbox,dc=example,dc=com

Identity assertion access

The idassert-authzFrom mechanism controls whether a client's identity can be asserted or not. The idassert-authzFrom mechanism basically selects what identities can access the identity assertion feature, and indeed should be considered as the set of values of the authzFrom attribute associated to the administrative identity, with the essential difference that, if not present, by default every identity is authorized, including anonymous. Operations executed with identities that are not allowed to access the mechanism are rejected with a proxyAuthorizationFailure error.

Examples:
Authorize only specific identities:

    idassert-authzFrom "dn.exact:uid=jaj,ou=People,dc=example,dc=com"
    idassert-authzFrom "u:bjorn"
Authorize only identities below the "ou=People,dc=example,dc=com" branch:
    idassert-authzFrom "dn.children:ou=People,dc=example,dc=com"
Authorize only non-anonymous:
    idassert-authzFrom "dn:*"

Identity assertion methods

The parameter bindmethod for the idassert-bind statement is used to define what method is used by the proxy to bind to the remote server with the given administrative identity:
    bindmethod={none|simple|sasl}

SASL authc/authz

The administrative bind can be performed via SASL. The identity assertion can be performed by means of the native SASL authorization, if the SASL mechanism supports it. The backend must be explicitly instructed to perform native authorization, by means of the parameter
    idassert-bind bindmethod=sasl authz=native
The default is
    idassert-bind bindmethod=sasl authz=proxyAuthz
The only mechanism, to the author's knowledge, that supports native authorization is DIGEST-MD5. Note that native should only be used when authorizing as a specific identity, because back-ldap caches connections.

Proxy Authorization Control

In its essential implementation, the identity assertion mechanism uses the proxyAuthz control (see
draft-weltman-ldapv3-proxy for details), which is added to each operation whenever an identity that differs from the identity assertion administrative identity must be asserted. As a consequence, the proxyAuthz control cannot be directly used by the clients, otherwise it would be duplicated, and this is not allowed. However, there are notable exceptions:
  • when mode=none is used, no proxyAuthz takes place;
  • when native SASL authorization is used at SASL bind, the identity is directly asserted at the connection level, so the proxyAuthz control at the operation level is available.

Remote server requirements

There are a few requirements that impact the remote server to allow the exploitation of the identity assertion feature.
  • The administrative identity must exist on the remote server.
  • The administrative identity must use a bind mechanism that is supported by the remote server, and that provides a ssf appropriate for authorization (see Admin Guide for details).
  • The administrative identity on the remote server must be allowed to authorize as the desired identities; this in general must be obtained by using the authzTo attribute of the administrative identity, because the identities it is authorizing as likely do not exist on the remote server (otherwise there would be no need for the identity assertion feature...). This requires the use of the authz-policy to statement (see slapd.conf(5) for details), which may present security implications that must be carefully understood and counteracted by the remote server's administrator.

Scenarios

The identity assertion feature may be used in rather different scenarios.
  • To glue together different remote servers with different branches of the same naming context, to make them transparent to the final user as if they were one database:
        authz-regexp    "^uid=([^,]+),.*"
                        "uid=$1,ou=People,dc=example,dc=com"
        access to *
            by * read
    
        # people branch
        database        ldap
        suffix          "ou=People,dc=example,dc=com"
        uri             "ldap://people.example.com"
        idassert-bind   bindmethod=sasl
                        saslmech=DIGEST-MD5
                        authcID=proxy
                        credentials=proxy
                        mode=self
    
        # groups branch
        database        ldap
        suffix          "ou=Groups,dc=example,dc=com"
        uri             "ldap://groups.example.com"
        idassert-bind   bindmethod=sasl
                        saslmech=DIGEST-MD5
                        authcID=proxy
                        credentials=proxy
                        mode=self
    
        # root
        database        bdb
        suffix          "dc=example,dc=com"
        # other bdb stuff...
    
        overlay         glue
        glue-sub        "ou=People,dc=example,dc=com"
        glue-sub        "ou=Groups,dc=example,dc=com"
    
    The remote servers must contain the proxy identity; the configuration of the first one looks like:
        authz-policy    to
        authz-regexp    "^uid=([^,]+),.*"
                        "uid=$1,ou=People,dc=example,dc=com"
    
        # people branch
        database        bdb
        suffix          "ou=People,dc=example,dc=com"
        # other bdb stuff...
    
        access to attrs=userPassword
            by self =xw
            by * =x
    
        access to *
            by users read
            by * search
    
    the configuration of the second one looks like:
        authz-policy    to
        authz-regexp    "^uid=([^,]+),.*"
                        "uid=$1,ou=Groups,dc=example,dc=com"
    
        # groups branch
        database        bdb
        suffix          "ou=Groups,dc=example,dc=com"
        # other bdb stuff...
    
        access to attrs=userPassword
            by self =xw
            by * =x
    
        access to *
            by users read
            by * search
    
    A local root of the naming context must be provided to glue together the remote servers. Operations that refer to the proxied naming branches of the naming contexts are correctly proxied to the remote servers; all other operations are dealt with by the local root database.

    A complete example is provided as test029 in the distribution.

  • To allow (dumb) clients that do not perform bind to access servers that require bind (and some ssf) by asserting some static identity (the dn:<dn>, or even the anonymous mode, to implement the "sandbox" user described above) without any idassert-authzFrom rule in place:
        database        ldap
        suffix          "dc=example,dc=com"
        uri             "ldap://ldap.example.com"
        idassert-bind   bindmethod=simple
                        binddn="cn=Proxy,dc=example,dc=com"
                        credentials=proxy
                        authzID="dn:cn=Sandbox,dc=example,dc=com"
    
    If no authzID is given, and mode is set to none (for instance because the remote server does not support the proxyAuthz control), the clients will be authorized as "cn=Proxy,dc=example,dc=com" even if they actually connected anonymously to the proxy. Beware that this may be a significant security breach, if that identity is granted anything but anonymous read privileges.

Caveats and unresolved issues

  • If SASL native authorization is used and anonymous connections are allowed, the proxyAuthz control is still applied to every anonymous operation, because the local connection appears as unbound. This leads to unrequired extra work and, moreover, the proxyAuthz control will be applied on behalf of the authorized identity, which might have insufficient or inappropriate permissions.

Security implications

The identity assertion feature heavily impacts security at the administration level. It uses well-understood and developed mechanisms both at the client and at the server levels (bind operation, proxyAuthz control, authorization permissions via the authzTo/authzFrom mechanism). It requires some level of interaction between the administration of the remote server and of the proxy to set up:
  • the authorization rules in the idassert-authzFrom statement to access the feature at the proxy level; see identity assertion access for details;
  • the administrative identity on the remote server;
  • the access policy of the administrative identity vs. those of the asserted users, not present on the remote database
  • the authz-policy of the remote server; see slapd.conf(5) for details;
  • the authzTo values of the administrative identity on the remote server; see slapd.conf(5) for details.
Its importance for the security of distributed and proxied DSAs is fundamental because it provides a robust and consistent mechanism to fill the gap of proxying for clients whose identity cannot be directly assessed by the remote server.
ando@sys-net.it
The syntax of the Identity Assertion feature has changed since early releases of 2.3. Releases after 2.3.3 will use the new syntax as described above and in the man page, slapd-ldap(5).
ando@sys-net.it
[Append to This Answer]
Previous: (Answer) The LDBM backend
Next: (Answer) The passwd backend (How do I setup/configure back-passwd?)
This document is: http://www.openldap.org/faq/index.cgi?file=532
[Search] [Appearance]
This is a Faq-O-Matic 2.721.test.
© Copyright 1998-2013, OpenLDAP Foundation, info@OpenLDAP.org