ForgeRock DS and the LDAP Relax Rules Control

In ForgeRock Directory Services 6.5, we’ve added the support for the LDAP Relax Rules Control, both on the server and our clients. One of my colleagues, involved with the customers’ deployment, asked me why we’ve added the control and what it should be used for.

The LDAP Relax Rules Control is an LDAP extension that allows a directory user agent (a client) to request the directory service to temporarily relax enforcement of various data and service model rules. The internet-draft is explicit about which rules can be relaxed or not. But typically it can be used to allow a client to write specific operational attributes that should be read-only and managed by the server.

Starting with OpenDJ 3.0, we’ve removed the ability to bulk import LDIF data to a server while preserving the existing data (the “append mode”). First, performing an import-ldif in append mode was breaking replication. The import needed to be applied to all replica, while no change was to happen on the new data. The process was cumbersome, especially when having multiple data-centers. But also, removing this feature allowed us to have a more generic interface and implement multiple backend using different underlying key-value stores.

But we have a few customers that have the need to seldom bulk load a large set of users to their directory service. In DS 6.0, we’ve added an option to speed bulk operations using ldapmodify or ldapdelete: –numConnections. Instead of serialising all updates or adds contained in an LDIF file, the tool will run them in parallel across multiple connections, while also controlling dependencies of changes. With this options, some of our customers have added several millions of users to their replicated directory services in minutes. By controlling the number of connections, one can also balance the need for speed of bulk loading data against the need to keep bandwidth for the regular client applications.

Doing bulk updates over LDAP is now fast, but some customers used the import process to also carry over some attributes that are usually managed by the directory server and thus read-only, such as the CreateTimeStamp, the CreatorsName.

And this is specifically what the Relax Rules Control is meant to allow.

So, if you have a need to bulk load large set of data, or synchronise over LDAP data from another server, and need to preserve some of the operational attribute, you can use the Relax Rules Control as illustrated below. Note that the OID for the control is but ForgeRock DS tools also recognise the RelaxRules string alias.

$ ldapmodify -p 1389 -D cn=directory\ manager -w secret12
-J RelaxRules:true --numConnections 4 ../50Kusers.ldif
ADD operation successful for DN uid=user.10021,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10022,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10001,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10020,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10026,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10025,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10024,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10005,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10033,ou=People,dc=example,dc=com
ADD operation successful for DN uid=user.10029,ou=People,dc=example,dc=com

Note that because the Relax Rules Control allows to override some of the rules enforced normally by the server, it’s important to control and restrict which clients or users are allowed to make use of it. In ForgeRock DS, you would use ACIs (global or not) to define who has permission to use the control. Out of the box, only Directory Manager can, because it has the bypass access controls privilege. Check the “Use Control or Extended Operation” section of the Administration Guide for the details on how to allow a user to use a control.

About LDAP Syntaxes and backward compatibility…

In the LDAP information model, a syntax constrains the structure and format of attribute values. OpenDJ defines and implements a large number of syntaxes (you can discover them by reading the ldapSyntaxes attribute from the cn=Schema entry).

But infrequently, we receive enquiries on an obscure and non standard syntax, often in the form of “I’m having an error importing schema from this or that legacy directory server”, with an error message that ends with “No such syntax is configured for use in the Directory Server”.

As syntaxes are constraining the structure and format of attribute values, they are implemented as code, specifically Java code in OpenDJ. It’s possible to implement new syntaxes by implementing the org.opends.server.api.AttributeSyntax abstract class, and installing the classes or the JAR in OpenDJ classpath. But often, it’s easier and more convenient to define a syntax by configuration, and OpenDJ offers 3 possibilities to define new syntaxes. In term of backward compatibility, I will only focus on the 2 main ones, by substitution and by pattern (the 3rd one allows to define enumeration of values).

With OpenDJ, you can define a new syntax by configuration and delegating the contraints to an already implemented syntax. A simple example is the URI syntax (which was defined is some very old schema with the OID A URI is really an ASCII string, and it might be sufficient to accept attributes with URI syntax to verify that all characters are pure ASCII. The standard syntax for ASCII strings is IA5String aka

ldapSyntaxes: ( DESC ‘URI’ X-SUBST ‘’ )

Insert the above line in the schema LDIF file before the attributeTypes, and you’re done.

The other option is to define the syntax as a pattern, using regular expressions. This could be better when willing to enforce additional constraints on an URI, for example, verifying that the URI is an LDAP one.

ldapSyntaxes: ( 999.999.999.1 DESC 'LDAP URI Syntax' X-PATTERN '^ldap://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]' )

So the next time you are trying to import some legacy schema to the OpenDJ directory server, and you have an error due to missing syntaxes, you know what to do to quickly resolve the problem.