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

MAPPING
       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 attribut-
       eType 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".

SUFFIX MASSAGING
       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
	      rewrite  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.

REWRITING
       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):

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  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-
	      tended'')

       `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 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_format(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, 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	 para-
	      meter;  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
       rewriting.

       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.

MAPS
       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-
       tials=<cred>]
	      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.

       escape [escape2dn|escape2filter|unescapedn|unescapefilter]...
	      The  escape map makes it possible	use DNs	or their parts in fil-
	      ter strings and vice versa.  It processes	a value	 according  to
	      the operations 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 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.

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.9			  2024/11/26			  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+14.3.quarterly>

home | help