This document describes different ways to simplify the use and deployement of filter rewriters and computed attributes

#Overview

Directory servers plugin API supports filter rewriters (slapi_compute_add_search_rewriter) and computed attributes (slapi_compute_add_evaluator). Those plugin-API functions register callbacks that will be called at specific points of a SRCH request. A developper must write the callbacks funtions and in addition a new plugin (init, start, stop, config functions) that registers the callbacks and finally configure the plugin.

This document describes two approaches to simplify the use of those API interfaces

a generic plugin that handle all the plugin requirements. Then the developper only has to write the callbacks and let the plugin registers them (via a configuration entry).

#Use Cases

DS contains group with ‘member’ attribute as membership attribute. An application (i.e. vsphere) needs to lookup those groups assuming those group contain ‘uniquemember’ attributes and expect to receive entries with ‘uniquemember’. For a developper one option to get this result is to write a new plugin and configure it. The plugin starting function registering filter rewriters (‘uniquemember’ -> ‘member’) and computed attributes (‘member’ -> ‘uniquemember’) callbacks. It would be much easier for the developper to simply write the callbacks and configure the server to load them.

Another case is a use of shortcut values in filters. An AD application sends filter with objectCategory=foo. AD application expects the filter to be rewrite into objectCategory=cn=foo,cn=schema,…. The developper will write the callback function and update the generic plugin configuration to register this callback as a filter rewriter.

#Design

The slapi_compute_add_search_rewriter and slapi_compute_add_evaluator functions registers callbacks. They are part of plugin API but it can be called from plugin or from core server. A first approach is to create a generic plugin that retrieves callback from its configuration and registers them. A second approach is to enhance core server so that it retrieves callbacks from server config and register them.

Generic plugin

The advantage of a generic plugin is that it benefit from the plugin framework, such as retrieval/load of entry point, dependencies and enable/disable capability

Configuration entries

The generic plugin configuration entry is

cn=srchRewriter,cn=plugins,cn=config
objectClass: top
objectClass: nsSlapdPlugin
objectClass: extensibleObject
nsslapd-pluginPath: libsrchRewrite-plugin
nsslapd-pluginInitfunc: srchRewriter_init
nsslapd-pluginType: object
nsslapd-pluginEnabled: on
nsslapd-plugin-depends-on-type: database
nsslapd-pluginId: srchRewriter
nsslapd-pluginVersion: 1.4.3
nsslapd-pluginVendor: 389 Project
nsslapd-pluginDescription: Register filter and computed attribute rewriters
cn: srchRewriter

rewriters subentries

The generic plugin configuration entry has children. Each child defines the application specific rewriters (filter or computed attributes). Rewriters are multivalued attributes. Note that the order of execution of the rewriters is not defined.

cn=ADrewrite,cn=srchRewriter,cn=plugins,cn=config
objectClass: top
objectClass: extensibleObject
cn: ADrewrite
nsslapd-libPath: libadrewrite-plugin
nsslapd-filterRewriter: objectcategory_filter_rewrite
nsslapd-filterRewriter: objectSID_rewrite
nsslapd-returnedAttrRewriter: givenname_returnedAttr_rewrite
nsslapd-returnedAttrRewriter: objectcategory_returnedAttr_rewrite

callback registration

At startup, when the generic plugin is enabled, it calls the plugin startup function. The function reads the generic plugin children and for each of them, it retrieves the shared library nsslapd-libPath (either absolute path or relative to /lib/dirsrv/plugin). Then the startup function loads the callback in nsslapd-filterRewriter or nsslapd-returnedAttrRewriter. Then nsslapd-filterRewriter callbacks are registered as filter rewriter (slapi_compute_add_search_rewriter) while nsslapd-returnedAttrRewriter are registered as computed attributes (slapi_compute_add_evaluator).

Core server

Configuration entries

During server startup, children of cn=rewriters,cn=config will be loaded and callback registered

cn=rewriters,cn=config
objectClass: top
objectClass: extensibleObject
cn: rewriters

cn=ADrewrite,cn=rewriters,cn=config
objectClass: top
objectClass: extensibleObject
cn: ADrewrite
nsslapd-libPath: libadrewrite
nsslapd-filterRewriter: objectcategory_filter_rewrite
nsslapd-filterRewriter: objectSID_rewrite
nsslapd-returnedAttrRewriter: givenname_rewrite
nsslapd-returnedAttrRewriter: objectcategory_returnedAttr_rewrite

cn=vsphere,cn=rewriters,cn=config
objectClass: top
objectClass: extensibleObject
cn: vsphere
nsslapd-libPath: libvsphere
nsslapd-filterRewriter: uniquememeber_filter_rewrite
nsslapd-returnedAttrRewriter: member_returnedAttr_rewrite

callback registration

At server startup, once all plugins have been started, a rewriter_init function reads cn=rewriters,cn=config children and for each of them, it retrieves/load the shared library nsslapd-libPath (either absolute path or relative to /lib/dirsrv/plugin). Then nsslapd-filterRewriter callbacks are registered as filter rewriter (slapi_compute_add_search_rewriter) while nsslapd-returnedAttrRewriter are registered as computed attributes (slapi_compute_add_evaluator).

Performance consideration

Implementing rewriter enhance virtual attribute support (in addition to cos, slapi-nis, views, roles..). It has always been a long debate if an attribute needs to be virtual or real. There is no final decision but advantages/drawback that need to be evaluated for both options

virtual attributes

Virtual attributes can accelerate the write path of the server. Indeed virtual attribute may be completely ignored during write operation or sometime trigger a cache update that is rapid and do not impact write. The drawback is that there is no index for the attribute.

Virtual attribute makes the search more expensive. Filter can be transformed, components with virtual attribute are not indexed. Virtual attribute need to generated on the fly (service provider or computed attribute) in candidate entries and filter systematically reevaluated.

Virtual attribute allows to give different “views” of a same database. So without the need to modify all the entries virtual attributes allow to match LDAP client needs. This means the admin can avoid a fixup phase to update all the entries to be used by a specific application. It also avoid additional updates (mep, memberof) that impact response time and replication trafic of those additional updates.

It introduces some “magic” in the server that make things more complex to understand, support and maintain.

real attributes

Real attributes are simple to understand, support and maintain. They impact write response time because it increases the size of the update and possibly trigger additional updates.

The benefit is that real attributes are indexed and accelerate SRCH operations.

If several “views” are required to match some application needs, this is at the cost of extra updates and possibly fixup phase.

Final database result is larger DB files that can impact disk space and backup/restore tasks.

Implementation

A prototype (generic plugin) was discussed with 50931

Major configuration options and enablement

Updates and Upgrades

No impact on update/upgrades

Dependencies

rewriter shared library should be loadable by DS core server

External Impact

389-ds project is not responsible of external rewriters

Author

tbordaz@redhat

Last modified on 17 March 2020