Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
SLAPO-RWM(5)		       File Formats Manual		    SLAPO-RWM(5)

NAME
     slapo-rwm - rewrite/remap overlay to slapd

SYNOPSIS
     /usr/local/etc/openldap/slapd.conf

DESCRIPTION
     The  rwm  overlay	to  slapd(8)  performs basic DN/data rewrite and object-
     Class/attributeType mapping.  Its usage is mostly intended to provide  vir-
     tual  views of existing data either remotely, in conjunction with the proxy
     backend described in slapd-ldap(5), or locally, in conjunction with the re-
     lay backend described in slapd-relay(5).

     This overlay is experimental.

MAPPING
     An important feature of the rwm overlay is the capability	to  map  object-
     Classes and attributeTypes from the local set (or a subset of it) to a for-
     eign set, and vice versa.	This is accomplished by means of the rwm-map di-
     rective.

     rwm-map {attribute | objectclass} [<local name> | *] {<foreign name> | *}
	    Map attributeTypes and objectClasses from the foreign server to dif-
	    ferent  values  on the local slapd.  The reason is that some attrib-
	    utes might not be part of the local slapd's schema,  some  attribute
	    names  might be different but serve the same purpose, etc.	If local
	    or foreign name is `*', the name is preserved.   If  local	name  is
	    omitted,  the foreign name is removed.  Unmapped names are preserved
	    if both local and foreign name are `*', and removed if local name is
	    omitted and foreign name is `*'.

     The local objectClasses and attributeTypes must be  defined  in  the  local
     schema;  the  foreign  ones do not have to, but users are encouraged to ex-
     plicitly define the remote attributeTypes and the objectClasses they intend
     to map.   All  in	all,  when  remapping  a  remote  server  via  back-ldap
     (slapd-ldap(5)) or back-meta (slapd-meta(5)) their definition can be easily
     obtained  by querying the subschemaSubentry of the remote server; the prob-
     lem should not exist when remapping a local database.  Note, however,  that
     the  decision  whether to rewrite or not attributeTypes with distinguished-
     Name syntax, requires the knowledge of the attributeType syntax.	See  the
     REWRITING section for details.

     Note that when mapping DN-valued attributes from local to remote, first the
     DN  is  rewritten, and then the attributeType is mapped; while mapping from
     remote to local, first the attributeType is mapped,  and  then  the  DN  is
     rewritten.  As such, it is important that the local attributeType is appro-
     priately  defined	as  using the distinguishedName syntax.  Also, note that
     there are DN-related syntaxes (i.e. compound types with a portion	that  is
     DN-valued), like nameAndOptionalUID, whose values are currently not rewrit-
     ten.

     If  the  foreign  type  of an attribute mapping is not defined on the local
     server, it might be desirable to have the attribute values normalized after
     the mapping process. Not normalizing the values can lead to wrong	results,
     when  the	rwm  overlay is used together with e.g. the pcache overlay. This
     normalization can be enabled by means of the rwm-normalize-mapped-attrs di-
     rective.

     rwm-normalize-mapped-attrs {yes|no}
	    Set this to "yes", if the rwm overlay should try  to  normalize  the
	    values  of attributes that are mapped from an attribute type that is
	    unknown to the local server. The default value of  this  setting  is
	    "no".

     rwm-drop-unrequested-attrs {yes|no}
	    Set  this  to  "yes", if the rwm overlay should drop attributes that
	    are not explicitly requested by a search operation.   When	this  is
	    set  to "no", the rwm overlay will leave all attributes in place, so
	    that subsequent modules can further manipulate them.  In  any  case,
	    unrequested  attributes  will  be omitted from search results by the
	    frontend, when the search entry response package  is  encoded.   The
	    default value of this setting is "yes".

SUFFIX MASSAGING
     A basic feature of the rwm overlay is the capability to perform suffix mas-
     saging between a virtual and a real naming context by means of the rwm-suf-
     fixmassage   directive.	This,	in   conjunction  with	proxy  backends,
     slapd-ldap(5) and slapd-meta(5), or with the relay backend, slapd-relay(5),
     allows one to create virtual views of databases.  A distinguishing  feature
     of this overlay is that, when instantiated before any database, it can mod-
     ify  the  DN of requests before database selection.  For this reason, rules
     that rewrite the  empty  DN  ("")	or  the  subschemaSubentry  DN	(usually
     "cn=subschema"),  would  prevent  clients	from reading the root DSE or the
     DSA's schema.

     rwm-suffixmassage [<virtual naming context>] <real naming context>
	    Shortcut to implement naming context rewriting; the trailing part of
	    the DN is rewritten from the virtual to the real naming  context  in
	    the  bindDN, searchDN, searchFilterAttrDN, compareDN, compareAttrDN,
	    addDN, addAttrDN,  modifyDN,  modifyAttrDN,  modrDN,  newSuperiorDN,
	    deleteDN, exopPasswdDN, and from the real to the virtual naming con-
	    text  in  the searchEntryDN, searchAttrDN and matchedDN rewrite con-
	    texts.  By default no rewriting occurs for the searchFilter and  for
	    the  referralAttrDN and referralDN rewrite contexts.  If no <virtual
	    naming context> is given, the first suffix of the database is  used;
	    this  requires  the rwm-suffixmassage directive be defined after the
	    database suffix directive.	The rwm-suffixmassage directive automat-
	    ically sets the rwm-rewriteEngine to ON.

     See the REWRITING section for details.

REWRITING
     A string is rewritten according to a set of rules, called a  `rewrite  con-
     text'.   The  rules  are  based on POSIX (''extended'') regular expressions
     with substring matching; basic variable substitution and map resolution  of
     substrings  is  allowed  by  specific mechanisms detailed in the following.
     The behavior of pattern matching/substitution can be altered by  a  set  of
     flags.

	    <rewrite context> ::= <rewrite rule> [...]
	    <rewrite rule> ::= <pattern> <action> [<flags>]

     The  underlying  concept  is  to build a lightweight rewrite module for the
     slapd server (initially dedicated to the LDAP backend):

Passes
     An incoming string is matched against a set  of  rewriteRules.   Rules  are
     made of a regex match pattern, a substitution pattern and a set of actions,
     described	by  a set of optional flags.  In case of match, string rewriting
     is performed according to the substitution pattern that allows one to refer
     to substrings matched in the incoming string.  The actions, if any, are fi-
     nally performed.  Each rule is executed recursively, unless altered by spe-
     cific action flags; see "Action Flags" for details.  A default limit on the
     recursion level is set, and can be altered by the rwm-rewriteMaxPasses  di-
     rective, as detailed in the "Additional Configuration Syntax" section.  The
     substitution  pattern  allows  map  resolution  of  substrings.  A map is a
     generic object that maps a substitution pattern to a value.  The flags  are
     divided  in  "Pattern  Matching Flags" and "Action Flags"; the former alter
     the regex match pattern behavior, while the latter alter the  actions  that
     are taken after substitution.

Pattern Matching Flags
     `C'    honors case in matching (default is case insensitive)

     `R'    use POSIX ''basic'' regular expressions (default is ''extended'')

     `M{n}'
	    allow  no more than n recursive passes for a specific rule; does not
	    alter the max total count of  passes,  so  it  can	only  enforce  a
	    stricter limit for a specific rule.

Action Flags
     `:'    apply the rule once only (default is recursive)

     `@'    stop  applying rules in case of match; the current rule is still ap-
	    plied recursively; combine with `:' to apply the current  rule  only
	    once and then stop.

     `#'    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.

     `U{n}'
	    uses  n  as return code if the rule matches; the flag does not alter
	    the recursive behavior of the rule, so, to have  it  performed  only
	    once,  it  must  be used in combination with `:', e.g.  `:U{32}' re-
	    turns the value `32' (indicating noSuchObject) after exactly one ex-
	    ecution of the rule, if the pattern matches.  As a consequence,  its
	    behavior is equivalent to `@', with the return code set to n; or, in
	    other  words,  `@' is equivalent to `U{0}'.  Positive errors are al-
	    lowed, indicating the related  LDAP  error	codes  as  specified  in
	    RFC4511.

     The  ordering of the flags can be 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 two lines ahead only  in
     case of match.

     More flags (mainly Action Flags) will be added as needed.

Pattern Matching
     See regex(7) and/or re_format(7).

Substitution Pattern Syntax
     Everything starting with `$' requires substitution;

     the only obvious exception is `$$', which is turned into a single `$';

     the basic substitution is `$<d>', where `<d>' is a digit; 0 means the whole
     string,  while  1-9  is a submatch, as discussed in regex(7) and/or re_for-
     mat(7).

     a `$' followed by a `{' invokes an advanced substitution.	The pattern is:

	    `$' `{' [ <operator> ] <name> `(' <substitution> `)' `}'

     where <name> must be a legal name for the map, i.e.

	    <name> ::= [a-z][a-z0-9]* (case insensitive)
	    <operator> ::= `>' `|' `&' `&&' `*' `**' `$'

     and <substitution> must be a legal substitution pattern, 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 IMPLEMENTED YET)

     &	    variable assignment; <name> defines a variable in the running opera-
	    tion structure which can be dereferenced later; operator & assigns a
	    variable  in  the rewrite context scope; operator && assigns a vari-
	    able that scopes the entire session, e.g. its value can be	derefer-
	    enced later by other rewrite contexts

     *	    variable  dereferencing; <name> must refer to a variable that is de-
	    fined and assigned for the running operation;  operator  *	derefer-
	    ences  a  variable scoping the rewrite context; operator ** derefer-
	    ences a variable scoping the whole session, e.g. the value is passed
	    across rewrite contexts

     $	    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;  no parameter is currently set by either back-ldap or back-meta,
	    but constant parameters can be defined in the configuration file  by
	    using the rewriteParam directive.

     Substitution  escaping  has been delegated to the `$' symbol, which is used
     instead of `\' in string substitution patterns because `\' is  already  es-
     caped by slapd's low level parsing routines; as a consequence, regex escap-
     ing  requires  two  `\'  symbols,	e.g.  `.*\.foo\.bar'  must be written as
     `.*\\.foo\\.bar'.

Rewrite Context
     A rewrite context is a set of rules which are applied in sequence.  The ba-
     sic 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.

     Each basic server operation is associated to a rewrite  context;  they  are
     divided  in  two main groups: client -> server and server -> client rewrit-
     ing.

     client -> server:

	    (default)		 if defined and no specific context
				 is available
	    bindDN		 bind
	    searchDN		 search
	    searchFilter	 search
	    searchFilterAttrDN	 search
	    compareDN		 compare
	    compareAttrDN	 compare AVA
	    addDN		 add
	    addAttrDN		 add AVA (DN portion of "ref" excluded)
	    modifyDN		 modify
	    modifyAttrDN	 modify AVA (DN portion of "ref" excluded)
	    referralAttrDN	 add/modify DN portion of referrals
				 (default to none)
	    renameDN		 modrdn (the old DN)
	    newSuperiorDN	 modrdn (the new parent DN, if any)
	    newRDN		 modrdn (the new relative DN)
	    deleteDN		 delete
	    exopPasswdDN	 password modify extended operation DN

     server -> client:

	    searchEntryDN	 search (only if defined; no default;
				 acts on DN of search entries)
	    searchAttrDN	 search AVA (only if defined; defaults
				 to searchEntryDN; acts on DN-syntax
				 attributes of search results)
	    matchedDN		 all ops (only if applicable; defaults
				 to searchEntryDN)
	    referralDN		 all ops (only if applicable; defaults
				 to none)

Basic Configuration Syntax
     All rewrite/remap directives start with the prefix rwm-

     rwm-rewriteEngine { on | off }
	    If `on', the requested rewriting is performed; if `off', no  rewrit-
	    ing  takes place (an easy way to stop rewriting without altering too
	    much the configuration file).

     rwm-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 con-
	    tains.  It is used also to reference sub contexts in string  rewrit-
	    ing.   A context may alias another one.  In this case the alias con-
	    text contains no rule, and any reference to it will  result  in  ac-
	    cessing the aliased one.

     rwm-rewriteRule <regex match pattern> <substitution pattern> [ <flags> ]
	    Determines	how  a	string can be rewritten if a pattern is matched.
	    Examples are reported below.

Additional Configuration Syntax
     rwm-rewriteMap <map type> <map name> [ <map attrs> ]
	    Allows one to define a map that transforms substring rewriting  into
	    something  else.  The map is referenced inside the substitution pat-
	    tern of a rule.

     rwm-rewriteParam <param name> <param value>
	    Sets a value with global scope, that can be dereferenced by the com-
	    mand `${$paramName}'.

     rwm-rewriteMaxPasses <number of passes> [<number of passes per rule>]
	    Sets the maximum number of total rewriting passes that can	be  per-
	    formed  in	a single rewrite operation (to avoid loops).  A safe de-
	    fault is set to 100; note that reaching this limit is still  treated
	    as	a  success; recursive invocation of rules is simply interrupted.
	    The count applies to the rewriting operation as a whole, not to  any
	    single  rule;  an optional per-rule limit can be set.  This limit is
	    overridden by setting specific per-rule limits with the `M{n}' flag.

MAPS
     Currently, few maps are builtin but additional map types may be  registered
     at runtime.

     Supported maps are:

     LDAP <URI> [bindwhen=<when>] [version=<version>] [binddn=<DN>] [creden-
     tials=<cred>]
	    The  LDAP  map  expands  a value by performing a simple LDAP search.
	    Its configuration is based on a mandatory URI, whose  attrs  portion
	    must  contain  exactly one attribute (use entryDN to fetch the DN of
	    an entry).	If a multi-valued attribute  is  used,	only  the  first
	    value is considered.

	    The  parameter  bindwhen  determines  when	the connection is estab-
	    lished.  It can take the values now, later, and  everytime,  respec-
	    tively  indicating that the connection should be created at startup,
	    when required, or any time it is used.  In the former two cases, the
	    connection is cached, while in the latter a fresh new  one	is  used
	    all times.	This is the default.

	    The parameters binddn and credentials represent the DN and the pass-
	    word  that	is  used  to perform an authenticated simple bind before
	    performing the search operation; if not given, an anonymous  connec-
	    tion is used.

	    The parameter version can be 2 or 3 to indicate the protocol version
	    that must be used.	The default is 3.

     slapd <URI>
	    The slapd map expands a value by performing an internal LDAP search.
	    Its configuration is based on a mandatory URI, which must begin with
	    ldap:///  (i.e.,  it  must	be an LDAP URI and it must not specify a
	    host).  As with the LDAP map, the attrs portion must contain exactly
	    one attribute, and if a multi-valued attribute  is	used,  only  the
	    first value is considered.

     escape [escape2dn|escape2filter|unescapedn|unescapefilter]...
	    The  escape  map  makes it possible use DNs or their parts in filter
	    strings and vice versa.  It processes a value according to the oper-
	    ations listed in order. Supported operations include:

	    escape2dn
		   takes a string and escapes it so it can safely be pasted in a
		   DN

	    escape2filter
		   takes a string and escapes it so it can safely be pasted in a
		   filter

	    unescapedn
		   takes a string and undoes DN escaping

	    unescapefilter
		   takes a string and undoes filter escaping

	    It is advised that each escape map ends with an escape operation  as
	    that is the only safe way to handle arbitrary strings.

REWRITE CONFIGURATION EXAMPLES
     # set to `off' to disable rewriting
     rwm-rewriteEngine on

     # the rules the "suffixmassage" directive implies
     rwm-rewriteEngine on
     # all dataflow from client to server referring to DNs
     rwm-rewriteContext default
     rwm-rewriteRule "(.+,)?<virtualnamingcontext>$" "$1<realnamingcontext>" ":"
     # empty filter rule
     rwm-rewriteContext searchFilter
     # all dataflow from server to client
     rwm-rewriteContext searchEntryDN
     rwm-rewriteRule "(.+,)?<realnamingcontext>$" "$1<virtualnamingcontext>" ":"
     rwm-rewriteContext searchAttrDN alias searchEntryDN
     rwm-rewriteContext matchedDN alias searchEntryDN
     # misc empty rules
     rwm-rewriteContext referralAttrDN
     rwm-rewriteContext referralDN

     # 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'

     rwm-rewriteRule "(.+,)?dc=home,[ ]?dc=net$"
		 "$1dc=OpenLDAP, dc=org"  ":"

     # since a pretty/normalized DN does not include spaces
     # after rdn separators, e.g. `,', this rule suffices:

     rwm-rewriteRule "(.+,)?dc=home,dc=net$"
		 "$1dc=OpenLDAP,dc=org"  ":"

     # Start a new context (ends input of the previous one).
     # This rule adds blanks between DN parts if not present.
     rwm-rewriteContext  addBlanks
     rwm-rewriteRule	 "(.*),([^ ].*)" "$1, $2"

     # This one eats blanks
     rwm-rewriteContext  eatBlanks
     rwm-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 `addBlanks'
     rwm-rewriteContext  default
     rwm-rewriteRule	 ".*" "${>addBlanks($0)}" ":"

     # Rewrite the search base according to `default' rules.
     rwm-rewriteContext  searchDN alias default

     # Search results with OpenLDAP DN are rewritten back with
     # `dc=home,dc=net' naming context, with spaces eaten.
     rwm-rewriteContext  searchEntryDN
     rwm-rewriteRule	 "(.*[^ ],)?[ ]?dc=OpenLDAP,[ ]?dc=org$"
		     "${>eatBlanks($1)}dc=home,dc=net"	  ":"

     # Transform a DN value such that it can be used in a filter
     rwm-rewriteMap escape dn2filter unescapedn escape2filter

     # Bind with email instead of full DN: we first need
     # an ldap map that turns attributes into a DN (the
     # argument used when invoking the map is appended to
     # the URI and acts as the filter portion)
     rwm-rewriteMap ldap attr2dn "ldap://host/dc=my,dc=org?dn?sub"

     # Then we need to detect DN made up of a single email,
     # e.g. `mail=someone@example.com'; 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.
     #
     # While actual email addresses tend not to contain filter
     # special characters, the provided Bind DN has no such
     # restrictions.
     rwm-rewriteContext bindDN
     rwm-rewriteRule "^(mail=)([^,]+@[^,]+)$"
		     "${attr2dn($1${dn2filter($2)})}" ":@I"

     # This is a rather sophisticated 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, which is
     # stored in a variable called `binddn' with session scope,
     # and left in place to allow regular binding:
     rwm-rewriteContext  bindDN
     rwm-rewriteRule	 ".+" "${&&binddn($0)}$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, in the value of the `uid=<arg>' AVA, 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
     # `cn=Web auth,ou=admin,dc=home,dc=net' user.
     rwm-rewriteContext searchFilter
     rwm-rewriteRule "(.*\\()uid=([a-z0-9_]+)(\\).*)"
       "${**binddn}<>${&prefix($1)}${&arg($2)}${&suffix($3)}"
       ":I"
     rwm-rewriteRule "^[^,]+,ou=admin,dc=home,dc=net$"
       "${*prefix}|(uid=${*arg})(cn=${*arg})${*suffix}" ":@I"
     rwm-rewriteRule ".*<>$" "${*prefix}uid=${*arg}${*suffix}" ":"

     # This example shows how to strip unwanted DN-valued
     # attribute values from a search result; the first rule
     # matches DN values below "ou=People,dc=example,dc=com";
     # in case of match the rewriting exits successfully.
     # The second rule matches everything else and causes
     # the value to be rejected.
     rwm-rewriteContext searchEntryDN
     rwm-rewriteRule ".+,ou=People,dc=example,dc=com$" "$0" ":@"
     rwm-rewriteRule ".*" "" "#"

MAPPING EXAMPLES
     The  following directives map the object class `groupOfNames' to the object
     class `groupOfUniqueNames' and the attribute type `member' to the attribute
     type `uniqueMember':

	    map objectclass groupOfNames groupOfUniqueNames
	    map attribute uniqueMember member

     This presents a limited attribute set from the foreign server:

	    map attribute cn *
	    map attribute sn *
	    map attribute manager *
	    map attribute description *
	    map attribute *

     These lines map cn, sn, manager, and description  to  themselves,	and  any
     other  attribute  gets  "removed"	from the object before it is sent to the
     client (or sent up to the LDAP server).  This is obviously a simplistic ex-
     ample, but you get the point.

FILES
     /usr/local/etc/openldap/slapd.conf
	    default slapd configuration file

SEE ALSO
     slapd.conf(5),  slapd-config(5),  slapd-ldap(5),  slapd-meta(5),  slapd-re-
     lay(5), slapd(8), regex(7), re_format(7).

AUTHOR
     Pierangelo  Masarati;  based  on back-ldap rewrite/remap features by Howard
     Chu, Pierangelo Masarati.

OpenLDAP 2.6.13 		   2026/03/09			    SLAPO-RWM(5)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=slapo-rwm&sektion=5&manpath=FreeBSD+Ports+15.1.quarterly>

home | help