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

FreeBSD Manual Pages


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

       slapo-rwm - rewrite/remap overlay to slapd


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

       This overlay is experimental.

       An  important  feature  of the rwm overlay is the capability to map ob-
       jectClasses and attributeTypes from the local set (or a subset  of  it)
       to a foreign set, and vice versa.  This is accomplished by means	of the
       rwm-map directive.

       rwm-map {attribute | objectclass} [<local name> | *] {<foreign name>  |
	      Map  attributeTypes and objectClasses from the foreign server to
	      different	values on the local slapd.  The	reason	is  that  some
	      attributes  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
       explicitly 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 problem should not exist when remapping a  local  database.
       Note,  however,	that the decision whether to rewrite or	not attribute-
       Types with distinguishedName syntax, requires the knowledge of the  at-
       tributeType 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  map-
       ping  from remote to local, first the attributeType is mapped, and then
       the DN is rewritten.  As	such, it  is  important	 that  the  local  at-
       tributeType  is	appropriately  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	rewritten.

       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-normal-
       ize-mapped-attrs	directive.

       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".

       A basic feature of the rwm overlay is the capability to perform	suffix
       massaging  between  a virtual and a real	naming context by means	of the
       rwm-suffixmassage directive.  This, in conjunction with proxy backends,
       slapd-ldap(5)  and  slapd-meta(5), or with the relay backend, slapd-re-
       lay(5), allows one to create virtual views  of  databases.   A  distin-
       guishing	 feature of this overlay is that, when instantiated before any
       database, it can	modify the DN of requests before  database  selection.
       For this	reason,	rules that rewrite the empty DN	("") or	the subschema-
       Subentry	DN (usually "cn=subschema"), would prevent clients from	 read-
       ing 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 context in	the  searchEntryDN,  searchAttrDN  and
	      matchedDN	 rewrite contexts.  By default no rewriting occurs for
	      the searchFilter and for the referralAttrDN and  referralDN  re-
	      write  contexts.	 If  no	_virtual naming	context_ is given, the
	      first suffix of the database is used; this requires the rwm-suf-
	      fixmassage directive be defined after the	database suffix	direc-
	      tive.  The rwm-suffixmassage directive  automatically  sets  the
	      rwm-rewriteEngine	to ON.

       See the REWRITING section for details.

       A  string  is  rewritten	according to a set of rules, called a `rewrite
       context'.  The rules are	based on POSIX (''extended'') regular  expres-
       sions with substring matching; basic variable substitution and map res-
       olution of substrings is	allowed	by specific mechanisms detailed	in the
       following.   The	 behavior  of pattern matching/substitution can	be al-
       tered 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):

       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  ac-
       tions,  described by a set of optional flags.  In case of match,	string
       rewriting is performed according	to the substitution pattern  that  al-
       lows  one  to  refer to substrings matched in the incoming string.  The
       actions,	if any,	are finally performed.	Each rule is  executed	recur-
       sively, unless altered by specific action flags;	see "Action Flags" for
       details.	 A default limit on the	recursion level	is set,	and can	be al-
       tered  by the rwm-rewriteMaxPasses directive, as	detailed in the	"Addi-
       tional 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 af-
       ter substitution.

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

       `R'    use  POSIX  ''basic''  regular  expressions  (default  is	 ''ex-

       `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
	      applied  recursively; combine with `:' to	apply the current rule
	      only once	and then stop.

       `#'    stop current operation if	the rule matches, and  issue  an  `un-
	      willing 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.  is-
	      sued by a	map, the error is treated as a missed match.  The `un-
	      willing to perform' is not overridden.

       `U{n}' uses n as	return code if the rule	matches; the flag does not al-
	      ter the recursive	behavior of the	rule, so, to have it performed
	      only once, it  must  be  used  in	 combination  with  `:',  e.g.
	      `:U{32}'	returns	the value `32' (indicating noSuchObject) after
	      exactly one execution 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 allowed, indicating	the related LDAP error
	      codes as specified in draft-ietf-ldapbis-protocol.

       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

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

	      `$' `{' [	<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,  al-
	      ready defined command name (NOT IMPLEMENTED YET)

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

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

       $      parameter	dereferencing; <name> must refer to an existing	param-
	      eter; 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  al-
       ready  escaped by slapd's low level parsing routines; as	a consequence,
       regex escaping 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
       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  con-
       text  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

       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
	      rewriting	takes place (an	easy way to stop rewriting without al-
	      tering 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
	      contains.	 It is used also to reference sub contexts  in	string
	      rewriting.   A  context may alias	another	one.  In this case the
	      alias context contains no	rule, and any reference	to it will re-
	      sult in accessing	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 substitu-
	      tion pattern of a	rule.

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

       rwm-rewriteMaxPasses <number of passes> [<number	of passes per rule>]
	      Sets the maximum number of total rewriting passes	 that  can  be
	      performed	 in  a	single	rewrite	operation (to avoid loops).  A
	      safe default 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	opera-
	      tion  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.

       Currently,  few maps are	builtin	but additional map types may be	regis-
       tered at	runtime.

       Supported maps are:

       LDAP <URI> [bindwhen=<when>] [version=<version>]	[binddn=<DN>] [creden-
	      The LDAP map expands a value by performing a simple LDAP search.
	      Its configuration	is based on a mandatory	URI, whose attrs  por-
	      tion  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,  re-
	      spectively  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
	      password	that  is  used to perform an authenticated simple bind
	      before performing	the search operation; if not given, an	anony-
	      mous connection 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 por-
	      tion must	contain	exactly	one attribute, and if  a  multi-valued
	      attribute	is used, only the first	value is considered.

       # 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"    ":"

       # 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. `'; 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.
       rwm-rewriteContext bindDN
       rwm-rewriteRule "^mail=[^,]+@[^,]+$" "${attr2dn($0)}" ":@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_]+)(\\).*)"
       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 ".*" "" "#"

       The following directives	map the	object class `groupOfNames' to the ob-
       ject 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
       example,	but you	get the	point.

	      default slapd configuration file

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

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

OpenLDAP 2.6.1			  2022/01/20			  SLAPO-RWM(5)

NAME | SYNOPSIS | DESCRIPTION | MAPPING | SUFFIX MASSAGING | REWRITING | Passes | Pattern Matching Flags | Action Flags | Pattern Matching | Substitution Pattern Syntax | Rewrite Context | Basic Configuration Syntax | Additional Configuration Syntax | MAPS | REWRITE CONFIGURATION EXAMPLES | MAPPING EXAMPLES | FILES | SEE ALSO | AUTHOR

Want to link to this manual page? Use this URL:

home | help