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 RFC4511.
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
369 escape [escape2dn|escape2filter|unescapedn|unescapefilter]...
370 The escape map makes it possible use DNs or their parts in fil‐
371 ter strings and vice versa. It processes a value according to
372 the operations listed in order. Supported operations include:
373
374
375 escape2dn
376 takes a string and escapes it so it can safely be pasted
377 in a DN
378
379 escape2filter
380 takes a string and escapes it so it can safely be pasted
381 in a filter
382
383 unescapedn
384 takes a string and undoes DN escaping
385
386 unescapefilter
387 takes a string and undoes filter escaping
388
389 It is advised that each escape map ends with an escape operation
390 as that is the only safe way to handle arbitrary strings.
391
392
394 # set to `off' to disable rewriting
395 rwm-rewriteEngine on
396
397 # the rules the "suffixmassage" directive implies
398 rwm-rewriteEngine on
399 # all dataflow from client to server referring to DNs
400 rwm-rewriteContext default
401 rwm-rewriteRule "(.+,)?<virtualnamingcontext>$" "$1<realnamingcontext>" ":"
402 # empty filter rule
403 rwm-rewriteContext searchFilter
404 # all dataflow from server to client
405 rwm-rewriteContext searchEntryDN
406 rwm-rewriteRule "(.+,)?<realnamingcontext>$" "$1<virtualnamingcontext>" ":"
407 rwm-rewriteContext searchAttrDN alias searchEntryDN
408 rwm-rewriteContext matchedDN alias searchEntryDN
409 # misc empty rules
410 rwm-rewriteContext referralAttrDN
411 rwm-rewriteContext referralDN
412
413 # Everything defined here goes into the `default' context.
414 # This rule changes the naming context of anything sent
415 # to `dc=home,dc=net' to `dc=OpenLDAP, dc=org'
416
417 rwm-rewriteRule "(.+,)?dc=home,[ ]?dc=net$"
418 "$1dc=OpenLDAP, dc=org" ":"
419
420 # since a pretty/normalized DN does not include spaces
421 # after rdn separators, e.g. `,', this rule suffices:
422
423 rwm-rewriteRule "(.+,)?dc=home,dc=net$"
424 "$1dc=OpenLDAP,dc=org" ":"
425
426 # Start a new context (ends input of the previous one).
427 # This rule adds blanks between DN parts if not present.
428 rwm-rewriteContext addBlanks
429 rwm-rewriteRule "(.*),([^ ].*)" "$1, $2"
430
431 # This one eats blanks
432 rwm-rewriteContext eatBlanks
433 rwm-rewriteRule "(.*), (.*)" "$1,$2"
434
435 # Here control goes back to the default rewrite
436 # context; rules are appended to the existing ones.
437 # anything that gets here is piped into rule `addBlanks'
438 rwm-rewriteContext default
439 rwm-rewriteRule ".*" "${>addBlanks($0)}" ":"
440
441 # Rewrite the search base according to `default' rules.
442 rwm-rewriteContext searchDN alias default
443
444 # Search results with OpenLDAP DN are rewritten back with
445 # `dc=home,dc=net' naming context, with spaces eaten.
446 rwm-rewriteContext searchEntryDN
447 rwm-rewriteRule "(.*[^ ],)?[ ]?dc=OpenLDAP,[ ]?dc=org$"
448 "${>eatBlanks($1)}dc=home,dc=net" ":"
449
450 # Transform a DN value such that it can be used in a filter
451 rwm-rewriteMap escape dn2filter unescapedn escape2filter
452
453 # Bind with email instead of full DN: we first need
454 # an ldap map that turns attributes into a DN (the
455 # argument used when invoking the map is appended to
456 # the URI and acts as the filter portion)
457 rwm-rewriteMap ldap attr2dn "ldap://host/dc=my,dc=org?dn?sub"
458
459 # Then we need to detect DN made up of a single email,
460 # e.g. `mail=someone@example.com'; note that the rule
461 # in case of match stops rewriting; in case of error,
462 # it is ignored. In case we are mapping virtual
463 # to real naming contexts, we also need to rewrite
464 # regular DNs, because the definition of a bindDN
465 # rewrite context overrides the default definition.
466 #
467 # While actual email addresses tend not to contain filter
468 # special characters, the provided Bind DN has no such
469 # restrictions.
470 rwm-rewriteContext bindDN
471 rwm-rewriteRule "^(mail=)([^,]+@[^,]+)$"
472 "${attr2dn($1${dn2filter($2)})}" ":@I"
473
474 # This is a rather sophisticated example. It massages a
475 # search filter in case who performs the search has
476 # administrative privileges. First we need to keep
477 # track of the bind DN of the incoming request, which is
478 # stored in a variable called `binddn' with session scope,
479 # and left in place to allow regular binding:
480 rwm-rewriteContext bindDN
481 rwm-rewriteRule ".+" "${&&binddn($0)}$0" ":"
482
483 # A search filter containing `uid=' is rewritten only
484 # if an appropriate DN is bound.
485 # To do this, in the first rule the bound DN is
486 # dereferenced, while the filter is decomposed in a
487 # prefix, in the value of the `uid=<arg>' AVA, and
488 # in a suffix. A tag `<>' is appended to the DN.
489 # If the DN refers to an entry in the `ou=admin' subtree,
490 # the filter is rewritten OR-ing the `uid=<arg>' with
491 # `cn=<arg>'; otherwise it is left as is. This could be
492 # useful, for instance, to allow apache's auth_ldap-1.4
493 # module to authenticate users with both `uid' and
494 # `cn', but only if the request comes from a possible
495 # `cn=Web auth,ou=admin,dc=home,dc=net' user.
496 rwm-rewriteContext searchFilter
497 rwm-rewriteRule "(.*\\()uid=([a-z0-9_]+)(\\).*)"
498 "${**binddn}<>${&prefix($1)}${&arg($2)}${&suffix($3)}"
499 ":I"
500 rwm-rewriteRule "^[^,]+,ou=admin,dc=home,dc=net$"
501 "${*prefix}|(uid=${*arg})(cn=${*arg})${*suffix}" ":@I"
502 rwm-rewriteRule ".*<>$" "${*prefix}uid=${*arg}${*suffix}" ":"
503
504 # This example shows how to strip unwanted DN-valued
505 # attribute values from a search result; the first rule
506 # matches DN values below "ou=People,dc=example,dc=com";
507 # in case of match the rewriting exits successfully.
508 # The second rule matches everything else and causes
509 # the value to be rejected.
510 rwm-rewriteContext searchEntryDN
511 rwm-rewriteRule ".+,ou=People,dc=example,dc=com$" "$0" ":@"
512 rwm-rewriteRule ".*" "" "#"
513
515 The following directives map the object class `groupOfNames' to the ob‐
516 ject class `groupOfUniqueNames' and the attribute type `member' to the
517 attribute type `uniqueMember':
518
519 map objectclass groupOfNames groupOfUniqueNames
520 map attribute uniqueMember member
521
522 This presents a limited attribute set from the foreign server:
523
524 map attribute cn *
525 map attribute sn *
526 map attribute manager *
527 map attribute description *
528 map attribute *
529
530 These lines map cn, sn, manager, and description to themselves, and any
531 other attribute gets "removed" from the object before it is sent to the
532 client (or sent up to the LDAP server). This is obviously a simplistic
533 example, but you get the point.
534
536 /etc/openldap/slapd.conf
537 default slapd configuration file
538
540 slapd.conf(5), slapd-config(5), slapd-ldap(5), slapd-meta(5), slapd-re‐
541 lay(5), slapd(8), regex(7), re_format(7).
542
544 Pierangelo Masarati; based on back-ldap rewrite/remap features by
545 Howard Chu, Pierangelo Masarati.
546
547
548
549OpenLDAP 2.6.3 2022/07/14 SLAPO-RWM(5)