Chapter 3. Configuring Plug-ins

After compiling the server plug-in, configure the Red Hat Directory Server so that it correctly loads the plug-in. The following sections describe this process.

3.1. Creating a Plug-in Configuration File

To add the plug-in to the Directory Server configuration, you need to create an LDIF representation of the plug-in entry, add the plug-in entry to the Directory Server configuration, and reload the server configuration. This section illustrates how to create the plug-in entry. Section 3.3, “Loading the Plug-in Configuration File” explains how to add the plug-in entry to the Directory Server configuration and reload the server configuration.

Important

Any custom plug-in files must be located in the default plug-ins directory, install_directory/ldapserver/ldap/servers/plugins on Red Hat Enterprise Linux 7. SELinux policies set rules on what directories the Directory Server processes are allowed to access, and any required files (such as plug-ins) must be in the default directories or the server cannot load them.
If the plug-in files are not in the default location, then the SELinux policies must be manually updated to include the alternate location.
The plug-in configuration file must be an LDIF file written in ASCII format. The following listing shows the contents of an example plug-in configuration file.

Example 3.1. An Example Plug-in Configuration File

dn: cn=Example Plug-in,cn=plugins,cn=config
objectclass: top
objectclass: nsSlapdPlugin
objectclass: extensibleObject
cn: Example Plug-in
nsslapd-pluginpath: /servers/lib/test-plugin.so
nsslapd-plugininitfunc: searchdn_preop_init
nsslapd-plugintype: preoperation
nsslapd-pluginenabled: on
nsslapd-pluginid: Example Pre-operation Plug-in
nsslapd-pluginversion: 1.0
nsslapd-pluginvendor: Example Corporation
nsslapd-plugindescription: This plug-in does ...
nsslapd-pluginPrecedence: 1
This example plug-in configuration file defines a plug-in as follows:
  • Line 1 sets the DN of the plug-in, which identifies the plug-in:
    dn: cn=Example Plug-in,cn=plugins,cn=config
    Here, the common name of the plug-in is set to Example Plug-in. The remainder of the DN entry (cn=plugins,cn=config) places the entry in the database tree that contains the configuration settings for plug-ins.
  • Lines 2-4 declare the object classes of the plug-in.
  • Line 5 sets the common name of the plug-in to Example Plug-in.
  • Line 6 defines the absolute path to the library that implements the plug-in:
    nsslapd-pluginpath:/servers/lib/test-plugin.so
  • Line 7 identifies the initialization function that the server calls to register the plug-in. In this example, the initialization is set to searchdn_preop_init. For information on implementing initialization functions, refer to Section 2.2, “Writing Plug-in Initialization Functions”.
  • Line 8 specifies the type of plug-in. In this case, it is a pre-operation plug-in. For a complete list of the types of plug-in you can declare, refer to Section 3.1.3, “Summary of Plug-in Directives”.
  • Line 9 specifies whether the plug-in is active by default. The nsslapd-pluginenabled attribute can have a value of either on or off. The following line specifies that the plug-in is active by default:
    nsslapd-pluginenabled: on
    The Directory Server Console can also activate or deactivate the plug-in after it has been loaded.

    Note

    Whenever plug-in configuration is edited — as when a plug-in is activated or deactived — then the server must be restarted for the plug-in changes to take effect.
  • Line 10 uses the nsslapd-pluginid attribute to set the name of the plug-in. The name that you specify here will show up in the Directory Server Console. In this example, the plug-in identification is set to Example Pre-operation Plug-in.
  • Line 11 sets the version number of the plug-in. This version number is also displayed in the Directory Server Console and is used to track the version of the distributed plug-in. It does not indicate the Directory Server compatibility; this is defined by the plug-in version number described in Section 2.2.1, “Specifying Directory Server Compatibility”.
  • Line 12 identifies the vendor or author of the plug-in. In the following line, the vendor is set to Example Corporation:
    nsslapd-pluginvendor: Example Corporation
  • Line 13 sets the description of the plug-in. This is the description visible through the Directory Server Console.
  • Line 14 sets the plug-in precedence. This defines the priority that the plug-in has in the execution order of plug-ins for an operation.

3.1.1. Setting Plug-in Dependencies

A plug-in can be dependent on one or more different plug-ins. Any specified plug-in dependencies must start correctly before the associated plug-in will start.
There are two attributes in the plug-in configuration file that specify the dependencies of the plug-in:
  • nsslapd-plugin-depends-on-named
  • nsslapd-plugin-depends-on-type
Each of these attributes can take multiple values, meaning that the plug-in depends on one or more other plug-ins.

3.1.1.1. Specific Plug-in Dependencies

If you specify the nsslapd-plugin-depends-on-named attribute in the plug-in configuration file, set its value to the names of one or more plug-ins. For example, in the plug-in configuration file, you could specify the following:
nsslapd-plugin-depends-on-named: my_pluginA 
nsslapd-plugin-depends-on-named: vendor_pluginB
In this example, the plug-in depends on two specifically named plug-ins: my_pluginA and vendor_pluginB. This configuration line indicates that before the plug-in can be loaded, the two specifically named plug-ins must be loaded. If either of these two plug-ins fails to load, the Directory Server will exit with a -1 error code.

3.1.1.2. Plug-in Type Dependencies

If you specify the nsslapd-plugin-depends-on-type attribute in the plug-in configuration file, set its value to one or more plug-in types. For example, in the plug-in configuration file, you could specify the following:
nsslapd-plugin-depends-on-type: syntax
This configuration line indicates that the plug-in depends on any plug-in of the type syntax. If there is a configured plug-in of type syntax, it must be successfully loaded before the plug-in can be loaded; otherwise, the Directory Server will exit with a -1 error code.
If you specify a plug-in type dependency, the Directory Server will search for any and all plug-ins of the types specified. If none are found, processing will continue without errors. However, the Directory Server must load all plug-ins of the types specified before it can load the plug-in. For a complete list of the supported plug-in types, refer to the Section 3.1.3, “Summary of Plug-in Directives”.

3.1.2. Specifying the Order of Plug-ins

Generally, plug-ins are not called in a specific order. As in, it is not possible to define that Preoperation Plug-in A is always called before Preoperation Plug-in B. Ideally, plug-ins should be written so that they function correctly irrespective of the order in which they are called.
It can be convenient, however, to set one plug-in to complete its job before the next plug-in is executed. This can allow more complex interactions between plug-ins and more specific functionality for plug-ins.
To set a general plug-in order (within a plug-in type), define a precedence for a plug-in. The precedence sets a value (between 1 and 99) on the plug-in priority, and high-priority plug-ins are called and completed first, going down the line in precedence. The default, if no precedence is set, is 50.
Plug-in precedence sets the execution order for plug-ins of the same type. A precedence of 5 on a preoperation plug-in only matters when other preoperation plug-ins are called of an operation. It doesn't affect the execution order of other types of plug-ins called in the operation.
The plug-in precedence is set in the nsslapd-pluginPrecedence attribute.
nsslapd-pluginPrecedence: 12
Although the plug-in precedence can be set on any plug-in, it is really only relevant for preoperation and postoperation plug-ins. Other plug-in types, like extended operation or matching rule plug-ins, implement callbacks to support specific data types or operations, rather than being called with all other plug-ins of that time for normal LDAP operations.

Note

Plug-in precedence is not the same as plug-in dependence. Dependencies determine the plug-in startup and shutdown order. Precedence determines the execution order for plug-ins in LDAP operations. The plug-in dependencies do not affect the plug-in precedence, and vice versa.
The server loads plug-ins of the same precedence in alphabetical order, determined by standard ASCII ordering of the cn value of the plug-in entry. (The cn appears in the plug-in configuration entry under cn=plugins,cn=config in the dse.ldif file.) Therefore, plug-in names can be used as an extra control measure for the order that plug-ins are loaded and executed.

3.1.3. Summary of Plug-in Directives

The following table summarizes the different types of plug-ins that you can specify in the plug-in configuration file.

Table 3.1. Directives for Specifying Different Plug-in Types

Directive Description Example of use
entryfetch Declares an entry fetch plug-in, which is called by the server after retrieving an entry from the default backend database. If you encrypt data with an entry store plug-in function before saving the data to the database, you can define an entry_fetch function that decrypts data after reading it from the database.
entrystore Declares an entry store plug-in, which is called by the server before saving an entry to the default backend database. (If you are writing your own database plug-in, you do not need to use this plug-in.) You can define an entry_store function to encrypt data before saving the data to the database.
extendedop Declares an extended operation plug-in, which is called by the server when receiving a request for an extended operation from a client. Three common server operations use extended operation plug-ins:
  • StartTLS (start_tls_extop.c)
  • Password Change (passwd_extop.c)
  • Replication (plugins/replication/)
matchingRule Declares a matching rule plug-in, which is called by the server when receiving a search request with an extensible matching search filter from a client. This type of plug-in is also called by the server when indexing attributes for the backend database.
postoperation Declares a post-operation/data notification plug-in, which is called by the server after performing an LDAP operation. You can define a data_notification function to send notification to the administrator if certain data has changed.
preoperation Declares a pre-operation/data validation plug-in, which is called by the server before performing an LDAP operation. You can define a data_validation function to check new entries before they are added to the directory.
syntax Declares a syntax plug-in, which is called by the server when getting a list of possible candidates for a search, when determining how to compare values in searches, and when adding or deleting values from certain attribute indexes. You can define a function that specifies how the equals comparison works for case-insensitive strings.
object Declares an object plug-in. Object plug-ins can install SLAPI_PLUGIN_START_FN, SLAPI_PLUGIN_CLOSE_FN, and SLAPI_PLUGIN_POSTSTART_FN functions. They can also use the slapi_register_plugin() call to register any other kind of plug-in. Object plug-ins are typically used to simplify configuration of a group of related plug-ins (one entry under cn=config instead of many). You can use this plug-in type when the plug-in does not fit in any of the other types listed in this table. For example, if the plug-in does performs more than one operation, then you should use this directive. This type of plug-in will typically register the types of operations it wants to handle using the internal API.
pwdstoragescheme This defines a new hashing scheme for passwords. This kind of plug-in can be used to add support for hashing or encrypting passwords with a method that is not otherwise supported in Directory Server.
bepreoperation The back end pre-operation plug-in is called after the pre-operation plug-ins and before the operation is applied to the back end.  
bepostoperation The back end post-operation plug-in is called after the back end was applied to the operation.  
betxnpreoperation The back end transaction pre-operation plug-in is called after the bepreoperation plug-ins. If a plug-in returns a failure, the entire operation is aborted.  
betxnpostoperation The back end transaction post-operation plug-in is called after the bepostoperation plug-ins. If a plug-in returns a failure, the entire operation is aborted.