]> git.sur5r.net Git - openldap/commitdiff
First commit of Hallvard's backend documentation effort
authorPierangelo Masarati <ando@openldap.org>
Mon, 29 Apr 2002 20:24:29 +0000 (20:24 +0000)
committerPierangelo Masarati <ando@openldap.org>
Mon, 29 Apr 2002 20:24:29 +0000 (20:24 +0000)
Backend documentation patch, version 1

================
Most of this text is taken from OpenLDAP.  The work of rewriting it
to manual pages is done by by Hallvard B. Furuseth and placed into
the public domain.  This software is not subject to any license of
the University of Oslo.
================

Hallvard B. Furuseth <h.b.furuseth@usit.uio.no>, April 2002.

15 files changed:
doc/man/man5/slapd-bdb.5 [new file with mode: 0644]
doc/man/man5/slapd-ldbm.5 [new file with mode: 0644]
doc/man/man5/slapd-meta.5 [new file with mode: 0644]
doc/man/man5/slapd-null.5 [new file with mode: 0644]
doc/man/man5/slapd-passwd.5 [new file with mode: 0644]
doc/man/man5/slapd-perl.5 [new file with mode: 0644]
doc/man/man5/slapd-shell.5 [new file with mode: 0644]
doc/man/man5/slapd-sql.5 [new file with mode: 0644]
doc/man/man5/slapd-tcl.5 [new file with mode: 0644]
doc/man/man5/slapd.conf.5
doc/man/man8/slapd.8
libraries/librewrite/RATIONALE
servers/slapd/back-perl/SampleLDAP.pm
servers/slapd/back-sql/docs/concept
servers/slapd/back-tcl/README.back-tcl

diff --git a/doc/man/man5/slapd-bdb.5 b/doc/man/man5/slapd-bdb.5
new file mode 100644 (file)
index 0000000..519b131
--- /dev/null
@@ -0,0 +1,99 @@
+.TH SLAPD-BDB 5 "28 April 2002" "OpenLDAP LDVERSION"
+.\" Copyright 1998-2002 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.\" $OpenLDAP$
+.SH NAME
+slapd-bdb \- BDB backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The BDB backend to
+.BR slapd (8)
+is the recommended backend for a normal slapd database.
+It uses the Sleepycat BerkelyDB package to store data.
+It makes extensive use of indexing and caching to speed data access.
+.SH CONFIGURATION
+The
+.BR slapd.conf (5)
+options in this category apply to the BDB databases.
+That is, they must follow a "database bdb" line and come before any
+subsequent "backend" or "database" lines.
+.TP
+.B cachesize <integer>
+Specify the size in entries of the in-memory cache maintained 
+by the BDB backend database instance.
+The default is 1000 entries.
+.TP
+.B checkpoint <kbyte> <min>
+Specify the frequency for checkpointing the database transaction log.
+A checkpoint operation flushes the database buffers to disk and writes
+a checkpoint record in the log.
+The checkpoint will occur if either <kbyte> data has been written or
+<min> minutes have passed since the last checkpoint.
+Both arguments default to zero, in which case they are ignored.
+See the Berkeley DB reference guide for more details.
+.TP
+.B dbnosync
+Specify that on-disk database contents should not be immediately
+synchronized with in memory changes.
+Enabling this option may improve performance at the expense of data
+security.
+.TP
+.B directory <directory>
+Specify the directory where the BDB files containing this database and
+associated indexes live.
+A separate directory must be specified for each database.
+The default is
+.BR LOCALSTATEDIR/openldap-data .
+.TP
+.B dirtyread
+Allow reads of modified but not yet committed data.
+Usually transactions are isolated to prevent other operations from
+accessing uncommitted data.
+This option may improve performance, but may also return inconsistent
+results if the data comes from a transaction that is later aborted.
+In this case, the modified data is discarded and a subsequent search
+will return a different result.
+.TP
+.B
+index {<attrlist>|default} [pres,eq,approx,sub,<special>]
+Specify the indexes to maintain for the given attribute (or
+list of attributes).
+Some attributes only support a subset of indexes.
+If only an <attr> is given, the indices specified for \fBdefault\fR
+are maintained.
+Note that setting a default does not imply that all attributes will be
+indexed.
+
+A number of special index parameters may be specified.
+The index type
+.B sub
+can be decomposed into
+.BR subinitial ,
+.BR subany ,\ and
+.B subfinal
+indices.
+The special type
+.B nolang
+may be specified to disallow use of this index by language subtypes.
+The special type
+.B nosubtypes
+may be specified to disallow use of this index by named subtypes.
+Note: changing index settings requires rebuilding indices, see
+.BR slapindex (8).
+.TP
+.B lockdetect {oldest|youngest|fewest|random|default}
+Specify which transaction to abort when a deadlock is detected.
+The default is the same as
+.BR random .
+.TP
+.B mode <integer>
+Specify the file protection mode that newly created database 
+index files should have.
+The default is 0600.
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8),
+.BR slapadd (8),
+.BR slapcat (8),
+.BR slapindex (8).
diff --git a/doc/man/man5/slapd-ldbm.5 b/doc/man/man5/slapd-ldbm.5
new file mode 100644 (file)
index 0000000..95ca923
--- /dev/null
@@ -0,0 +1,122 @@
+.TH SLAPD-LDBM 5 "28 April 2002" "OpenLDAP LDVERSION"
+.\" Copyright 1998-2002 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.\" $OpenLDAP$
+.SH NAME
+slapd-ldbm \- LDBM backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The LDBM backend to
+.BR slapd (8)
+is a database that makes
+extensive use of indexing and caching to speed data access.
+.\" .SH LDBM BACKEND-SPECIFIC OPTIONS
+.\" Options in this category only apply to the LDBM backend.
+.\" That is, they must follow "backend ldbm" line and come before
+.\" any subsequent "backend" or "database" lines.
+.SH CONFIGURATION
+The
+.BR slapd.conf (5)
+options in this category apply to the LDBM databases.
+That is, they must follow a "database ldbm" line and come before any
+subsequent "backend" or "database" lines.
+.TP
+.B cachesize <integer>
+Specify the size in entries of the in-memory cache maintained 
+by the LDBM backend database instance.
+The default is 1000 entries.
+.TP
+.B dbcachesize <integer>
+Specify the size in bytes of the in-memory cache associated with each
+open index file.
+If not supported by the underlying database method, this option is
+ignored without comment.
+The default is 100000 bytes.
+.TP
+.B dbnolocking
+Specify that no database locking should be performed.  
+Enabling this option may improve performance at the expense of data security.
+Do NOT run any slap tools while slapd is running.
+.TP
+.B dbnosync
+Specify that on-disk database contents should not be immediately
+synchronized with in memory changes.
+Enabling this option may improve performance at the expense of data
+security.
+.TP
+.B dbsync <frequency> <maxdelays> <delayinterval>
+Flush dirty database buffers to disk every
+.B <seconds>
+seconds.
+Implies
+.B dbnosync
+(ie. indvidual updates are no longer written to disk).
+It attempts to avoid syncs during periods of peak activity by waiting
+.B <delayinterval>
+seconds if the server is busy, repeating this delay up to
+.B <maxdelays>
+times before proceeding.  
+It is an attempt to provide higher write performance with some amount
+of data security.
+Note that it may still be possible to get an inconsistent database if
+the underlying engine fills its cache and writes out individual pages
+and slapd crashes or is killed before the next sync.
+.B <maxdelays>
+and
+.B <delayinterval>
+are optional and default to
+.B 12
+and
+.B 5
+respectively, giving a total elapsed delay of 60 seconds before a sync
+will occur.
+.B <maxdelays>
+may be zero, and
+.B <delayinterval>
+must be 1 or greater.
+.TP
+.B directory <directory>
+Specify the directory where the LDBM files containing this database and
+associated indexes live.
+A separate directory must be specified for each database.
+The default is
+.BR LOCALSTATEDIR/openldap-data .
+.TP
+.B
+index {<attrlist>|default} [pres,eq,approx,sub,<special>]
+Specify the indexes to maintain for the given attribute (or
+list of attributes).
+Some attributes only support a subset of indexes.
+If only an <attr> is given, the indices specified for \fBdefault\fR
+are maintained.
+Note that setting a default does not imply that all attributes will be
+indexed.
+
+A number of special index parameters may be specified.
+The index type
+.B sub
+can be decomposed into
+.BR subinitial ,
+.BR subany ,\ and
+.B subfinal
+indices.
+The special type
+.B nolang
+may be specified to disallow use of this index by language subtypes.
+The special type
+.B nosubtypes
+may be specified to disallow use of this index by named subtypes.
+Note: changing index settings requires rebuilding indices, see
+.BR slapindex (8).
+.TP
+.B mode <integer>
+Specify the file protection mode that newly created database 
+index files should have.
+The default is 0600.
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8),
+.BR slapadd (8),
+.BR slapcat (8),
+.BR slapindex (8).
diff --git a/doc/man/man5/slapd-meta.5 b/doc/man/man5/slapd-meta.5
new file mode 100644 (file)
index 0000000..9e3ef92
--- /dev/null
@@ -0,0 +1,657 @@
+.TH SLAPD_META 5 "28 April 2002" "OpenLDAP LDVERSION"
+.\" Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+.\" Copying restrictions apply.  See the COPYRIGHT file.
+.\" Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
+.\" $OpenLDAP$
+.\"
+.\" Portions of this document should probably be moved to slapd-ldap(5)
+.\" and maybe manual pages for librewrite.
+.\"
+.SH NAME
+slapd_meta \- metadirectory backend
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The
+.B meta
+backend to
+.BR slapd (8)
+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).
+.LP
+A basic knowledge of the functionality of the
+.BR slapd_ldap (5)
+backend is recommended.
+This backend has been designed as an enhancement of the ldap backend.
+The two backends share many features (actually they also share
+portions of code).
+While the
+.B ldap
+backend is intended to proxy operations directed to a single server, the
+.B meta
+backend 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.
+.SH EXAMPLES
+There are examples various places in this document, as well as in the
+slapd/back-meta/data/ directory in the OpenLDAP source tree.
+.SH CONFIGURATION
+The
+.BR slapd.conf (5)
+options in this category apply to the META backend database.
+That is, they must follow a "database meta" line and come before any
+subsequent "backend" or "database" lines.
+.LP
+Note: as with the
+.B ldap
+backend, 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
+.LP
+.nf
+       lastmod         off
+.fi
+.LP
+for every
+.B ldap
+and
+.B meta
+backend.
+.SH "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:
+.TP
+.B 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.
+.TP
+.B 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.
+.SH "TARGET SPECIFICATION"
+Target specification starts with a "uri" directive:
+.TP
+.B uri <protocol>://[<host>[:<port>]]/<naming context>
+The "server" directive that was allowed in the LDAP backend (although
+deprecated) has been discarded in the Meta backend.
+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.:
+.LP
+.nf
+  suffix "dc=foo,dc=com"
+  uri    "ldap://x.foo.com/dc=x,dc=foo,dc=com"
+.fi
+.LP
+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.
+.TP
+.B 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.
+.TP
+.B binddn <administrative dn for ac purposes>
+This directive, as in the LDAP backend, 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.
+.TP
+.B bindpw <password for ac purposes>
+This directive sets the password for acl checking in conjunction
+with the above mentioned "binddn" directive.
+.TP
+.B 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.
+.TP
+.B 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.
+.TP
+.B rewrite* ...
+The rewrite options are described in the "REWRITING" section.
+.TP
+.B 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 the LDAP backend 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.
+.LP
+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".
+.LP
+See the "REWRITING" section.
+.TP
+.B map {objectClass|attribute} {<source>|*} [<dest>|*]
+This maps object classes and attributes as in the LDAP backend.
+See
+.BR slapd-ldap (5).
+.SH "SCENARIOS"
+A powerful (and in some sense dangerous) rewrite engine has been added
+to both the LDAP and Meta backends.
+While the former can gain limited beneficial effects from rewriting
+stuff, the latter can become an amazingly powerful tool.
+.LP
+Consider a couple of scenarios first.
+.LP
+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 Meta database can be configured as:
+.LP
+.nf
+  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"
+.fi
+.LP
+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.
+.LP
+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 incur 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 Meta backend as:
+.LP
+.nf
+  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"
+.fi
+.LP
+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.
+.LP
+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).
+.LP
+Finally, if the scope is "sub" the incoming base is replaced
+by each target's unmassaged naming context, and the scope
+is not altered.
+.LP
+2b) Consider the above reported scenario with the two servers
+sharing the same naming context:
+.LP
+.nf
+  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"
+.fi
+.LP
+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.
+.SH ACLs
+Note on ACLs: at present you may add whatever ACL rule you desire
+to to the Meta (and LDAP) backends.
+However, the meaning of an ACL on a proxy may require some
+considerations.
+Two philosophies may be considered:
+.LP
+a) the remote server dictates the permissions; the proxy simply passes
+back what it gets from the remote server.
+.LP
+b) the remote server unveils "everything"; the proxy is responsible
+for protecting data from unauthorized access.
+.LP
+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
+.LP
+.nf
+  access to dn="<dn>" attr=<attr>
+        by dnattr=<dnattr> read
+        by * none
+.fi
+.LP
+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)
+.LP
+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!
+.LP
+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".
+.\"
+.\" If this section is moved, also update the reference in
+.\" libraries/librewrite/RATIONALE.
+.\"
+.SH REWRITING
+A string is rewritten according to a set of rules, called a `rewrite
+context'.
+The rules are based on Regular Expressions (POSIX regex) with
+substring matching; extensions are planned to allow basic variable
+substitution and map resolution of substrings.
+The behavior of pattern matching/substitution can be altered by a set
+of flags.
+.LP
+The underlying concept is to build a lightweight rewrite module
+for the slapd server (initially dedicated to the LDAP backend).
+.SH Passes
+An incoming string is matched agains a set of rules.
+Rules are made of a match pattern, a substitution pattern and a set of
+actions.
+In case of match a string rewriting is performed according to the
+substitution pattern that allows to refer to substrings matched in the
+incoming string.
+The actions, if any, are finally performed.
+The substitution pattern allows map resolution of substrings.
+A map is a generic object that maps a substitution pattern to a value.
+.SH "Pattern Matching Flags"
+.TP
+.B `C'
+honors case in matching (default is case insensitive)
+.TP
+.B `R'
+use POSIX Basic Regular Expressions (default is Extended)
+.SH "Action Flags"
+.TP
+.B `:'
+apply the rule once only (default is recursive)
+.TP
+.B `@'
+stop applying rules in case of match.
+.TP
+.B `#'
+stop current operation if the rule matches, and issue an `unwilling to
+perform' error.
+.TP
+.B `G{n}'
+jump n rules back and forth (watch for loops!).
+Note that `G{1}' is implicit in every rule.
+.TP
+.B `I'
+ignores errors in rule; this means, in case of error, e.g. issued by a
+map, the error is treated as a missed match.
+The `unwilling to perform' is not overridden.
+.LP
+The ordering of the flags is significant.
+For instance: `IG{2}' means ignore errors and jump two lines ahead
+both in case of match and in case of error, while `G{2}I' means ignore
+errors, but jump thwo lines ahead only in case of match.
+.LP
+More flags (mainly Action Flags) will be added as needed.
+.SH "Pattern matching:"
+See
+.BR regex (7).
+.SH "String Substitution:"
+The string substitution happens according to a substitution pattern.
+.TP
+.B -
+substring substitution is allowed with the syntax `\\d' where `d' is a
+digit ranging 0-9 (0 is the full match).
+I see that 0-9 digit expansion is a widely accepted practise; however
+there is no technical reason to use such a strict limit.
+A syntax of the form `\\{ddd}' should be fine if there is any need to
+use a higher number of possible submatches.
+.TP
+.B -
+variable substitution will be allowed (at least when I figure out
+which kind of variable could be proficiently substituted)
+.TP
+.B -
+map lookup will be allowed (map lookup of substring matches in gdbm,
+ldap(!), math(?) and so on maps `a la sendmail'.
+.TP
+.B -
+subroutine invocation will make it possible to rewrite a submatch in
+terms of the output of another rewriteContext.
+.Sh "Old syntax:"
+.TP
+.B `\\' {0-9} [ `{' <name> [ `(' <args> `)' ] `}' ]
+where <name> is the name of a built-in map, and <args> are optional
+arguments to the map, if the map <name> requires them.
+The following experimental maps have been implemented:
+.TP
+.B \\n{xpasswd}
+maps the n-th substring match as uid to the gecos field in
+/etc/passwd;
+.TP
+.B \\n{xfile(/absolute/path)}
+maps the n-th substring match to a `key value' style plain text file.
+.TP
+.B \\n{xldap(ldap://url/with?%0?in?filter)
+maps the n-th substring match to an attribute retrieved by means of an
+LDAP url with substitution of %0 in the filter (NOT IMPL.)
+.SH "New scheme:"
+everything starting with `\\' requires substitution;
+.LP
+the only obvious exception is `\\\\', which is left as is;
+.LP
+the basic substitution is `\\d', where `d' is a digit;
+0 means the whole string, while 1-9 is a submatch;
+.LP
+in the outdated schema, the digit may be optionally
+followed by a `{', which means pipe the submatch into
+the map described by the string up to the following `}';
+.LP
+the output of the map is used instead of the submatch;
+.LP
+in the new schema, a `\\' followed by a `{' invokes an
+advanced substitution scheme.
+The pattern is:
+.LP
+.nf
+  `\\' `{' [{ <op> }] <name> `(' <substitution schema> `)' `}'
+.fi
+.LP
+where <name> must be a legal name for the map, i.e.
+.LP
+.nf
+  <name> ::= [a-z][a-z0-9]* (case insensitive)
+  <op> ::= `>' `|' `&' `&&' `*' `**' `$'
+.fi
+.LP
+and <substitution schema> must be a legal substitution
+schema, with no limits on the nesting level.
+.LP
+The operators are:
+.TP
+.B >
+sub context invocation; <name> must be a legal, already defined
+rewrite context name
+.TP
+.B |
+external command invocation; <name> must refer to a legal, already
+defined command name (NOT IMPL.)
+.TP
+.B &
+variable assignment; <name> defines a variable in the running
+operation structure which can be dereferenced later (NOT IMPL.)
+.TP
+.B *
+variable dereferencing; <name> must refer to a variable that is
+defined and assigned for the running operation (NOT IMPL.)
+.TP
+.B $
+parameter dereferencing; <name> must refer to an existing parameter;
+the idea is to make some run-time parameters set by the system
+available to the rewrite engine, as the client host name, the bind dn
+if any, constant parameters initialized at config time, and so on (NOT
+IMPL.)
+.LP
+Note: as the slapd parsing routines escape backslashes ('\\'),
+a double backslash is required inside substitution patterns.
+To overcome the resulting heavy notation, the substitution escaping
+has been delegated to the `%' symbol, which should be used
+instead of `\\' in string substitution patterns.
+The symbol can be altered at will by redefining the related macro in
+"rewrite-int.h".
+In the current snapshot, all the `\\' on the left side of each rule
+(the regex pattern) must be converted in `\\\\'; all the `\\' on the
+right side of the rule (the substitution pattern) must be turned into
+`%'.
+In the following examples, the original (more readable) syntax is
+used.
+.SH "Rewrite context:"
+A rewrite context is a set of rules which are applied in sequence.
+The basic idea is to have an application initialize a rewrite
+engine (think of Apache's mod_rewrite ...) with a set of rewrite
+contexts; when string rewriting is required, one invokes the
+appropriate rewrite context with the input string and obtains the
+newly rewritten one if no errors occur.
+.LP
+An interesting application, in the LDAP backend or in slapd itself,
+could associate each basic server operation to a rewrite context
+(most of them possibly aliasing the default one).
+Then, DN rewriting could take place at any invocation of a backend
+operation.
+.LP
+client -> server:
+.LP
+.nf
+     default         if defined and no specific
+                     context is available
+     bindDn          bind
+     searchBase      search
+     searchFilter    search
+     compareDn       compare
+     addDn           add
+     modifyDn        modify
+     modrDn          modrdn
+     newSuperiorDn   modrdn
+     deleteDn        delete
+.fi
+.LP
+server -> client:
+.LP
+.nf
+     searchResult    search (only if defined; no default)
+.fi
+.LP
+.SH "Basic configuration syntax"
+.TP
+.B rewriteEngine { on | off }
+If `on', the requested rewriting is performed; if `off', no
+rewriting takes place (an easy way to stop rewriting without
+altering too much the configuration file).
+.TP
+.B rewriteContext <context name> [ alias <aliased context name> ]
+<Context name> is the name that identifies the context, i.e. the name
+used by the application to refer to the set of rules it contains.
+It is used also to reference sub contexts in string rewriting.
+A context may aliase another one.
+In this case the alias context contains no rule, and any reference to
+it will result in accessing the aliased one.
+.TP
+.B rewriteRule <regex pattern> <substitution pattern> [ <flags> ]
+Determines how a tring can be rewritten if a pattern is matched.
+Examples are reported below.
+.SH "Additional configuration syntax:"
+.TP
+.B rewriteMap <map name> <map type> [ <map attrs> ]
+Allows to define a map that transforms substring rewriting into
+something else.
+The map is referenced inside the substitution pattern of a rule.
+.TP
+.B rewriteParam <param name> <param value>
+Sets a value with global scope, that can be dereferenced by the
+command `\\{$paramName}'.
+.TP
+.B rewriteMaxPasses <number of passes>
+Sets the maximum number of total rewriting passes taht can be
+performed in a signle rewriting operation (to avoid loops).
+.SH "Configuration examples:"
+.nf
+     # set to `off' to disable rewriting
+     rewriteEngine on
+
+     # Everything defined here goes into the `default' context.
+     # This rule changes the naming context of anything sent
+     # to `dc=home,dc=net' to `dc=OpenLDAP, dc=org'
+
+     rewriteRule "(.*)dc=home,[ ]?dc=net"
+                 "\\1dc=OpenLDAP, dc=org"  ":"
+
+     # Start a new context (ends input of the previous one).
+     # This rule adds blancs between dn parts if not present.
+     rewriteContext  addBlancs
+     rewriteRule     "(.*),([^ ].*)" "\\1, \\2"
+
+     # This one eats blancs
+     rewriteContext  eatBlancs
+     rewriteRule     "(.*),[ ](.*)" "\\1,\\2"
+
+     # Here control goes back to the default rewrite
+     # context; rules are appended to the existing ones.
+     # anything that gets here is piped into rule `addBlancs'
+     rewriteContext  default
+     rewriteRule     ".*" "\\{>addBlancs(\\0)}" ":"
+
+     # Anything with `uid=username' is looked up in
+     # /etc/passwd for gecos (I know it's nearly useless,
+     # but it is there just to test something fancy!). Note
+     # the `I' flag that leaves `uid=username' in place if
+     # `username' does not have a valid account, and the
+     # `:' that forces the rule to be processed exactly once.
+     rewriteContext  uid2Gecos
+     rewriteRule     "(.*)uid=([a-z0-9]+),(.+)"
+                     "\\1cn=\\2{xpasswd},\\3"      "I:"
+
+     # Finally, in a bind, if one uses a `uid=username' dn,
+     # it is rewritten in `cn=name surname' if possible.
+     rewriteContext  bindDn
+     rewriteRule     ".*" "\\{>addBlancs(\\{>uid2Gecos(\\0)})}" ":"
+
+     # Rewrite the search base  according to `default' rules.
+     rewriteContext  searchBase alias default
+
+     # Search results with OpenLDAP dn are rewritten back with
+     # `dc=home,dc=net' naming context, with spaces eaten.
+     rewriteContext  searchResult
+     rewriteRule     "(.*[^ ]?)[ ]?dc=OpenLDAP,[ ]?dc=org"
+                     "\\{>eatBlancs(\\1)}dc=home,dc=net"    ":"
+
+     # Bind with email instead of full dn: we first need
+     # an ldap map that turns attributes into a dn (the
+     # filter is provided by the substitution string):
+     rewriteMap ldap attr2dn "ldap://host/dc=my,dc=org?dn?sub"
+
+     # Then we need to detect emails; note that the rule
+     # in case of match stops rewriting; in case of error,
+     # it is ignored.  In case we are mapping virtual
+     # to real naming contexts, we also need to rewrite
+     # regular DNs, because the definition of a bindDn
+     # rewrite context overrides the default definition.
+     rewriteContext bindDn
+     rewriteRule "(mail=[^,]+@[^,]+)" "\\{attr2dn(\\1)}" "@I"
+
+     # This is a rather sophisticate example. It massages a
+     # search filter in case who performs the search has
+     # administrative privileges.  First we need to keep
+     # track of the bind dn of the incoming request:
+     rewriteContext  bindDn
+     rewriteRule     ".+" "\\{**&binddn(\\0)}" ":"
+
+     # A search filter containing `uid=' is rewritten only
+     # if an appropriate dn is bound.
+     # To do this, in the first rule the bound dn is
+     # dereferenced, while the filter is decomposed in a
+     # prefix, the argument of the `uid=', and in a
+     # suffix. A tag `<>' is appended to the DN. If the DN
+     # refers to an entry in the `ou=admin' subtree, the
+     # filter is rewritten OR-ing the `uid=<arg>' with
+     # `cn=<arg>'; otherwise it is left as is. This could be
+     # useful, for instance, to allow apache's auth_ldap-1.4
+     # module to authenticate users with both `uid' and
+     # `cn', but only if the request comes from a possible
+     # `dn: cn=Web auth, ou=admin, dc=home, dc=net' user.
+     rewriteContext searchFilter
+     rewriteRule "(.*\\()uid=([a-z0-9_]+)(\\).*)"
+       "\\{**binddn}<>\\{&prefix(\\1)}\\{&arg(\\2)}\\{&suffix(\\3)}"
+       ":I"
+     rewriteRule "[^,]+,[ ]?ou=admin,[ ]?dc=home,[ ]?dc=net"
+       "\\{*prefix}|(uid=\\{*arg})(cn=\\{*arg})\\{*suffix}" "@I"
+     rewriteRule ".*<>" "\\{*prefix}uid=\\{*arg}\\{*suffix}"
+.fi
+.SH "LDAP Proxy resolution (a possible evolution of slapd-ldap(5):"
+In case the rewritten dn is an LDAP URL, the operation is initiated
+towards the host[:port] indicated in the url, if it does not refer
+to the local server.
+E.g.:
+.LP
+.nf
+  rewriteRule \'^cn=root,.*\' \'\\0\'                     \'G{3}\'
+  rewriteRule \'^cn=[a-l].*\' \'ldap://ldap1.my.org/\\0\' \'@\'
+  rewriteRule \'^cn=[m-z].*\' \'ldap://ldap2.my.org/\\0\' \'@\'
+  rewriteRule \'.*\'          \'ldap://ldap3.my.org/\\0\' \'@\'
+.fi
+.LP
+(Rule 1 is simply there to illustrate the `G{n}' action; it could have
+been written:
+.LP
+.nf
+  rewriteRule \'^cn=root,.*\' \'ldap://ldap3.my.org/\\0\' \'@\'
+.fi
+.LP
+with the advantage of saving one rewrite pass ...)
+.SH "SEE ALSO"
+.BR slapd.conf (5),
+.BR slapd (8),
+.BR regex (7).
diff --git a/doc/man/man5/slapd-null.5 b/doc/man/man5/slapd-null.5
new file mode 100644 (file)
index 0000000..350b7db
--- /dev/null
@@ -0,0 +1,46 @@
+.TH SLAPD-NULL 5 "25 April 2002" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.SH NAME
+slapd-null \- Null backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The Null backend to
+.BR slapd (8)
+is surely the most useful part of
+.BR slapd :
+.br
+- Searches return success but no entries.
+.br
+- Compares return compareFalse.
+.br
+- Updates return success (unless readonly is on) but do nothing.
+.br
+- Binds fail unless the database option "bind on" is given.
+.br
+Inspired by the /dev/null device.
+.SH CONFIGURATION
+The
+.BR slapd.conf (5)
+option in this category applies to the NULL backend database.
+That is, it must follow a "database null" line and come before
+any subsequent "database" lines.
+Other database options are described in the
+.BR slapd.conf (5)
+manual page.
+.TP
+.B bind <on/off>
+Allow binds as DNs in this backend's suffix.
+The default is "off".
+.SH EXAMPLE
+Here is a possible slapd.conf extract using the Null backend:
+.LP
+.nf
+  database null
+  suffix   "cn=Nothing"
+  bind     on
+.fi
+.LP
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8).
diff --git a/doc/man/man5/slapd-passwd.5 b/doc/man/man5/slapd-passwd.5
new file mode 100644 (file)
index 0000000..1cf6bf6
--- /dev/null
@@ -0,0 +1,32 @@
+.TH SLAPD-PASSWD 5 "25 April 2002" "OpenLDAP LDVERSION"
+.\" Copyright 1998-2002 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.\" $OpenLDAP$
+.SH NAME
+slapd-passwd \- /etc/passwd backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The PASSWD backend to
+.BR slapd (8)
+serves up the user account information listed in the system
+.BR passwd (5)
+file.
+.SH CONFIGURATION
+The
+.BR slapd.conf (5)
+options in this category apply to the PASSWD backend database.
+That is, they must follow a "database passwd" line and come before any
+subsequent "backend" or "database" lines.
+Other database options are described in the
+.BR slapd.conf (5)
+manual page.
+.TP
+.B file <filename>
+Specifies an alternate passwd file to use.
+The default is
+.BR /etc/passwd .
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8),
+.BR passwd (5).
diff --git a/doc/man/man5/slapd-perl.5 b/doc/man/man5/slapd-perl.5
new file mode 100644 (file)
index 0000000..16117d1
--- /dev/null
@@ -0,0 +1,170 @@
+.TH SLAPD-PERL 5 "25 April 2002" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.SH NAME
+slapd-perl \- Perl backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The Perl backend to
+.BR slapd (8)
+works by embedding a
+.BR perl (1)
+interpreter into
+.BR slapd (8).
+Any perl database section of the configuration file
+.BR slapd.conf (5)
+must then specify what Perl module to use.
+.B Slapd
+then creates a new Perl object that handles all the requests for that
+particular instance of the backend.
+.LP
+You will need to create a method for each one of the
+following actions:
+.LP
+.nf
+  * new        # creates a new object,
+  * search     # performs the ldap search,
+  * compare    # does a compare,
+  * modify     # modifies an entry,
+  * add        # adds an entry to backend,
+  * modrdn     # modifies an entry's rdn,
+  * delete     # deletes an ldap entry,
+  * config     # process unknown config file lines,
+  * init       # called after backend is initialized.
+.fi
+.LP
+Unless otherwise specified, the methods return the result code
+which will be returned to the client.  Unimplemented actions
+can just return unwillingToPerform (53).
+.TP
+.B new
+This method is called when the configuration file encounters a 
+.B perlmod
+line.
+The module in that line is then effectively `use'd into the perl
+interpreter, then the \fBnew\fR method is called to create a new
+object.
+Note that multiple instances of that object may be instantiated, as
+with any perl object.
+.\" .LP
+The
+.B new
+method receives the class name as argument.
+.TP
+.B search
+This method is called when a search request comes from a client.
+It arguments are as follows:
+.nf
+  * object reference
+  * base DN
+  * scope
+  * alias deferencing policy
+  * size limit
+  * time limit
+  * filter string
+  * attributes only flag (1 for yes)
+  * list of attributes that are to be returned (may be empty).
+.fi
+.LP
+Return value: (resultcode, ldif-entry, ldif-entry, ...)
+.TP
+.B compare
+This method is called when a compare request comes from a client.
+Its arguments are as follows.
+.nf
+  * object reference
+  * dn
+  * attribute assertion string
+.fi
+.LP
+.TP
+.B modify
+This method is called when a modify request comes from a client.
+Its arguments are as follows.
+.nf
+  * object reference
+  * dn
+  * a list formatted as follows
+    { "ADD" | "DELETE" | "REPLACE" }, attributetype, value..., ...
+.fi
+.LP
+.TP
+.B add
+This method is called when a add request comes from a client.
+Its arguments are as follows.
+.nf
+  * object reference
+  * entry in string format.
+.fi
+.LP
+.TP
+.B modrdn
+This method is called when a modrdn request comes from a client.
+Its arguments are as follows.
+.nf
+  * object reference
+  * dn
+  * new rdn
+  * delete old dn flag (1 means yes)
+.fi
+.LP
+.TP
+.B delete
+This method is called when a delete request comes from a client.
+Its arguments are as follows.
+.nf
+  * object reference
+  * dn
+.fi
+.LP
+.TP
+.B config
+This method is called with unknown
+.BR slapd.conf (5)
+configuration file lines.
+Its arguments are as follows.
+.nf
+  * object reference
+  * array of arguments on line
+.fi
+.LP
+Return value: nonzero if this is not a valid option.
+.TP
+.B init
+This method is called after backend is initialized.
+Its argument is as follows.
+.nf
+  * object reference
+.fi
+.LP
+Return value: nonzero if initialization failed.
+.SH CONFIGURATION
+The
+.BR slapd.conf (5)
+options in this category apply to the PERL backend database.
+That is, they must follow a "database perl" line and come before any
+subsequent "backend" or "database" lines.
+Other database options are described in the
+.BR slapd.conf (5)
+manual page.
+.TP
+.B perlModulePath /path/to/libs
+Add the path to the @INC variable.
+.TP
+.B perlModule ModName
+`Use' the module name ModName from ModName.pm
+.TP
+.B filterSearchResults
+Search results are candidates that need to be filtered (with the
+filter in the search request), rather than search results to be
+returned directly to the client.
+.SH EXAMPLE
+There is an example Perl module `SampleLDAP' in the slapd/back-perl/
+direcetory in the OpenLDAP source tree.
+.SH WARNING
+The interface of this backend to the perl module MAY change.
+Any suggestions would greatly be appreciated.
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8),
+.BR perl (1).
diff --git a/doc/man/man5/slapd-shell.5 b/doc/man/man5/slapd-shell.5
new file mode 100644 (file)
index 0000000..7a9d4a5
--- /dev/null
@@ -0,0 +1,53 @@
+.TH SLAPD-SHELL 5 "25 April 2002" "OpenLDAP LDVERSION"
+.\" Copyright 1998-2002 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.\" $OpenLDAP$
+.SH NAME
+slapd-shell \- Shell backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The Shell backend to
+.BR slapd (8)
+executes external programs to implement operations, and is designed to
+make it easy to tie an existing database to the
+.B slapd
+front-end.
+.SH CONFIGURATION
+The
+.BR slapd.conf (5)
+options in this category apply to the SHELL backend database.
+That is, they must follow a "database shell" line and come before any
+subsequent "backend" or "database" lines.
+.LP
+These options specify the pathname of the command to execute in response 
+to the given LDAP operation.
+Note that you need only supply configuration lines for those commands you
+want the backend to handle.
+Operations for which a command is not supplied will be refused with an
+"unwilling to perform" error.
+.TP
+.B bind <pathname>
+.TP
+.B unbind <pathname>
+.TP
+.B search <pathname>
+.TP
+.B compare <pathname>
+.TP
+.B modify <pathname>
+.TP
+.B modrdn <pathname>
+.TP
+.B add <pathname>
+.TP
+.B delete <pathname>
+.TP
+.B abandon <pathname>
+.SH EXAMPLE
+There is a skeleton search script in the slapd/back-shell/ directory
+in the OpenLDAP source tree.
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8),
+.BR sh (1).
diff --git a/doc/man/man5/slapd-sql.5 b/doc/man/man5/slapd-sql.5
new file mode 100644 (file)
index 0000000..f40659f
--- /dev/null
@@ -0,0 +1,324 @@
+.TH SLAPD-SQL 5 "25 April 2002" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.SH NAME
+slapd-sql \- SQL backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH PURPOSE
+The primary purpose of this backend (8) to
+.BR slapd (8)
+is to PRESENT information stored in some RDBMS as an LDAP subtree
+without any programming (some SQL and maybe stored procedures can't be
+considered programming, anyway ;).
+.LP
+That is, for example, when you (some ISP) have account information you
+use in RDBMS, and want to use modern solutions that expect such
+information in LDAP (to authenticate users, make email lookups etc.).
+Or you want to synchronize or distribute information between different
+sites/applications that use RDBMSes and/or LDAP.
+Or whatever else...
+.LP
+It is NOT designed as general-purpose backend that uses RDBMS instead
+of BerkeleyDB (as the standard LDBM backend does), though it can be
+used as such with several limitations.
+You can take a look at
+.B http://www.openldap.org/faq/index.cgi?file=378 
+(OpenLDAP FAQ-O-Matic/General LDAP FAQ/Directories vs. conventional
+databases) to find out more on this point.
+.LP
+The idea (detailed below) is to use some metainformation to translate
+LDAP queries to SQL queries, leaving relational schema untouched, so
+that old applications can continue using it without any
+modifications.
+This allows SQL and LDAP applications to inter-operate without
+replication, and exchange data as needed.
+.LP
+The SQL backend is designed to be tunable to virtually any relational
+schema without having to change source (through that metainformation
+mentioned).
+Also, it uses ODBC to connect to RDBMSes, and is highly configurable
+for SQL dialects RDBMSes may use, so it may be used for integration
+and distribution of data on different RDBMSes, OSes, hosts etc., in
+other words, in highly heterogeneous environment.
+.SH "METAINFORMATION USED"
+.LP
+Almost everything mentioned later is illustrated in examples located
+in the
+.B slapd/back-sql/rdbms_depend/
+directory in the OpenLDAP source tree, and contains scripts for
+generating sample database for Oracle,MS SQL Server and mySQL.
+.LP
+First thing that one must arrange for himself is what set of LDAP
+object classes can present your RDBMS information.
+.LP
+The easiest way is to create an objectclass for each entity you had in
+ER-diagram when designing your relational schema.
+Any relational schema, no matter how normalized it is, was designed
+after some model of your application's domain (for instance, accounts,
+services etc. in ISP), and is used in terms of its entities, not just
+tables of normalized schema.
+It means that for every attribute of every such instance there is an
+effective SQL query that loads its values.
+.LP
+Also you might want your object classes to conform to some of standard
+schemas like inetOrgPerson etc.
+.LP
+Nevertheless, when you think it out, we must define a way to translate
+LDAP operation requests to (series of) SQL queries.
+Let us deal with the SEARCH operation.
+.LP
+Example:
+Let's suppose that we store information about persons working in our 
+organization in two tables:
+.LP
+.nf
+  PERSONS                 PHONES
+  ----------              -------------
+  id integer              id integer
+  first_name varchar      pers_id integer references persons(id)
+  last_name varchar       phone
+  middle_name varchar
+  ...
+.fi
+.LP
+(PHONES contains telephone numbers associated with persons).
+A person can have several numbers, then PHONES contains several
+records with corresponding pers_id, or no numbers (and no records in
+PHONES with such pers_id).
+An LDAP objectclass to present such information could look like this:
+.LP
+.nf
+  person
+  -------
+  MUST cn
+  MAY telephoneNumber
+  MAY firstName
+  MAY lastName
+  ...
+.fi
+.LP
+To fetch all values for cn attribute given person ID, we construct the
+query:
+.LP
+.nf
+  SELECT CONCAT(persons.first_name,\' \',persons.last_name)
+      AS cn FROM persons WHERE persons.id=?
+.fi
+.LP
+for telephoneNumber we can use:
+.LP
+.nf
+  SELECT phones.phone AS telephoneNumber FROM persons,phones
+   WHERE persons.id=phones.pers.id AND persons.id=?
+.fi
+.LP
+If we wanted to service LDAP requests with filters like
+(telephoneNumber=123*), we would construct something like:
+.LP
+.nf
+  SELECT ... FROM persons,phones
+   WHERE persons.id=phones.pers.id
+     AND persons.id=?
+     AND phones.phone like \'123%\'
+.fi
+.LP
+So, if we had information about what tables contain values for each
+attribute, how to join this tables and arrange these values, we could
+try to automatically generate such statements, and translate search
+filters to SQL WHERE clauses.
+.LP
+To store such information, we add three more tables to our schema, so
+that and fill it with data (see samples):
+.LP
+.nf
+  ldap_oc_mappings (some columns are not listed for clarity)
+  ---------------
+  id=1
+  name="person"
+  keytbl="persons"
+  keycol="id"
+.fi
+.LP
+This table defines a mapping between objectclass (its name held in the
+"name" column), and a table that holds primary key for corresponding
+entities.
+For instance, in our example, the person entity, which we are trying
+to present as "person" objectclass, resides in two tables (persons and
+phones), and is identified by persons.id column (that we will call
+primary key for this entity).
+Keytbl and keycol thus contain "persons" (name of the table), and "id"
+(name of the column).
+.LP
+.nf
+  ldap_attr_mappings (some columns are not listed for clarity)
+  -----------
+  id=1
+  oc_id=1
+  name="cn"
+  sel_expr="CONCAT(persons.first_name,\' \',persons.last_name)"
+  from_tbls="persons"
+  join_where=NULL
+  ************
+  id=<n>
+  oc_map_id=1
+  name="telephoneNumber"
+  sel_expr="phones.phone"
+  from_tbls="persons,phones"
+  join_where="phones.pers_id=persons.id"
+.fi
+.LP
+This table defines mappings between LDAP attributes and SQL queries
+that load their values.
+Note that, unlike LDAP schema, these are not
+.B attribute types
+- attribute "cn" for "person" objectclass can well
+have its values in different table than "cn" for other objectclass,
+so attribute mappings depend on objectclass mappings (unlike attribute
+types in LDAP schema, which are indifferent to objectclasses).
+Thus, we have oc_map_id column with link to oc_mappings table.
+.LP
+Now we cut the SQL query that loads values for given attribute into 3 parts.
+First goes into sel_expr column - this is the expression we had
+between SELECT and FROM keywords, which defines WHAT to load.
+Next is table list - text between FROM and WHERE keywords.
+It may contain aliases for convenience (see exapmles).
+The last is part of where clause, which (if exists at all) express the
+condition for joining the table containing values wich table
+containing primary key (foreign key equality and such).
+If values are in the same table with primary key, then this column is
+left NULL (as for cn attribute above).
+.LP
+Having this information in parts, we are able to not only construct
+queries that load attribute values by id of entry (for this we could
+store SQL query as a whole), but to construct queries that load id's
+of objects that correspond to given search filter (or at least part of
+it).
+See below for examples.
+.LP
+.nf
+  ldap_entries
+  ------------
+  id=1
+  dn=<dn you choose>
+  oc_map_id=...
+  parent=<parent record id>
+  keyval=<value of primary key>
+.fi
+.LP
+This table defines mappings between DNs of entries in your LDAP tree,
+and values of primary keys for corresponding relational data.
+It has recursive structure (parent column references id column of the
+same table), which allows you to add any tree structure(s) to your
+flat relational data.
+Having id of objectclass mapping, we can determine table and column
+for primary key, and keyval stores value of it, thus defining exact
+tuple corresponding to LDAP entry with this DN.
+.LP
+Note that such design (see exact SQL table creation query) implies one
+important constraint - the key must be integer.
+But all that I know about well-designed schemas makes me think that it
+s not very narrow ;) If anyone needs support for different types for
+keys - he may want to write a patch, and submit it to OpenLDAP ITS,
+then I'll include it.
+.LP
+Also, several people complained that they don't really need very
+structured tree, and they don't want to update one more table every
+time they add or delete instance in relational schema.
+Those can use a view instead of real table for ldap_entries, something
+like this (by Robin Elfrink):
+.LP
+.nf
+  CREATE VIEW ldap_entries (id, dn, oc_map_id, parent, keyval)
+      AS SELECT (1000000000+userid),
+  UPPER(CONCAT(CONCAT(\'cn=\',gecos),\',o=MyCompany,c=NL\')),
+  1, 0, userid FROM unixusers UNION
+          SELECT (2000000000+groupnummer),
+  UPPER(CONCAT(CONCAT(\'cn=\',groupnaam),\',o=MyCompany,c=NL\')),
+  2, 0, groupnummer FROM groups;
+.fi
+.LP
+.SH "Typical SQL backend operation"
+Having metainformation loaded, the SQL backend uses these tables to
+determine a set of primary keys of candidates (depending on search
+scope and filter).
+It tries to do it for each objectclass registered in ldap_objclasses.
+.LP
+Example:
+for our query with filter (telephoneNumber=123*) we would get following 
+query generated (which loads candidate IDs)
+.LP
+.nf
+  SELECT ldap_entries.id,persons.id, \'person\' AS objectClass,
+         ldap_entries.dn AS dn
+    FROM ldap_entries,persons,phones
+   WHERE persons.id=ldap_entries.keyval
+     AND ldap_entries.objclass=?
+     AND ldap_entries.parent=?
+     AND phones.pers_id=persons.id
+     AND (phones.phone LIKE \'123%\')
+.fi
+.LP
+(for ONELEVEL search)
+or "... AND dn=?" (for BASE search)
+or "... AND dn LIKE \'%?\'" (for SUBTREE)
+.LP
+Then, for each candidate, we load attributes requested using
+per-attribute queries like
+.LP
+.nf
+  SELECT phones.phone AS telephoneNumber
+    FROM persons,phones
+   WHERE persons.id=? AND phones.pers_id=persons.id
+.fi
+.LP
+Then, we use test_filter() from frontend API to test entry for full
+LDAP search filter match (since we cannot effectively make sense of
+SYNTAX of corresponding LDAP schema attribute, we translate the filter
+into most relaxed SQL condition to filter candidates), and send it to
+user.
+.LP
+ADD, DELETE, MODIFY operations also performed on per-attribute
+metainformation (add_proc etc.).
+In those fields one can specify an SQL statement or stored procedure
+call which can add, or delete given value of given attribute, using
+given entry keyval (see examples -- mostly ORACLE and MSSQL - since
+there're no stored procs in mySQL).
+.LP
+We just add more columns to oc_mappings and attr_mappings, holding
+statements to execute (like create_proc, add_proc, del_proc etc.), and
+flags governing order of parameters passed to those statements.
+Please see samples to find out what are the parameters passed, and other
+information on this matter - they are self-explanatory for those familiar
+with concept expressed above.
+.LP
+.SH "common techniques (referrals, multiclassing etc.)"
+First of all, lets remember that among other major differences to
+complete LDAP data model, the concept above does not directly support
+such things as multiple objectclasses for entry, and referrals.
+Fortunately, they are easy to adopt in this scheme.
+The SQL backend suggests two more tables being added to schema -
+ldap_entry_objectclasses(entry_id,oc_name), and
+ldap_referrals(entry_id,url).
+.LP
+First contains any number of objectclass names that corresponding
+entries will be found by, in addition to that mentioned in
+mapping.
+The SQL backend automatically adds attribute mapping for "objectclass"
+attribute to each objectclass mapping, that loads values from this table.
+So, you may, for instance, have mapping for inetOrgPerson, and use it
+for queries for "person" objectclass...
+.LP
+Second table contains any number of referrals associated with given entry.
+The SQL backend automatically adds attribute mapping for "ref" attribute
+to each objectclass mapping, that loads values from this table.
+So, if you add objectclass "referral" to this entry, and make one or
+more tuples in ldap_referrals for this entry (they will be seen as
+values of "ref" attribute), you will have slapd return referral, as
+described in Administrators Guide.
+.LP
+.SH EXAMPLES
+There are example SQL modules in the slapd/back-sql/rdbms_depend/
+direcetory in the OpenLDAP source tree.
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8).
diff --git a/doc/man/man5/slapd-tcl.5 b/doc/man/man5/slapd-tcl.5
new file mode 100644 (file)
index 0000000..3b9d1ae
--- /dev/null
@@ -0,0 +1,243 @@
+.TH SLAPD-TCL 5 "28 April 2002" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.SH NAME
+slapd-tcl \- Tcl backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The Tcl backend to
+.BR slapd (8)
+works by embedding a
+.BR Tcl (3tcl)
+interpreter into
+.BR slapd (8).
+Any tcl database section of the configuration file
+.BR slapd.conf (5)
+must then specify what Tcl script to use.
+.SH CONFIGURATION
+The
+.BR slapd.conf (5)
+options in this category apply to the TCL backend database.
+That is, they must follow a "database tcl" line and come before any
+subsequent "backend" or "database" lines.
+Other database options are described in the
+.BR slapd.conf (5)
+manual page.
+.TP
+.B scriptpath      <filename.tcl>
+The full path to the tcl script used for this database
+.TP
+.B search   <proc>
+.TP
+.B add      <proc>
+.TP
+.B delete   <proc>
+.TP
+.B modify   <proc>
+.TP
+.B bind     <proc>
+.TP
+.B unbind   <proc>
+.TP
+.B modrdn   <proc>
+.TP
+.B compare  <proc>
+.TP
+.B abandon  <proc>
+The procs for each ldap function.
+This is similar to how the
+.BR slapd-shell (5)
+backend setup works, but these refer to the tcl procs in the
+`scriptpath' script that handle them.
+.TP
+.B tclrealm <interpreter name>
+This is one of the biggest pluses of using the tcl backend.
+The realm lets you group several databases to the same interpreter.
+This basically means they share the same global variables and proc space.
+So global variables, as well as all the procs, are callable between databases.
+If no tclrealm is specified, it is put into the "default" realm.
+.SH "Variables passed to the procs"
+.TP
+.B abandon { action msgid suffix }
+.nf
+  action - Always equal to ABANDON.
+  msgid  - The msgid of this ldap operation.
+  suffix - List of suffix(es) associated with the
+           call.  Each one is an entry in a tcl
+           formatted list (surrounded by {}'s).
+.fi
+.TP
+.B add { action msgid suffix entry }
+.nf
+  action - Always equal to ADD.
+  msgid  - The msgid of this ldap operation.
+  suffix - List of suffix(es), as above.
+  entry  - Full entry to add. Each "type: val" is
+           an element in a tcl formatted list.
+.fi
+.TP
+.B bind { action msgid suffix dn method cred_len cred }
+.nf
+  action   - Always equal to BIND.
+  msgid    - The msgid of this ldap operation.
+  suffix   - List of suffix(es), as above.
+  dn       - DN being bound to.
+  method   - One of the ldap authentication methods.
+  cred_len - Length of cred.
+  cred     - Credentials being used to authenticate,
+             according to RFC.  If this value is empty,
+             then it should be considered an anonymous
+             bind (??)
+.fi
+.TP
+.B compare { action msgid suffix dn ava_type ava_value }
+.nf
+  action    - Always equal to COMPARE.
+  msgid     - The msgid of this ldap operation.
+  suffix    - List of suffix(es), as above.
+  dn        - DN for compare.
+  ava_type  - Type for comparison.
+  ava_value - Value to compare.
+.fi
+.TP
+.B delete { action msgid suffix dn }
+.nf
+  action    - Always equal to DELETE.
+  msgid     - The msgid of this ldap operation.
+  suffix    - List of suffix(es), as above.
+  dn        - DN to delete.
+.fi
+.TP
+.B modify { action msgid suffix dn mods }
+.nf
+  action - Always equal to MODIFY.
+  msgid  - The msgid of this ldap operation.
+  suffix - List of suffix(es), as above.
+  dn     - DN to modify.
+  mods   - Tcl list of modifications.
+           The list is formatted in this way:
+
+           {
+             { {op: type} {type: val} }
+             { {op: type} {type: val} {type: val} }
+             ...
+           }
+
+           Newlines are not present in the actual var,
+           they are present here for clarification.
+           "op" is the type of modification
+           (ADD, DELETE, REPLACE).
+.fi
+.TP
+.B modrdn { action msgid suffix dn newrdn deleteoldrdn }
+.nf
+  action - Always equal to MODRDN.
+  msgid  - The msgid of this ldap operation.
+  suffix - List of suffix(es), as above.
+  dn     - DN whose RDN is being renamed.
+  newrdn - New RDN.
+  deleteoldrdn - Boolean stating whether or not the
+           old RDN should be removed after being renamed.
+.fi
+.TP
+.B search { action msgid suffix base scope deref sizelimit timelimit filterstr attrsonly attrlist }
+.nf
+  action    - Always equal to SEARCH.
+  msgid     - The msgid of this ldap operation.
+  suffix    - List of suffix(es), as above.
+  base      - Base for this search.
+  scope     - Scope of search, ( 0 | 1 | 2 ).
+  deref     - Alias dereferencing ( 0 | 1 | 2 | 3 ).
+  sizelimit - Maximum number of entries to return.
+  timelimit - Time limit for search.
+  filterstr - Filter string as sent by the requester.
+  attrsonly - Boolean for whether to list only the
+              attributes, and not values as well.
+  attrlist  - Tcl list if to retrieve.
+.fi
+.TP
+.B unbind { action msgid suffix dn }
+.nf
+  action - Always equal to UNBIND.
+  msgid  - The msgid of this ldap operation.
+  suffix - List of suffix(es), as above.
+  dn     - DN to unbind.
+.fi
+.LP
+.SH "Return Method and Syntax"
+There are only 2 return types.
+All procs must return a result to show status of the operation.
+The result is in this form:
+.LP
+.nf
+  { RESULT {code: <integer>} {matched: <partialdn>}
+    {info: <string>} {} }
+.fi
+.LP
+This is best accomplished with this type of tcl code
+.LP
+.nf
+  lappend ret_val "RESULT"
+  lappend ret_val "code: 0"
+  lappend ret_val ""
+  return $ret_val
+.fi
+.LP
+The final empty string (item in list) is necessary to point to the end
+of list.
+The `code', `matched', and `info' values are not necessary, and
+default values are given if not specified.
+The `code' value is usually an LDAP error in decimal notation from
+ldap.h.
+The `info', may be sent back to the client, depending on the
+function.
+In the bind proc, LDAP uses the value of `code' to indicate whether or
+not the authentication is acceptable.
+.LP
+The other type of return is for searches.
+It is similar format to the shell backend return (as is most of the
+syntax here).
+Its format follows:
+.LP
+.nf
+    {dn: o=Company, c=US} {attr: val} {objectclass: val} {}
+    {dn: o=CompanyB, c=US} {attr: val} {objectclass: val} {}
+.fi
+.LP
+Again, newlines are for visual purposes here.
+Also note the {} marking the end of the entry (same effect as a
+newline in ldif format).
+Here is some example code again, showing a full search proc example.
+.LP
+.nf
+  # Note that `args' lets you lump all possible args
+  # into one var, used here for simplicity of example
+  proc ldap:search { args } {
+    # ...perform some operations...
+  
+    lappend ret_val "dn: $rdn,$base"
+    lappend ret_val "objectclass: $objcl"
+    lappend ret_val "sn: $rdn"
+    lappend ret_val "mail: $email"
+    lappend ret_val ""
+    # Now setup the result
+    lappend ret_val "RESULT"
+    lappend ret_val "code: 0"
+    lappend ret_val ""
+    return $ret_val
+  }
+.fi
+.LP
+NOTE: Newlines in the return value is acceptable in search entries
+(i.e. when returning base64 encoded binary entries).
+.LP
+.SH "Builtin Commands and Variables"
+.TP
+.B ldap:debug <msg>
+Allows you to send debug messages through OpenLDAP's native debugging
+system, this is sent as a LDAP_DEBUG_ANY and will be logged.
+Useful for debugging scripts or logging bind failures.
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8),
+.BR Tcl (3tcl).
index 827134160f5d734c710fa140e2a9a5ebe510f326..1ad79e00415691611ca31b71d7720421fefbcee8 100644 (file)
@@ -1,4 +1,4 @@
-.TH SLAPD.CONF 5 "26 January 2002" "OpenLDAP LDVERSION"
+.TH SLAPD.CONF 5 "28 April 2002" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2002 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .\" $OpenLDAP$
@@ -56,12 +56,11 @@ backslash character (`\\'), the character should be preceded by a
 backslash character.
 .LP
 The specific configuration options available are discussed below in the
-Global Configuration Options, General Backend Options, General Database
-Options, LDBM Database-Specific Options,
-Shell Database-Specific Options, and Password
-Database-Specific Options sections.  Refer to the "OpenLDAP
-Administrator's Guide" for more details on the slapd configuration
-file.
+Global Configuration Options, General Backend Options, and General Database
+Options.  Backend-specific options are discussed in the
+.B slapd-<backend>(5)
+manual pages.  Refer to the "OpenLDAP Administrator's Guide" for more
+details on the slapd configuration file.
 .SH GLOBAL CONFIGURATION OPTIONS
 Options described in this section apply to all backends, unless specifically 
 overridden in a backend definition. Arguments that should be replaced by 
@@ -787,7 +786,11 @@ depending on which backend will serve the database.
 .SH GENERAL DATABASE OPTIONS
 Options in this section only apply to the configuration file section
 for the database in which they are defined.  They are supported by every
-type of backend.
+type of backend.  Note that the
+.B database
+and at least one
+.B suffix
+option are mandatory for each database.
 .TP
 .B database <databasetype>
 Mark the beginning of a new database instance definition. <databasetype>
@@ -941,195 +944,11 @@ Specify the referral to pass back when
 .BR slapd (8)
 is asked to modify a replicated local database.
 If specified multiple times, each url is provided.
-.\" .SH LDBM BACKEND-SPECIFIC OPTIONS
-.\" Options in this category only apply to the LDBM backend. That is,
-.\" they must follow "backend ldbm" line and come before any subsequent
-.\" "backend" or "database" lines.  The LDBM backend is a high-performance
-.\" database that makes extensive use of indexing and caching to speed
-.\" data access. 
-.SH BDB DATABASE-SPECIFIC OPTIONS
-Options in this category only apply to the BDB databases. That is,
-they must follow "database bdb" line and come before any subsequent
-"backend" or "database" lines.
-.TP
-.B cachesize <integer>
-Specify the size in entries of the in-memory cache maintained 
-by the BDB backend database instance.  The default is 1000 entries.
-.TP
-.B checkpoint <kbyte> <min>
-Specify the frequency for checkpointing the database transaction log.
-A checkpoint operation flushes the database buffers to disk and writes
-a checkpoint record in the log. The checkpoint will occur if either
-<kbyte> data has been written or <min> minutes have passed since the
-last checkpoint. Both arguments default to zero, in which case they are ignored.
-See the Berkeley DB reference guide for more details.
-.TP
-.B dbnosync
-Specify that on-disk database contents should not be immediately
-synchronized with in memory changes.  Enabling this option may improve
-performance at the expense of data security.
-.TP
-.B directory <directory>
-Specify the directory where the BDB files containing this database and
-associated indexes live.  A separate directory must be specified for
-each database.  The default is
-.BR LOCALSTATEDIR/openldap-data .
-.TP
-.B dirtyread
-Allow reads of modified but not yet committed data. Usually transactions
-are isolated to prevent other operations from accessing uncommitted data.
-This option may improve performance, but may also return inconsistent
-results if the data comes from a transaction that is later aborted. In
-this case, the modified data is discarded and a subsequent search will
-return a different result.
-.TP
-.B
-index {<attrlist>|default} [pres,eq,approx,sub,<special>]
-See the description for LDBM.
-.TP
-.B lockdetect {oldest|youngest|fewest|random|default}
-Specify which transaction to abort when a deadlock is detected. The
-default is the same as
-.BR random .
-.TP
-.B mode <integer>
-Specify the file protection mode that newly created database 
-index files should have.  The default is 0600.
-
-.SH LDBM DATABASE-SPECIFIC OPTIONS
-Options in this category only apply to the LDBM databases. That is,
-they must follow "database ldbm" line and come before any subsequent
-"backend" or "database" lines.
-.TP
-.B cachesize <integer>
-Specify the size in entries of the in-memory cache maintained 
-by the LDBM backend database instance.  The default is 1000 entries.
-.TP
-.B dbcachesize <integer>
-Specify the size in bytes of the in-memory cache associated 
-with each open index file. If not supported by the underlying database 
-method, this option is ignored without comment.  The default is 100000 bytes.
-.TP
-.B dbnolocking
-Specify that no database locking should be performed.  
-Enabling this option may improve performance at the expense of data security.
-Do NOT run any slap tools while slapd is running.
-.TP
-.B dbnosync
-Specify that on-disk database contents should not be immediately
-synchronized with in memory changes.  Enabling this option may improve
-performance at the expense of data security.
-.TP
-.B dbsync <frequency> <maxdelays> <delayinterval>
-Flush dirty database buffers to disk every
-.B <seconds>
-seconds.  Implies
-.B dbnosync
-(ie. indvidual updates are no longer written to disk).  It attempts to avoid
-syncs during periods of peak activity by waiting
-.B <delayinterval>
-seconds if the server is busy, repeating this delay up to
-.B <maxdelays>
-times before proceeding.  
-It is an attempt to provide higher write performance with some amount of data
-security.  Note that it may still be possible to get an inconsistent 
-database if the underlying engine fills its cache and writes out individual
-pages and slapd crashes or is killed before the next sync.
-.B <maxdelays>
-and
-.B <delayinterval>
-are optional and default to
-.B 12
-and
-.B 5
-respectively, giving a total elapsed delay of 60 seconds before a sync
-will occur.
-.B <maxdelays>
-may be zero, and
-.B <delayinterval>
-must be 1 or greater.
-.TP
-.B directory <directory>
-Specify the directory where the LDBM files containing this database and
-associated indexes live.  A separate directory must be specified for
-each database.  The default is
-.BR LOCALSTATEDIR/openldap-data .
-.TP
-.B
-index {<attrlist>|default} [pres,eq,approx,sub,<special>]
-Specify the indexes to maintain for the given attribute (or
-list of attributes).  Some attributes only support a subset
-of indexes.  If only an <attr> is given, the indices specified
-for \fBdefault\fR are maintained.  Note that setting a default
-does not imply that all attributes will be indexed.
-
-A number of special index parameters may be
-specified.
-The index type
-.B sub
-can be decomposed into
-.BR subinitial ,
-.BR subany ,\ and
-.B subfinal
-indices.
-The special type
-.B nolang
-may be specified to disallow use of this index by language subtypes.
-The special type
-.B nosubtypes
-may be specified to disallow use of this index by named subtypes.
-Note: changing index settings requires rebuilding indices, see
-.BR slapindex (8).
-.TP
-.B mode <integer>
-Specify the file protection mode that newly created database 
-index files should have.  The default is 0600.
-.SH SHELL DATABASE-SPECIFIC OPTIONS
-Options in this category only apply to the SHELL backend database. That is,
-they must follow a "database shell" line and come before any subsequent
-"backend" or "database" lines.  The Shell backend executes external programs to
-implement operations, and is designed to make it easy to tie an existing
-database to the
-.B slapd
-front-end.
-.TP
-.B bind <pathname>
-.TP
-.B unbind <pathname>
-.TP
-.B search <pathname>
-.TP
-.B compare <pathname>
-.TP
-.B modify <pathname>
-.TP
-.B modrdn <pathname>
-.TP
-.B add <pathname>
-.TP
-.B delete <pathname>
-.TP
-.B abandon <pathname>
-These options specify the pathname of the command to execute in response 
-to the given LDAP operation.
-
-Note that you need only supply configuration lines for those commands you
-want the backend to handle. Operations for which a command is not
-supplied will be refused with an "unwilling to perform" error.
-.SH PASSWORD DATABASE-SPECIFIC OPTIONS
-Options in this category only apply to the PASSWD backend database.
-That is, they must follow a "database passwd" line and come before any
-subsequent "backend" or "database" lines.  The PASSWD database serves up the user
-account information listed in the system
-.BR passwd (5)
-file.
-.TP
-.B file <filename>
-Specifies an alternate passwd file to use.  The default is
-.B /etc/passwd.
-.SH OTHER DATABASE-SPECIFIC OPTIONS
-Other databases may allow specific configuration options; they will be
-documented separately since most of these databases are very specific
+.SH DATABASE-SPECIFIC OPTIONS
+Each database may allow specific configuration options; they will be
+documented separately in the
+.B slapd-<backend>(5)
+manual pakges since most of these databases are very specific
 or experimental.
 .SH EXAMPLE
 "OpenLDAP Administrator's Guide" contains an annotated
@@ -1138,10 +957,18 @@ example of a configuration file.
 ETCDIR/slapd.conf
 .SH SEE ALSO
 .BR ldap (3),
+.BR slapd-bdb (5),
+.BR slapd-ldbm (5),
+.BR slapd-meta (5),
+.BR slapd-null (5),
+.BR slapd-passwd (5),
+.BR slapd-perl (5),
+.BR slapd-shell (5),
+.BR slapd-sql (5),
+.BR slapd-tcl (5),
 .BR slapd.replog (5),
 .BR slapd.access (5),
 .BR locale (5),
-.BR passwd (5),
 .BR slapd (8),
 .BR slapadd (8),
 .BR slapcat (8),
index 4a92d7aad4c324feb46f136c7ca0dd7fdd54b09a..842aade8e40c7724f6033c793e6d463a489ef7d1 100644 (file)
@@ -169,7 +169,7 @@ on voluminous debugging which will be printed on standard error, type:
 .LP
 .nf
 .ft tt
-       LIBEXECDIR/slapd -f ETCDIR/slapd.conf -d 255
+       LIBEXECDIR/slapd -f /var/tmp/slapd.conf -d 255
 .ft
 .fi
 .LP
index f059bd702d18c9ca5be09034c6b68a0885e3e23a..c8fa38695cbdea5af806da63427244429b28471a 100644 (file)
@@ -1,397 +1,2 @@
-/******************************************************************************
- *
- * Copyright (C) 2000 Pierangelo Masarati, <ando@sys-net.it>
- * All rights reserved.
- *
- * 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.
- *
- ******************************************************************************/
-
-/*
- * Description
- *
- *      A string is rewritten according to a set of rules, called
- *     a `rewrite context'.
- *      The rules are based on Regular Expressions (POSIX regex) with
- *      substring matching; extensions are planned to allow basic variable
- *      substitution and map resolution of substrings.
- *      The behavior of pattern matching/substitution can be altered by a
- *      set of flags.
- *
- *      The underlying concept is to build a lightweight rewrite module
- *      for the slapd server (initially dedicated to the back-ldap module).
- *
- *
- * Passes
- *
- *      An incoming string is matched agains a set of rules. Rules are made
- *      of a match pattern, a substitution pattern and a set of actions.
- *     In case of match a string rewriting is performed according to the
- *     substitution pattern that allows to refer to substrings matched
- *     in the incoming string. The actions, if any, are finally performed.
- *     The substitution pattern allows map resolution of substrings.
- *     A map is a generic object that maps a substitution pattern to a
- *     value.
- *
- *
- * Pattern Matching Flags
- *
- *      'C'     honors case in matching (default is case insensitive)
- *      'R'     use POSIX Basic Regular Expressions (default is Extended)
- *
- *
- * Action Flags
- *
- *      ':'     apply the rule once only (default is recursive)
- *      '@'     stop applying rules in case of match.
- *      '#'     stop current operation if the rule matches, and issue an
- *              `unwilling to perform' error.
- *      'G{n}'  jump n rules back and forth (watch for loops!). Note that
- *             'G{1}' is implicit in every rule.
- *      'I'    ignores errors in rule; this means, in case of error, e.g.
- *             issued by a map, the error is treated as a missed match.
- *             The 'unwilling to perform' is not overridden.
- *
- *     the ordering of the flags is significant. For instance:
- *
- *     'IG{2}' means ignore errors and jump two lines ahead both in case
- *             of match and in case of error, while
- *     'G{2}I' means ignore errors, but jump thwo lines ahead only in case
- *             of match.
- *
- *     More flags (mainly Action Flags) will be added as needed.
- *
- *
- * Pattern matching: 
- *
- *      see regex(7)
- *
- *
- * String Substitution:
- *
- *      the string substitution happens according to a substitution pattern.
- *      -       susbtring substitution is allowed with the syntax '\d'
- *              where 'd' is a digit ranging 0-9 (0 is the full match).
- *             I see that 0-9 digit expansion is a widely accepted
- *             practise; however there is no technical reason to use
- *             such a strict limit. A syntax of the form '\{ddd}'
- *             should be fine if there is any need to use a higher
- *             number of possible submatches.
- *      -       variable substitution will be allowed (at least when I
- *              figure out which kind of variable could be proficiently
- *              substituted)
- *      -       map lookup will be allowed (map lookup of substring matches
- *              in gdbm, ldap(!), math(?) and so on maps 'a la sendmail'.
- *      -       subroutine invocation will make it possible to rewrite a
- *              submatch in terms of the output of another rewriteContext
- *
- *     Old syntax:
- *
- *             '\' {0-9} [ '{' <name> [ '(' <args> ')' ] '}' ]
- *
- *             where <name> is the name of a built-in map, and
- *             <args> are optional arguments to the map, if
- *             the map <name> requires them.
- *             The following experimental maps have been implemented:
- *
- *     \n{xpasswd}
- *                     maps the n-th substring match as uid to 
- *                     the gecos field in /etc/passwd;
- *
- *     \n{xfile(/absolute/path)}
- *                     maps the n-th substring match 
- *                     to a 'key value' style plain text file.
- *
- *     \n{xldap(ldap://url/with?%0?in?filter)
- *                     maps the n-th substring match to an
- *                     attribute retrieved by means of an LDAP
- *                     url with substitution of %0 in the filter
- *                     (NOT IMPL.)
- *
- *     New scheme:
- *
- *     -       everything starting with '\' requires substitution;
- *     -       the only obvious exception is '\\', which is left as is;
- *     -       the basic substitution is '\d', where 'd' is a digit;
- *             0 means the whole string, while 1-9 is a submatch;
- *     -       in the outdated schema, the digit may be optionally
- *             followed by a '{', which means pipe the submatch into
- *             the map described by the string up to the following '}';
- *     -       the output of the map is used instead of the submatch;
- *     -       in the new schema, a '\' followed by a '{' invokes an
- *             advanced substitution scheme. The pattern is:
- *
- *             '\' '{' [{ <op> }] <name> '(' <substitution schema> ')' '}'
- *
- *             where <name> must be a legal name for the map, i.e.
- *             
- *             <name> ::= [a-z][a-z0-9]* (case insensitive)
- *             <op> ::= '>' '|' '&' '&&' '*' '**' '$'
- *
- *             and <substitution schema> must be a legal substitution
- *             schema, with no limits on the nesting level.
- *             The operators are:
- *             >       sub context invocation; <name> must be a legal,
- *                     already defined rewrite context name
- *             |       external command invocation; <name> must refer
- *                     to a legal, already defined command name (NOT IMPL.)
- *             &       variable assignment; <name> defines a variable
- *                     in the running operation structure which can be
- *                     dereferenced later (NOT IMPL.)
- *             *       variable dereferencing; <name> must refer to a
- *                     variable that is defined and assigned for the
- *                     running operation (NOT IMPL.)
- *             $       parameter dereferencing; <name> must refer to
- *                     an existing parameter; the idea is to make
- *                     some run-time parameters set by the system
- *                     available to the rewrite engine, as the client
- *                     host name, the bind dn if any, constant
- *                     parameters initialized at config time, and so
- *                     on (NOT IMPL.)
- *
- *     Note: as the slapd parsing routines escape backslashes ('\'),
- *     a double backslash is required inside substitution patterns.
- *     To overcome the resulting heavy notation, the substitution escaping
- *     has been delegated to the '%' symbol, which should be used 
- *     instead of '\' in string substitution patterns. The symbol can
- *     be altered at will by redefining the related macro in "rewrite-int.h".
- *     In the current snapshot, all the '\' on the left side of each rule
- *     (the regex pattern) must be converted in '\\'; all the '\' on the
- *     right side of the rule (the substitution pattern) must be turned
- *     into '%'. In the following examples, the original (more readable)
- *     syntax is used; however, in the servers/slapd/back-ldap/slapd.conf
- *     example file, the working syntax is used.
- *
- *
- *
- * Rewrite context:
- *
- *     a rewrite context is a set of rules which are applied in sequence.
- *     The basic idea is to have an application initialize a rewrite
- *     engine (think of Apache's mod_rewrite ...) with a set of rewrite
- *     contexts; when string rewriting is required, one invokes the
- *     appropriate rewrite context with the input string and obtains the
- *     newly rewritten one if no errors occur.
- *     
- *     An interesting application, in back-ldap or in slapd itself,
- *     could associate each basic server operation to a rewrite context
- *     (most of them possibly aliasing the default one). Then, DN rewriting
- +     could take place at any invocation of a backend operation.
- *
- *     client -> server:
- *             default         if defined and no specific context is available
- *             bindDn          bind
- *             searchBase      search
- *             searchFilter    search
- *             compareDn       compare
- *             addDn           add
- *             modifyDn        modify
- *             modrDn          modrdn
- *             newSuperiorDn   modrdn
- *             deleteDn        delete
- *
- *     server -> client:
- *             searchResult    search (only if defined; no default)
- *
- *
- * Configuration syntax:
- *
- *             Basics:
- *
- *     rewriteEngine   { on | off }
- *
- *     rewriteContext  <context name> [ alias <aliased context name> ]
- *
- *     rewriteRule     <regex pattern> <substitution pattern> [ <flags> ]
- *
- *
- *             Additional:
- *
- *     rewriteMap      <map name> <map type> [ <map attrs> ]
- *
- *     rewriteParam    <param name> <param value>
- *
- *     rewriteMaxPasses <number of passes>
- *
- *
- *
- *     rewriteEngine:
- *
- *     if 'on', the requested rewriting is performed; if 'off', no
- *     rewriting takes place (an easy way to stop rewriting without
- *     altering too much the configuration file)
- *
- *     rewriteContext:
- *
- *     <context name> is the name that identifies the context, i.e.
- *     the name used by the application to refer to the set of rules
- *     it contains. It is used also to reference sub contexts in
- *     string rewriting. A context may aliase another one. In this
- *     case the alias context contains no rule, and any reference to
- *     it will result in accessing the aliased one.
- *
- *     rewriteRule:
- *
- *     determines how a tring can be rewritten if a pattern is matched.
- *     Examples are reported below.
- *
- *     rewriteMap:
- *
- *     allows to define a map that transforms substring rewriting into
- *     something else. The map is referenced inside the substitution
- *     pattern of a rule.
- *
- *     rewriteParam:
- *
- *     sets a value with global scope, that can be dereferenced by the
- *     command '\{$paramName}'.
- *
- *     rewriteMaxPasses:
- *
- *     sets the maximum number of total rewriting passes taht can be
- *     performed in a signle rewriting operation (to avoid loops).
- *
- *
- * Configuration examples:
- *
- *     # set to 'off' to disable rewriting
- *
- *     rewriteEngine   on
- *
- *
- *     # everything defined here goes into the 'default' context
- *     # this rule changes the naming context of anything sent to
- *     # 'dc=home,dc=net' to 'dc=OpenLDAP, dc=org'
- *
- *     rewriteRule     "(.*)dc=home,[ ]?dc=net" "\1dc=OpenLDAP, dc=org" ":"
- *
- *
- *     # start a new context (ends input of the previous one)
- *     # this rule adds blancs between dn parts if not present.
- *
- *     rewriteContext  addBlancs
- *     rewriteRule     "(.*),([^ ].*)" "\1, \2"
- *
- *
- *     # this one eats blancs
- *
- *     rewriteContext  eatBlancs
- *     rewriteRule     "(.*),[ ](.*)" "\1,\2"
- *
- *
- *     # here control goes back to the default rewrite context; rules are
- *     # appended to the existing ones.
- *     # anything that gets here is piped into rule 'addBlancs'
- *
- *     rewriteContext  default
- *     rewriteRule     ".*" "\{>addBlancs(\0)}" ":"
- *
- *
- *     # anything with 'uid=username' gets looked up in /etc/passwd for
- *     # gecos (I know it's nearly useless, but it is there just to
- *     # test something fancy!). Note the 'I' flag that leaves
- *     # 'uid=username' in place if 'username' does not have a valid
- *     # account. Note also the ':' that forces the rule to be processed
- *     # exactly once.
- *
- *     rewriteContext  uid2Gecos
- *     rewriteRule     "(.*)uid=([a-z0-9]+),(.+)" "\1cn=\2{xpasswd},\3" "I:"
- *
- *
- *     # finally, in case of bind, if one uses a 'uid=username' dn,
- *     # it is rewritten in 'cn=name surname' if possible.
- *
- *     rewriteContext  bindDn
- *     rewriteRule     ".*" "\{>addBlancs(\{>uid2Gecos(\0)})}" ":"
- *
- *
- *     # the search base is rewritten according to 'default' rules
- *
- *     rewriteContext  searchBase alias default
- *
- *
- *     # search results with OpenLDAP dn are rewritten back with
- *     # 'dc=home,dc=net' naming context, with spaces eaten.
- *
- *     rewriteContext  searchResult
- *     rewriteRule     "(.*[^ ]?)[ ]?dc=OpenLDAP,[ ]?dc=org" 
- *             "\{>eatBlancs(\1)}dc=home,dc=net" ":"
- *
- *     # bind with email instead of full dn: we first need an ldap map
- *     # that turns attributes into a dn (the filter is provided by the
- *     # substitution string):
- *
- *     rewriteMap      ldap attr2dn "ldap://host/dc=my,dc=org?dn?sub"
- *     
- *     # then we need to detect emails; note that the rule in case of match
- *     # stops rewriting; in case of error, it is ignored.
- *     # In case we are mapping virtual to real naming contexts, we also
- *     # need to rewrite regular dns, because the definition of a bindDn
- *     # rewrite context overrides the default definition.
- *
- *     rewriteContext bindDn
- *     rewriteRule     "(mail=[^,]+@[^,]+)" "\{attr2dn(\1)}" "@I"
- *
- *     # This is a rather sophisticate example. It massages a search filter
- *     # in case who performs the search has administrative privileges.
- *     # First we need to keep track of the bind dn of the incoming request:
- *
- *     rewriteContext  bindDn
- *     rewriteRule     ".+" "\{**&binddn(\0)}" ":"
- *
- *     # a search filter containing 'uid=' is rewritten only if an
- *     # appropriate dn is bound.
- *     # to do this, in the first rule the bound dn is dereferenced, while
- *     # the filter is decomposed in a prefix, the argument of the 'uid=',
- *     # and in a suffix. A tag '<>' is appended to the dn. If the dn 
- *     # refers to an entry in the 'ou=admin' subtree, the filter is
- *     # rewritten OR-ing the 'uid=<arg>' with 'cn=<arg>'; otherwise
- *     # it is left as is. This could be useful, for instance, to allow
- *     # apache's auth_ldap-1.4 module to authenticate users with both
- *     # 'uid' and 'cn', but only if the request comes from a possible
- *     # 'dn: cn=Web auth, ou=admin, dc=home, dc=net' user.
- *
- *     rewriteContext  searchFilter
- *     rewriteRule     "(.*\()uid=([a-z0-9_]+)(\).*)"
- *             "\{**binddn}<>\{&prefix(\1)}\{&arg(\2)}\{&suffix(\3)}" ":I"
- *     rewriteRule     "[^,]+,[ ]?ou=admin,[ ]?dc=home,[ ]?dc=net"
- *             "\{*prefix}|(uid=\{*arg})(cn=\{*arg})\{*suffix}" "@I"
- *     rewriteRule     ".*<>" "\{*prefix}uid=\{*arg}\{*suffix}"
- *
- *
- * LDAP Proxy resolution (a possible evolution of the back-ldap):
- *
- *     in case the rewritten dn is an LDAP URL, the operation is initiated
- *     towards the host[:port] indicated in the url, if it does not refer
- *     to the local server.
- *
- *     e.g.:
- *
- *     rewriteRule     '^cn=root,.*'   '\0'                            'G{3}'
- *     rewriteRule     '^cn=[a-l].*'   'ldap://ldap1.my.org/\0'        '@'
- *     rewriteRule     '^cn=[m-z].*'   'ldap://ldap2.my.org/\0'        '@'
- *     rewriteRule     '.*'            'ldap://ldap3.my.org/\0'        '@'
- *
- *     (rule 1 is simply there to illustrate the 'G{n}' action; it could
- *     have been written:
- *
- *     rewriteRule     '^cn=root,.*'   'ldap://ldap3.my.org/\0'        '@'
- *
- *     with the advantage of saving one rewrite pass ...)
- */
-
+The workings of the rewrite library are described in the
+REWRITING section of the slapd-meta(5) manual page.
index 6bbcd0e5a375709548aa5d74b91a2a43f4c13de1..c6a8f9ea5dd0fcbcf571c01ce299e2421ff00bb3 100644 (file)
-
-=head1 Introduction
-
-This is a sample Perl module for the OpenLDAP server slapd.
-It also contains the documentation that you will need to
-get up and going.
-
-WARNING: the interfaces of this backen to the perl module
-MAY change.  Any suggestions would greatly be appreciated.
-
-
-=head1 Overview
-
-The Perl back end works by embedding a Perl interpreter into
-the slapd backend. Then when the configuration file indicates
-that we are going to be using a Perl backend it will get an
-option that tells it what module to use.  It then creates a 
-new Perl object that handles all the request for that particular
-instance of the back end.
-
-
-=head1 Interface
-
-You will need to create a method for each one of the
-following actions that you wish to handle.
-
-   * new        # Creates a new object.
-   * search     # Performs the ldap search
-   * compare    # does a compare
-   * modify     # modify's and entry
-   * add        # adds an entry to back end
-   * modrdn     # modifies a an entries rdn
-   * delete     # deletes an ldap entry
-   * config     # process unknown config file lines
-   * init       # called after backend is initialized
-
-=head2 new
-
-This method is called when the config file encounters a 
-B<perlmod> line. The module in that line is then effectively
-used into the perl interpreter, then the new method is called
-to create a new object.  Note that multiple instances of that
-object may be instantiated, as with any perl object.
-
-The new method doesn't receive any arguments other than the
-class name.
-
-RETURN: 
-
-=head2 search
-
-This method is called when a search request comes from a client.
-It arguments are as follow.
-
-  * obj reference
-  * base DN
-  * scope
-  * alias deferencing policy
-  * size limit
-  * time limit
-  * filter string
-  * attributes only flag ( 1 for yes )
-  * list of attributes that are to be returned. (could be empty)
-
-RETURN:
-
-=head2 compare
-
-This method is called when a compare request comes from a client.
-Its arguments are as follows.
-
-  * obj reference
-  * dn
-  * attribute assertion string
-
-RETURN:
-
-=head2 modify
-
-This method is called when a modify request comes from a client.
-Its arguments are as follows.
-
-  * obj reference
-  * dn
-  * lists formatted as follows
-   { ADD | DELETE | REPLACE }, key, value
-
-RETURN:
-
-=head2 add
-
-This method is called when a add request comes from a client.
-Its arguments are as follows.
-
-  * obj reference
-  * entry in string format.
-
-RETURN:
-
-=head2 modrdn
-
-This method is called when a modrdn request comes from a client.
-Its arguments are as follows.
-
-  * obj reference
-  * dn
-  * new rdn
-  * delete old dn flage ( 1 means yes )
-
-RETURN:
-
-=head2 delete
-
-This method is called when a delete request comes from a client.
-Its arguments are as follows.
-
-  * obj reference
-  * dn
-
-RETURN:
-
-=head2 config
-
-  * obj reference
-  * arrray of arguments on line
-
-RETURN: non zero value if this is not a valid option.
-
-=head2 init
-
-  * obj reference
-
-RETURN: non zero value if initialization failed.
-
-=head1 Configuration
-
-The perl section of the config file recognizes the following 
-options.  It should also be noted that any option not recoginized
-will be sent to the B<config> method of the perl module as noted
-above.
-
-  database perl         # startn section for the perl database
-
-  suffix          "o=AnyOrg, c=US"
-
-  perlModulePath /path/to/libs  # addes the path to @INC variable same
-                             # as "use lib '/path/to/libs'"
-
-  perlModule ModName       # use the module name ModName from ModName.pm
-
-  filterSearchResults      # search results are candidates that need to be
-                           # filtered, rather than search results to be 
-                           # returned directly to the client
-
-=cut
+# This is a sample Perl module for the OpenLDAP server slapd.
+#
+# $OpenLDAP$
+#
+# Usage: Add something this to slapd.conf:
+#
+#      database        perl
+#      suffix          "o=AnyOrg, c=US"
+#      perlModulePath  /path/to/this/file
+#      perlModule      SampleLDAP
 
 package SampleLDAP;
 
@@ -169,6 +24,11 @@ sub new
        return $this;
 }
 
+sub init
+{
+       return 0;
+}
+
 sub search
 {
        my $this = shift;
@@ -247,7 +107,7 @@ sub add
        my ( $dn ) = ( $entryStr =~ /dn:\s(.*)$/m );
 
        #
-       # This needs to be here untill a normalize dn is
+       # This needs to be here until a normalized dn is
        # passed to this routine.
        #
        $dn = uc( $dn );
@@ -296,5 +156,3 @@ sub config
 }
 
 1;
-
-
index 4d9303da7c27453fb3460e48728f09646fa96b79..ed2904762f06496a5d1f41e3c1dcc8a1c541f384 100644 (file)
@@ -1,257 +1 @@
-CONTENT
-1. Purpose
-2. Metainformation used
-3. Typical back-sql operation
-4. Several important common techniques (referrals, multiclassing)
-
-1. Purpose
-Primary purpose of this backend is to PRESENT information stored in some RDBMS
-as an LDAP subtree without any programming (some SQL and maybe stored
-procedures can't be considered programming, anyway ;).
-
-That is, for example, when you (some ISP) have account
-information you use in RDBMS, and want to use modern solutions that expect such
-information in LDAP (to authenticate users, make email lookups etc.).
-Or you want to syncronize or distribute information between different
-sites/applications that use RDBMSes and/or LDAP. Or whatever else...
-
-It is NOT designed as general-purpose backend that uses RDBMS instead of
-BerkeleyDB (as standard back-ldbm does), though it can be used as such
-with several limitations. You can take a look at
-http://www.openldap.org/faq/index.cgi?file=378 
-(OpenLDAP FAQ-O-Matic/General LDAP FAQ/Directories vs. conventional databases)
-to find out more on this point.
-
-The idea (detailed below) is to use some metainformation to translate
-LDAP queries to SQL queries, leaving relational schema untouched, so that
-old applications can continue using it without any modifications. This allows
-SQL and LDAP applications to interoperate without replication, and exchange
-data as needed.
-
-Back-sql is designed to be tunable to virtually any relational schema without
-having to change source (through that metainformation mentioned).
-Also, it uses ODBC to connect to RDBMSes, and is highly configurable for
-SQL dialects RDBMSes may use, so it may be used for integration and 
-distribution of data on different RDBMSes, OSes, hosts etc., in other words,
-in highly heterogeneous environment.
-
-2. Metainformation used
-***
-Almost everything mentioned later is illustrated in example, which is located
-in backsql/rdbms_depend directory, and contains scripts for generating sample
-database for Oracle,MS SQL Server and mySQL.
-***
-First thing that one must arrange for himself is what set of LDAP 
-objectclasses can present your RDBMS information.
-
-The easiest way is to create objectclass for each entity you had
-in ER-diagram when designing your relational schema.
-Any relational schema, no matter how normalized it is, was designed after
-some model of your applications domain (for instance, accounts, services etc.
-in ISP), and is used in terms of its entities, not just tables of normalized
-schema.
-It means that for every attribute of every such instance there is an effective
-SQL query that loads it's values.
-
-Also you might want your objectclasses to conform to some of standard schemas
-like inetOrgPerson etc..
-
-Nevertheless, when you think it out, we must define a way to translate LDAP
-operation requests to (series of) SQL queries. Let us deal with SEARCH 
-operation.
-
-Example:
-Lets suppose that we store information about persons working in our 
-organization in two tables:
-
-PERSONS                PHONES
-----------           -------------
-id integer             id integer
-first_name varchar      pers_id integer references persons(id)
-last_name varchar       phone
-middle_name varchar
-...
-
-(PHONES contains telephone numbers associated with persons). A person can have
-several numbers, then PHONES contains several records with corresponding 
-pers_id, or no numbers (and no records in PHONES with such pers_id). LDAP
-objectclass to present such information could look like this:
-person
--------
-MUST cn
-MAY telephoneNumber
-MAY firstName
-MAY lastName
-...
-
-To fetch all values for cn attribute given person ID, we construct the query:
-SELECT CONCAT(persons.first_name,' ',persons.last_name) as cn FROM persons WHERE persons.id=?
-
-for telephoneNumber we can use:
-SELECT phones.phone as telephoneNumber FROM persons,phones WHERE persons.id=phones.pers.id and persons.id=?
-
-If we wanted to service LDAP request with filter like (telephoneNumber=123*),
-we would construct something like:
-SELECT ... FROM persons,phones WHERE persons.id=phones.pers.id and persons.id=? and phones.phone like '123%'
-
-So, if we had information about what tables contain values for each 
-attribute, how to join this tables and arrange these values, we could try
-to automatically generate such statements, and translate search filters
-to SQL WHERE clauses.
-
-To store such information, we add three more tables to our schema, so that
- and fill it with data (see samples):
-
-ldap_oc_mappings (some columns are not listed for clarity)
----------------
-id=1
-name="person"
-keytbl="persons"
-keycol="id"
-
-This table defines mapping between objectclass (its name held in "name" column),
-and table that holds primary key for corresponding entities. For instance,
-in our example, the person entity, which we are trying to present as "person"
-objectclass, resides in two tables (persons and phones), and is identified
-by persons.id column (that we will call primary key for this entity).
-keytbl and keycol thus contain "persons" (name of the table), and "id" (name
-of the column).
-
-ldap_attr_mappings (some columns are not listed for clarity)
------------
-id=1
-oc_id=1
-name="cn"
-sel_expr="CONCAT(persons.first_name,' ',persons.last_name)"
-from_tbls="persons"
-join_where=NULL
-************
-id=<n>
-oc_map_id=1
-name="telephoneNumber"
-sel_expr="phones.phone"
-from_tbls="persons,phones"
-join_where="phones.pers_id=persons.id"
-
-This table defines mappings between LDAP attributes and SQL queries that
-load their values. Note that, unlike LDAP schema, these are not *attribute types*
-- attribute "cn" for "person" objectclass can well have it's values in different
-table than "cn" for other objectclass, so attribute mappings depend on
-objectclass mappings (unlike attribute types in LDAP schema, which are
-indifferent to objectclasses). Thus, we have oc_map_id column with link to
-oc_mappings table. 
-Now we cut the SQL query that loads values for given attribute into 3 parts.
-First goes into sel_expr column - this is the expression we had between
-SELECT and FROM keywords, which defines WHAT to load.
-Next is table list - text between FROM and WHERE keywords. It may contain
-aliases for convenience (see exapmles).
-The last is part of where clause, which (if exists at all) express the
-condition for joining the table containing values wich table containing
-primary key (foreign key equality and such). If values are in the same table
-with primary key, then this column is left NULL (as for cn attribute above).
-
-Having this information in parts, we are able to not only construct queries
-that load attribute values by id of entry (for this we could store SQL query
-as a whole), but to construct queries that load id's of objects that
-correspond to given search filter (or at least part of it).
-See below for examples.
-
-ldap_entries
-------------
-id=1
-dn=<dn you choose>
-oc_map_id=...
-parent=<parent record id>
-keyval=<value of primary key>
-
-This table defines mappings between DNs of entries in your LDAP tree,
-and values of primary keys for corresponding relational data. It has
-recursive structure (parent column references id column of the same table),
-which allows you to add any tree structure(s) to your flat relational data.
-Having id of objectclass mapping, we can determine table and column for
-primary key, and keyval stores value of it, thus defining exact tuple
-corresponding to LDAP entry with this DN.
-
-Note that such design (see exact SQL table creation query) implies one
-important constraint - the key must be integer. But all that I know about
-well-designed schemas makes me think that it s not very narrow ;)
-If anyone needs support for different types for keys - he may want to write
-a patch, and submit it to OpenLDAP ITS, then I'll include it.
-
-Also, several people complained that they don't really need very structured
-tree, and they don't want to update one more table every time they add or
-delete instance in relational schema. Those can use a view instead of real
-table, something like this:
-
-
-Robin Elfrink wrote:
-
-> About using a view for ldap_entries...
->
-> This is what I came up with this morning:
->
-> CREATE VIEW ldap_entries (id, dn, oc_map_id, parent, keyval) AS
->         SELECT (1000000000+userid),
-> UPPER(CONCAT(CONCAT('cn=',gecos),',o=MyCompany,c=NL'))
-> , 1, 0, userid FROM unixusers UNION
->         SELECT (2000000000+groupnummer),
-> UPPER(CONCAT(CONCAT('cn=',groupnaam),',o=MyCompany,c=NL')), 2, 0,
-> groupnummer FROM groups;
->
-
-
-3. Typical back-sql operation
-Having metainformation loaded, back-sql uses these tables to determine a set
-of primary keys of candidates (depending on search scope and filter). It tries
-to do it for each objectclass registered in ldap_objclasses.
-Exapmle:
-for our query with filter (telephoneNumber=123*) we would get following 
-query generated (which loads candidate IDs)
-SELECT ldap_entries.id,persons.id, 'person' AS objectClass, ldap_entries.dn AS dn FROM ldap_entries,persons,phones WHERE persons.id=ldap_entries.keyval AND ldap_entries.objclass=? AND ldap_entries.parent=? AND phones.pers_id=persons.id AND (phones.phone LIKE '123%')
-(for ONELEVEL search)
-or "... AND dn=?" (for BASE search)
-or "... AND dn LIKE '%?'" (for SUBTREE)
-
-Then, for each candidate, we load attributes requested using per-attribute queries
-like
-
-SELECT phones.phone AS telephoneNumber FROM persons,phones WHERE persons.id=? AND phones.pers_id=persons.id
-
-Then, we use test_filter() from frontend API to test entry for full
-LDAP search filter match (since we cannot effectively make sense of SYNTAX
-of corresponding LDAP schema attribute, we translate the filter into most relaxed
-SQL condition to filter candidates), and send it to user.
-
-ADD,DELETE,MODIFY operations also performed on per-attribute metainformation
-(add_proc etc.). In those fields one can specify an SQL statement or stored procedure
-call which can add, or delete given value of given attribute, using given entry
-keyval (see examples -- mostly ORACLE and MSSQL - since there're no stored procs in mySQL).
-
-We just add more columns to oc_m,appings and attr_mappings, holding statements
-to execute (like create_proc, add_proc, del_proc etc.), and flags governing
-order of parameters passed to those statements.
-Please see samples to find out what are the parameters passed, and other
-information on this matter - they are self-explanatory for those familiar
-with concept expressed above.
-
-4. Several common techniques (referrals, multiclassing etc.)
-First of all, lets remember that among other major differences to complete
-LDAP data model, the concept above does not directly support such things
-as multiple objectclasses for entry, and referrals.
-Fortunately, they are easy to adopt in this scheme. Back-sql suggests two more
-tables being added to schema - 
-ldap_entry_objectclasses(entry_id, oc_name), and ldap_referrals (entry_id,url).
-
-First contains any number of objectclass names that corresponding entries
-will be found by, in addition to that mentioned in mapping. Back-sql
-automatically adds attribute mapping for "objectclass" attribute to each objectclass
-mapping, that loads values from this table. So, you may, for instance, have
-mapping for inetOrgPerson, and use it for queries for "person" objectclass...
-
-Second table contains any number of referrals associated with given entry.
-Back-sql automatically adds attribute mapping for "ref" attribute to each
-objectclass mapping, that loads values from this table.
-So, if you add objectclass "referral" to this entry, and make one or more
-tuples in ldap_referrals for this entry (they will be seen as values of "ref"
-attribute), you will have slapd return referral, as described in Administrators
-Guide.
+The SQL backend is described in the slapd-sql(5) manual page.
index 66d53e77c6ee2e670ef8c888b3b244abe5847993..d0112d42409a6acbb87099924193b46f16fab9ab 100644 (file)
@@ -1,206 +1 @@
-Tcl Backend Interface for OpenLDAP
-
-
-----------------------------
-Synopsis of slapd.conf setup
-----------------------------
-
-database       tcl
-suffix          o=Suffix
-
-# The full path to the tcl script used for this database
-scriptpath      /usr/lib/ldap/database.tcl
-
-# The procs for each ldap function. This is similar to how
-# the shell backend setup works, but these refer to
-# the tcl procs in the 'scriptpath' script that handle them
-search          <proc>
-add             <proc>
-delete          <proc>
-modify          <proc>
-bind            <proc>
-unbind          <proc>
-modrdn         <proc>
-compare                <proc>
-abandon                <proc>
-
-# This is one of the biggest pluses of using the tcl backend.
-# The realm lets you group several databases to the same interpreter.
-# This basically means they share the same global variables and proc
-# space. So global variables, as well as all the procs, are callable
-# between databases. If no tclrealm is specified, it is put into the
-# "default" realm.
-tclrealm        <interpreter name>
-
-
------------------------------------------
-Synopsis of variables passed to the procs
------------------------------------------
-
-abandon { action msgid suffix }
-
-       action - Always equal to ABANDON
-       msgid  - The msgid of this ldap session
-       suffix - List of suffix(es) associated with the call. Each one is
-                an entry in a tcl formatted list (surrounded by {}'s)
-
-add { action msgid suffix entry }
-
-       action - Always equal to ADD
-       msgid  - The msgid of this ldap session
-       suffix - List of suffix(es) associated with the call. Each one is
-                an entry in a tcl formatted list (surrounded by {}'s)
-       entry  - Full entry to add. Each "type: val" is an element in a
-                tcl formatted list.
-
-bind { action msgid suffix dn method cred_len cred }
-
-       action   - Always equal to BIND
-       msgid    - The msgid of this ldap session
-       suffix   - List of suffix(es) associated with the call. Each one
-                  is an entry in a tcl formatted list (surrounded by {}'s)
-       dn       - DN being bound to
-       method   - One of the ldap authentication methods
-       cred_len - Length of cred
-       cred     - Credentials being used to authenticate, according to
-                  RFC, if this value is empty, then it should be
-                  considered an anonomous bind (??)
-
-compare { action msgid suffix dn ava_type ava_value }
-
-       action    - Always equal to COMPARE
-       msgid     - The msgid of this ldap session
-       suffix    - List of suffix(es) associated with the call. Each one
-                   is and entry in a tcl formatted list (surrounded by {}'s)
-       dn        - DN for compare
-       ava_type  - Type for comparison
-       ava_value - Value to compare
-
-delete { action msgid suffix dn }
-
-       action    - Always equal to DELETE
-       msgid     - The msgid of this ldap session
-       suffix    - List of suffix(es) associated with the call. Each one
-                   is and entry in a tcl formatted list (surrounded by {}'s)
-       dn        - DN to delete
-
-modify { action msgid suffix dn mods }
-
-       action - Always equal to MODIFY
-       msgid  - The msgid of this ldap session
-       suffix - List of suffix(es) associated with the call. Each one
-                is and entry in a tcl formatted list (surrounded by {}'s)
-       dn     - DN to modify
-       mods   - Tcl list of modifications. List is formatted in this way:
-
-                {
-                  { {op: type} {type: val} }
-                  { {op: type} {type: val} {type: val} }
-                  ...
-                }
-
-                Newlines are not present in the actual var, they are
-                present here for clarification. "op" is the type of
-                modification (add, delete, replace).
-
-modrdn { action msgid suffix dn newrdn deleteoldrdn }
-
-       action - Always equal to MODRDN
-       msgid  - The msgid of this ldap session
-       suffix - List of suffix(es) associated with the call. Each one
-                is and entry in a tcl formatted list (surrounded by {}'s)
-       dn     - DN whose RDN is being renamed
-       newrdn - New RDN
-       deleteoldrdn - Boolean stating whether or not the old RDN should
-                be removed after being renamed
-
-search { action msgid suffix base scope deref sizelimit timelimit
-        filterstr attrsonly attrlist }
-
-       action - Always equal to SEARCH
-       msgid  - The msgid of this ldap session
-       suffix - List of suffix(es) associated with the call. Each one
-                is and entry in a tcl formatted list (surrounded by {}'s)
-       base   - Base for this search
-       scope  - Scope of search, ( 0 | 1 | 2 )
-       deref  - Alias dereferencing ( 0 | 1 | 2 | 3 )
-       sizelimit - Script should try not to return more data that this
-       timelimit - Time limit for search
-       filterstr - Filter string as sent by the requestor.
-       attrsonly - Boolean for whether to list only the attributes
-                instead of attributes and their values.
-       attrlist  - Tcl list if to retrieve.
-
-unbind { action msgid suffix dn }
-
-       action - Always equal to UNBIND
-       msgid  - The msgid of this ldap session
-       suffix - List of suffix(es) associated with the call. Each one
-                is and entry in a tcl formatted list (surrounded by {}'s)
-       dn     - DN to unbind
-
-
-------------------------------------
-Synopsis of Return Method and Syntax
-------------------------------------
-
-There are only 2 return types. All procs must return a result to show
-status of the operation. The result is in this form: 
-
-  { RESULT {code: <integer>} {matched: <partialdn>} {info: <string>} {} }
-
-This is best accomplished with this type of tcl code
-
-  lappend ret_val "RESULT"
-  lappend ret_val "code: 0"
-  lappend ret_val ""
-  return $ret_val
-
-The final empty string (item in list) is necessary to point to the end of
-list. The 'code', 'matched', and 'info' values are not necessary, and
-default values are given if not specified. The 'code' value is usually an
-LDAP error in decimal notation from ldap.h. The 'info', may be sent back
-to the client, depending on the function. LDAP uses the value of 'code' to
-indicate whether or not the authentication is acceptible in the bind proc.
-
-The other type of return is for searches. It is similar format to the
-shell backend return (as is most of the syntax here). Its format follows:
-
-    {dn: o=Company, c=US} {attr: val} {objectclass: val} {}
-    {dn: o=CompanyB, c=US} {attr: val} {objectclass: val} {}
-
-Again, newlines are for visual purposes here. Also note the {} marking the
-end of the entry (same effect as a newline in ldif format). Here is some
-example code again, showing a full search proc example.
-
-# Note that 'args' lets you lump all possible args into one var, used
-# here for simplicity of example
-proc ldap:search { args } {
-  # perform some operations
-
-  lappend ret_val "dn: $rdn,$base"
-  lappend ret_val "objectclass: $objcl"
-  lappend ret_val "sn: $rdn"
-  lappend ret_val "mail: $email"
-  lappend ret_val ""
-# Now setup the result
-  lappend ret_val "RESULT"
-  lappend ret_val "code: 0"
-  lappend ret_val ""
-
-  return $ret_val
-}
-
-NOTE: Newlines in the return value is acceptable in search entries (i.e.
-when returning base64 encoded binary entries).
-
-
--------------------------------------
-Synopsis of Builtin Commands and Vars
--------------------------------------
-
-ldap:debug <msg>
-
-  Allows you to send debug messages through OpenLDAP's native debugging
-  system, this is sent as a LDAP_DEBUG_ANY and will be logged. Useful for
-  debugging scripts or logging bind failures.
+The Tcl Backend is described in the slapd-tcl(5) manual page.