1SLAPO-RWM(5) File Formats Manual SLAPO-RWM(5)
2
3
4
6 slapo-rwm - rewrite/remap overlay to slapd
7
9 /etc/openldap/slapd.conf
10
12 The rwm overlay to slapd(8) performs basic DN/data rewrite and object‐
13 Class/attributeType mapping. Its usage is mostly intended to provide
14 virtual views of existing data either remotely, in conjunction with the
15 proxy backend described in slapd-ldap(5), or locally, in conjunction
16 with the relay backend described in slapd-relay(5).
17
18 This overlay is experimental.
19
21 An important feature of the rwm overlay is the capability to map ob‐
22 jectClasses and attributeTypes from the local set (or a subset of it)
23 to a foreign set, and vice versa. This is accomplished by means of the
24 rwm-map directive.
25
26 rwm-map {attribute | objectclass} [<local name> | *] {<foreign name> |
27 *}
28 Map attributeTypes and objectClasses from the foreign server to
29 different values on the local slapd. The reason is that some
30 attributes might not be part of the local slapd's schema, some
31 attribute names might be different but serve the same purpose,
32 etc. If local or foreign name is `*', the name is preserved.
33 If local name is omitted, the foreign name is removed. Unmapped
34 names are preserved if both local and foreign name are `*', and
35 removed if local name is omitted and foreign name is `*'.
36
37 The local objectClasses and attributeTypes must be defined in the local
38 schema; the foreign ones do not have to, but users are encouraged to
39 explicitly define the remote attributeTypes and the objectClasses they
40 intend to map. All in all, when remapping a remote server via back-
41 ldap (slapd-ldap(5)) or back-meta (slapd-meta(5)) their definition can
42 be easily obtained by querying the subschemaSubentry of the remote
43 server; the problem should not exist when remapping a local database.
44 Note, however, that the decision whether to rewrite or not attribute‐
45 Types with distinguishedName syntax, requires the knowledge of the at‐
46 tributeType syntax. See the REWRITING section for details.
47
48 Note that when mapping DN-valued attributes from local to remote, first
49 the DN is rewritten, and then the attributeType is mapped; while map‐
50 ping from remote to local, first the attributeType is mapped, and then
51 the DN is rewritten. As such, it is important that the local at‐
52 tributeType is appropriately defined as using the distinguishedName
53 syntax. Also, note that there are DN-related syntaxes (i.e. compound
54 types with a portion that is DN-valued), like nameAndOptionalUID, whose
55 values are currently not rewritten.
56
57 If the foreign type of an attribute mapping is not defined on the local
58 server, it might be desirable to have the attribute values normalized
59 after the mapping process. Not normalizing the values can lead to wrong
60 results, when the rwm overlay is used together with e.g. the pcache
61 overlay. This normalization can be enabled by means of the rwm-normal‐
62 ize-mapped-attrs directive.
63
64 rwm-normalize-mapped-attrs {yes|no}
65 Set this to "yes", if the rwm overlay should try to normalize
66 the values of attributes that are mapped from an attribute type
67 that is unknown to the local server. The default value of this
68 setting is "no".
69
70 rwm-drop-unrequested-attrs {yes|no}
71 Set this to "yes", if the rwm overlay should drop attributes
72 that are not explicitly requested by a search operation. When
73 this is set to "no", the rwm overlay will leave all attributes
74 in place, so that subsequent modules can further manipulate
75 them. In any case, unrequested attributes will be omitted from
76 search results by the frontend, when the search entry response
77 package is encoded. The default value of this setting is "yes".
78
80 A basic feature of the rwm overlay is the capability to perform suffix
81 massaging between a virtual and a real naming context by means of the
82 rwm-suffixmassage directive. This, in conjunction with proxy backends,
83 slapd-ldap(5) and slapd-meta(5), or with the relay backend, slapd-re‐
84 lay(5), allows one to create virtual views of databases. A distin‐
85 guishing feature of this overlay is that, when instantiated before any
86 database, it can modify the DN of requests before database selection.
87 For this reason, rules that rewrite the empty DN ("") or the subschema‐
88 Subentry DN (usually "cn=subschema"), would prevent clients from read‐
89 ing the root DSE or the DSA's schema.
90
91 rwm-suffixmassage [<virtual naming context>] <real naming context>
92 Shortcut to implement naming context rewriting; the trailing
93 part of the DN is rewritten from the virtual to the real naming
94 context in the bindDN, searchDN, searchFilterAttrDN, compareDN,
95 compareAttrDN, addDN, addAttrDN, modifyDN, modifyAttrDN, modrDN,
96 newSuperiorDN, deleteDN, exopPasswdDN, and from the real to the
97 virtual naming context in the searchEntryDN, searchAttrDN and
98 matchedDN rewrite contexts. By default no rewriting occurs for
99 the searchFilter and for the referralAttrDN and referralDN re‐
100 write contexts. If no <virtual naming context> is given, the
101 first suffix of the database is used; this requires the rwm-suf‐
102 fixmassage directive be defined after the database suffix direc‐
103 tive. The rwm-suffixmassage directive automatically sets the
104 rwm-rewriteEngine to ON.
105
106 See the REWRITING section for details.
107
109 A string is rewritten according to a set of rules, called a `rewrite
110 context'. The rules are based on POSIX (''extended'') regular expres‐
111 sions with substring matching; basic variable substitution and map res‐
112 olution of substrings is allowed by specific mechanisms detailed in the
113 following. The behavior of pattern matching/substitution can be al‐
114 tered by a set of flags.
115
116 <rewrite context> ::= <rewrite rule> [...]
117 <rewrite rule> ::= <pattern> <action> [<flags>]
118
119 The underlying concept is to build a lightweight rewrite module for the
120 slapd server (initially dedicated to the LDAP backend):
121
123 An incoming string is matched against a set of rewriteRules. Rules are
124 made of a regex match pattern, a substitution pattern and a set of ac‐
125 tions, described by a set of optional flags. In case of match, string
126 rewriting is performed according to the substitution pattern that al‐
127 lows one to refer to substrings matched in the incoming string. The
128 actions, if any, are finally performed. Each rule is executed recur‐
129 sively, unless altered by specific action flags; see "Action Flags" for
130 details. A default limit on the recursion level is set, and can be al‐
131 tered by the rwm-rewriteMaxPasses directive, as detailed in the "Addi‐
132 tional Configuration Syntax" section. The substitution pattern allows
133 map resolution of substrings. A map is a generic object that maps a
134 substitution pattern to a value. The flags are divided in "Pattern
135 Matching Flags" and "Action Flags"; the former alter the regex match
136 pattern behavior, while the latter alter the actions that are taken af‐
137 ter substitution.
138
140 `C' honors case in matching (default is case insensitive)
141
142 `R' use POSIX ''basic'' regular expressions (default is ''ex‐
143 tended'')
144
145 `M{n}' allow no more than n recursive passes for a specific rule; does
146 not alter the max total count of passes, so it can only enforce
147 a stricter limit for a specific rule.
148
150 `:' apply the rule once only (default is recursive)
151
152 `@' stop applying rules in case of match; the current rule is still
153 applied recursively; combine with `:' to apply the current rule
154 only once and then stop.
155
156 `#' stop current operation if the rule matches, and issue an `un‐
157 willing to perform' error.
158
159 `G{n}' jump n rules back and forth (watch for loops!). Note that
160 `G{1}' is implicit in every rule.
161
162 `I' ignores errors in rule; this means, in case of error, e.g. is‐
163 sued by a map, the error is treated as a missed match. The `un‐
164 willing to perform' is not overridden.
165
166 `U{n}' uses n as return code if the rule matches; the flag does not al‐
167 ter the recursive behavior of the rule, so, to have it performed
168 only once, it must be used in combination with `:', e.g.
169 `:U{32}' returns the value `32' (indicating noSuchObject) after
170 exactly one execution of the rule, if the pattern matches. As a
171 consequence, its behavior is equivalent to `@', with the return
172 code set to n; or, in other words, `@' is equivalent to `U{0}'.
173 Positive errors are allowed, indicating the related LDAP error
174 codes as specified in draft-ietf-ldapbis-protocol.
175
176 The ordering of the flags can be significant. For instance: `IG{2}'
177 means ignore errors and jump two lines ahead both in case of match and
178 in case of error, while `G{2}I' means ignore errors, but jump two lines
179 ahead only in case of match.
180
181 More flags (mainly Action Flags) will be added as needed.
182
184 See regex(7) and/or re_format(7).
185
187 Everything starting with `$' requires substitution;
188
189 the only obvious exception is `$$', which is turned into a single `$';
190
191 the basic substitution is `$<d>', where `<d>' is a digit; 0 means the
192 whole string, while 1-9 is a submatch, as discussed in regex(7) and/or
193 re_format(7).
194
195 a `$' followed by a `{' invokes an advanced substitution. The pattern
196 is:
197
198 `$' `{' [ <operator> ] <name> `(' <substitution> `)' `}'
199
200 where <name> must be a legal name for the map, i.e.
201
202 <name> ::= [a-z][a-z0-9]* (case insensitive)
203 <operator> ::= `>' `|' `&' `&&' `*' `**' `$'
204
205 and <substitution> must be a legal substitution pattern, with no limits
206 on the nesting level.
207
208 The operators are:
209
210 > sub-context invocation; <name> must be a legal, already defined
211 rewrite context name
212
213 | external command invocation; <name> must refer to a legal, al‐
214 ready defined command name (NOT IMPLEMENTED YET)
215
216 & variable assignment; <name> defines a variable in the running
217 operation structure which can be dereferenced later; operator &
218 assigns a variable in the rewrite context scope; operator && as‐
219 signs a variable that scopes the entire session, e.g. its value
220 can be dereferenced later by other rewrite contexts
221
222 * variable dereferencing; <name> must refer to a variable that is
223 defined and assigned for the running operation; operator *
224 dereferences a variable scoping the rewrite context; operator **
225 dereferences a variable scoping the whole session, e.g. the
226 value is passed across rewrite contexts
227
228 $ parameter dereferencing; <name> must refer to an existing param‐
229 eter; the idea is to make some run-time parameters set by the
230 system available to the rewrite engine, as the client host name,
231 the bind DN if any, constant parameters initialized at config
232 time, and so on; no parameter is currently set by either
233 back-ldap or back-meta, but constant parameters can be defined
234 in the configuration file by using the rewriteParam directive.
235
236 Substitution escaping has been delegated to the `$' symbol, which is
237 used instead of `\' in string substitution patterns because `\' is al‐
238 ready escaped by slapd's low level parsing routines; as a consequence,
239 regex escaping requires two `\' symbols, e.g. `.*\.foo\.bar' must be
240 written as `.*\\.foo\\.bar'.
241
243 A rewrite context is a set of rules which are applied in sequence. The
244 basic idea is to have an application initialize a rewrite engine (think
245 of Apache's mod_rewrite ...) with a set of rewrite contexts; when
246 string rewriting is required, one invokes the appropriate rewrite con‐
247 text with the input string and obtains the newly rewritten one if no
248 errors occur.
249
250 Each basic server operation is associated to a rewrite context; they
251 are divided in two main groups: client -> server and server -> client
252 rewriting.
253
254 client -> server:
255
256 (default) if defined and no specific context
257 is available
258 bindDN bind
259 searchDN search
260 searchFilter search
261 searchFilterAttrDN search
262 compareDN compare
263 compareAttrDN compare AVA
264 addDN add
265 addAttrDN add AVA (DN portion of "ref" excluded)
266 modifyDN modify
267 modifyAttrDN modify AVA (DN portion of "ref" excluded)
268 referralAttrDN add/modify DN portion of referrals
269 (default to none)
270 renameDN modrdn (the old DN)
271 newSuperiorDN modrdn (the new parent DN, if any)
272 newRDN modrdn (the new relative DN)
273 deleteDN delete
274 exopPasswdDN password modify extended operation DN
275
276 server -> client:
277
278 searchEntryDN search (only if defined; no default;
279 acts on DN of search entries)
280 searchAttrDN search AVA (only if defined; defaults
281 to searchEntryDN; acts on DN-syntax
282 attributes of search results)
283 matchedDN all ops (only if applicable; defaults
284 to searchEntryDN)
285 referralDN all ops (only if applicable; defaults
286 to none)
287
289 All rewrite/remap directives start with the prefix rwm-
290
291 rwm-rewriteEngine { on | off }
292 If `on', the requested rewriting is performed; if `off', no
293 rewriting takes place (an easy way to stop rewriting without al‐
294 tering too much the configuration file).
295
296 rwm-rewriteContext <context name> [ alias <aliased context name> ]
297 <Context name> is the name that identifies the context, i.e. the
298 name used by the application to refer to the set of rules it
299 contains. It is used also to reference sub contexts in string
300 rewriting. A context may alias another one. In this case the
301 alias context contains no rule, and any reference to it will re‐
302 sult in accessing the aliased one.
303
304 rwm-rewriteRule <regex match pattern> <substitution pattern> [ <flags>
305 ]
306 Determines how a string can be rewritten if a pattern is
307 matched. Examples are reported below.
308
310 rwm-rewriteMap <map type> <map name> [ <map attrs> ]
311 Allows one to define a map that transforms substring rewriting
312 into something else. The map is referenced inside the substitu‐
313 tion pattern of a rule.
314
315 rwm-rewriteParam <param name> <param value>
316 Sets a value with global scope, that can be dereferenced by the
317 command `${$paramName}'.
318
319 rwm-rewriteMaxPasses <number of passes> [<number of passes per rule>]
320 Sets the maximum number of total rewriting passes that can be
321 performed in a single rewrite operation (to avoid loops). A
322 safe default is set to 100; note that reaching this limit is
323 still treated as a success; recursive invocation of rules is
324 simply interrupted. The count applies to the rewriting opera‐
325 tion as a whole, not to any single rule; an optional per-rule
326 limit can be set. This limit is overridden by setting specific
327 per-rule limits with the `M{n}' flag.
328
329
331 Currently, few maps are builtin but additional map types may be regis‐
332 tered at runtime.
333
334 Supported maps are:
335
336 LDAP <URI> [bindwhen=<when>] [version=<version>] [binddn=<DN>] [creden‐
337 tials=<cred>]
338 The LDAP map expands a value by performing a simple LDAP search.
339 Its configuration is based on a mandatory URI, whose attrs por‐
340 tion must contain exactly one attribute (use entryDN to fetch
341 the DN of an entry). If a multi-valued attribute is used, only
342 the first value is considered.
343
344 The parameter bindwhen determines when the connection is estab‐
345 lished. It can take the values now, later, and everytime, re‐
346 spectively indicating that the connection should be created at
347 startup, when required, or any time it is used. In the former
348 two cases, the connection is cached, while in the latter a fresh
349 new one is used all times. This is the default.
350
351 The parameters binddn and credentials represent the DN and the
352 password that is used to perform an authenticated simple bind
353 before performing the search operation; if not given, an anony‐
354 mous connection is used.
355
356 The parameter version can be 2 or 3 to indicate the protocol
357 version that must be used. The default is 3.
358
359
360 slapd <URI>
361 The slapd map expands a value by performing an internal LDAP
362 search. Its configuration is based on a mandatory URI, which
363 must begin with ldap:/// (i.e., it must be an LDAP URI and it
364 must not specify a host). As with the LDAP map, the attrs por‐
365 tion must contain exactly one attribute, and if a multi-valued
366 attribute is used, only the first value is considered.
367
368
370 # set to `off' to disable rewriting
371 rwm-rewriteEngine on
372
373 # the rules the "suffixmassage" directive implies
374 rwm-rewriteEngine on
375 # all dataflow from client to server referring to DNs
376 rwm-rewriteContext default
377 rwm-rewriteRule "(.+,)?<virtualnamingcontext>$" "$1<realnamingcontext>" ":"
378 # empty filter rule
379 rwm-rewriteContext searchFilter
380 # all dataflow from server to client
381 rwm-rewriteContext searchEntryDN
382 rwm-rewriteRule "(.+,)?<realnamingcontext>$" "$1<virtualnamingcontext>" ":"
383 rwm-rewriteContext searchAttrDN alias searchEntryDN
384 rwm-rewriteContext matchedDN alias searchEntryDN
385 # misc empty rules
386 rwm-rewriteContext referralAttrDN
387 rwm-rewriteContext referralDN
388
389 # Everything defined here goes into the `default' context.
390 # This rule changes the naming context of anything sent
391 # to `dc=home,dc=net' to `dc=OpenLDAP, dc=org'
392
393 rwm-rewriteRule "(.+,)?dc=home,[ ]?dc=net$"
394 "$1dc=OpenLDAP, dc=org" ":"
395
396 # since a pretty/normalized DN does not include spaces
397 # after rdn separators, e.g. `,', this rule suffices:
398
399 rwm-rewriteRule "(.+,)?dc=home,dc=net$"
400 "$1dc=OpenLDAP,dc=org" ":"
401
402 # Start a new context (ends input of the previous one).
403 # This rule adds blanks between DN parts if not present.
404 rwm-rewriteContext addBlanks
405 rwm-rewriteRule "(.*),([^ ].*)" "$1, $2"
406
407 # This one eats blanks
408 rwm-rewriteContext eatBlanks
409 rwm-rewriteRule "(.*), (.*)" "$1,$2"
410
411 # Here control goes back to the default rewrite
412 # context; rules are appended to the existing ones.
413 # anything that gets here is piped into rule `addBlanks'
414 rwm-rewriteContext default
415 rwm-rewriteRule ".*" "${>addBlanks($0)}" ":"
416
417 # Rewrite the search base according to `default' rules.
418 rwm-rewriteContext searchDN alias default
419
420 # Search results with OpenLDAP DN are rewritten back with
421 # `dc=home,dc=net' naming context, with spaces eaten.
422 rwm-rewriteContext searchEntryDN
423 rwm-rewriteRule "(.*[^ ],)?[ ]?dc=OpenLDAP,[ ]?dc=org$"
424 "${>eatBlanks($1)}dc=home,dc=net" ":"
425
426 # Bind with email instead of full DN: we first need
427 # an ldap map that turns attributes into a DN (the
428 # argument used when invoking the map is appended to
429 # the URI and acts as the filter portion)
430 rwm-rewriteMap ldap attr2dn "ldap://host/dc=my,dc=org?dn?sub"
431
432 # Then we need to detect DN made up of a single email,
433 # e.g. `mail=someone@example.com'; note that the rule
434 # in case of match stops rewriting; in case of error,
435 # it is ignored. In case we are mapping virtual
436 # to real naming contexts, we also need to rewrite
437 # regular DNs, because the definition of a bindDN
438 # rewrite context overrides the default definition.
439 rwm-rewriteContext bindDN
440 rwm-rewriteRule "^mail=[^,]+@[^,]+$" "${attr2dn($0)}" ":@I"
441
442 # This is a rather sophisticated example. It massages a
443 # search filter in case who performs the search has
444 # administrative privileges. First we need to keep
445 # track of the bind DN of the incoming request, which is
446 # stored in a variable called `binddn' with session scope,
447 # and left in place to allow regular binding:
448 rwm-rewriteContext bindDN
449 rwm-rewriteRule ".+" "${&&binddn($0)}$0" ":"
450
451 # A search filter containing `uid=' is rewritten only
452 # if an appropriate DN is bound.
453 # To do this, in the first rule the bound DN is
454 # dereferenced, while the filter is decomposed in a
455 # prefix, in the value of the `uid=<arg>' AVA, and
456 # in a suffix. A tag `<>' is appended to the DN.
457 # If the DN refers to an entry in the `ou=admin' subtree,
458 # the filter is rewritten OR-ing the `uid=<arg>' with
459 # `cn=<arg>'; otherwise it is left as is. This could be
460 # useful, for instance, to allow apache's auth_ldap-1.4
461 # module to authenticate users with both `uid' and
462 # `cn', but only if the request comes from a possible
463 # `cn=Web auth,ou=admin,dc=home,dc=net' user.
464 rwm-rewriteContext searchFilter
465 rwm-rewriteRule "(.*\\()uid=([a-z0-9_]+)(\\).*)"
466 "${**binddn}<>${&prefix($1)}${&arg($2)}${&suffix($3)}"
467 ":I"
468 rwm-rewriteRule "^[^,]+,ou=admin,dc=home,dc=net$"
469 "${*prefix}|(uid=${*arg})(cn=${*arg})${*suffix}" ":@I"
470 rwm-rewriteRule ".*<>$" "${*prefix}uid=${*arg}${*suffix}" ":"
471
472 # This example shows how to strip unwanted DN-valued
473 # attribute values from a search result; the first rule
474 # matches DN values below "ou=People,dc=example,dc=com";
475 # in case of match the rewriting exits successfully.
476 # The second rule matches everything else and causes
477 # the value to be rejected.
478 rwm-rewriteContext searchEntryDN
479 rwm-rewriteRule ".+,ou=People,dc=example,dc=com$" "$0" ":@"
480 rwm-rewriteRule ".*" "" "#"
481
483 The following directives map the object class `groupOfNames' to the ob‐
484 ject class `groupOfUniqueNames' and the attribute type `member' to the
485 attribute type `uniqueMember':
486
487 map objectclass groupOfNames groupOfUniqueNames
488 map attribute uniqueMember member
489
490 This presents a limited attribute set from the foreign server:
491
492 map attribute cn *
493 map attribute sn *
494 map attribute manager *
495 map attribute description *
496 map attribute *
497
498 These lines map cn, sn, manager, and description to themselves, and any
499 other attribute gets "removed" from the object before it is sent to the
500 client (or sent up to the LDAP server). This is obviously a simplistic
501 example, but you get the point.
502
504 /etc/openldap/slapd.conf
505 default slapd configuration file
506
508 slapd.conf(5), slapd-config(5), slapd-ldap(5), slapd-meta(5), slapd-re‐
509 lay(5), slapd(8), regex(7), re_format(7).
510
512 Pierangelo Masarati; based on back-ldap rewrite/remap features by
513 Howard Chu, Pierangelo Masarati.
514
515
516
517OpenLDAP 2.6.2 2022/05/04 SLAPO-RWM(5)