Plug-in Programmer’s Guide
Red Hat Directory Server                                                            

Previous
Contents
Index
Next

Chapter 11

Writing Matching Rule Plug-ins


This chapter explains how to write plug-in functions that handle matching rules.

Matching rule plug-in functions are described in the following sections:

Understanding Matching Rules

A matching rule specifies how one or more attributes of a particular syntax should be compared against assertion values. For example, a matching rule that specifies a "sound-alike" comparison attempts to match values that sound like the specified value. Each matching rule is identified by a unique OID (for example, "1.2.3.4").

LDAPv3 clients can specify a matching rule as part of a search filter in a search request. This type of search filter is called an extensible match filter.

Extensible Match Filters

In an extensible match filter, the client specifies that it wants to use the matching rule to compare a specified value against the values of entries in the directory. (For example, an extensible match filter might find all entries in which the sn attribute "sounds like" melon.)

An extensible match filter contains the following information:

For example, if the OID 1.2.3.4 identifies a matching rule that performs "sounds like" matches, the following extensible match filter attempts to find entries where the mail attribute "sounds like" moxie.

(mail:1.2.3.4:=moxie)
 

In the search filter, the client can specify the OID (that identifies a matching rule) and the attribute type. This indicates that the value in the filter should be compared against the attribute using the matching rule.

For example, if the OID 1.2.3.4 specifies a "sound-alike" match and if the string representation of the search filter is:

(uid:1.2.3.4:=moxie)
 

the client wants to find entries in which the value of the uid attribute sounds like moxie.

Although the LDAPv3 standard allows clients to omit the OID or the attribute type, at this time, the Red Hat Directory Server only supports extensible match filters that specify both the OID and attribute type.

The filter can also specify a preference indicating whether to search the attributes in the DN as well. For example, if the OID 1.2.3.4 specifies a "sound-alike" match and if the string representation of the search filter is

(sn:dn:1.2.3.4:=moxie)
 

then the client wants to find all entries in which the value of the sn attribute or the attributes in the DN (for example, uid, cn, ou, or o) sound like moxie.

Extensible Match Filters in the Directory Server

Directory Serveralready includes support for certain matching rules, which are used to determine the collation order and operator for searches of international data.

You can enable the Directory Server to handle your own matching rules for extensible match searches by defining your own matching rules plug-ins and registering them with the server.

You can also build indexes to improve the performance of search operations that use extended match filters.

Understanding Matching Rule Plug-ins

A matching rule plug-in can create filters that the server can use when handling extensible search filters. A matching rule plug-in can also create indexers to index entries for extensible searches.

Functions Defined in Matching Rule Plug-ins

The matching rule plug-in consists of the following:

When the server starts up and loads the matching rule plug-in, it calls the initialization function. In this function, you pass the server the pointers to the factory functions and the close function. The server calls these functions when needed. See "How Matching Rules Are Identified," on page 134, and "How the Server Associates Plug-ins with OIDs," on page 135, for details.

How Matching Rules Are Identified

Matching rules are identified by OID. When the server encounters an OID in the following situations, it attempts to find the matching rule plug-in that handles the matching rule with that OID.

The server can encounter a matching rule OID in the following situations:

index attribute_name  filter_type  matching_rule_oid
 
If the OID is associated with a matching rule plug-in, the server adds this OID to the list of matching rule OIDs to use for indexing.
For information on setting up the server to index based on matching rule, see "Indexing Based on Matching Rules," on page 137.
(sn:dn:1.2.3.4:=Jensen)
 
The search filter above specifies that the server should use the matching rule identified by the OID 1.2.3.4 to search for the value Jensen in the sn attribute and in all attributes in the DN.
For information on setting up the server to handle extensible match filters, see "Handling Extensible Match Filters," on page 142.
For information on setting up the server to sort based on matching rules, see "Handling Sorting by Matching Rules," on page 150.

In all of these situations, the server uses the matching rule OID to find the plug-in responsible for handling the rule. See "How the Server Associates Plug-ins with OIDs," on page 135, for details.

How the Server Associates Plug-ins with OIDs

When the server encounters the OID for a matching rule, it attempts to find the plug-in associated with that matching rule.

If no plug-in is associated with the matching rule, the server calls each matching rule plug-in to find one that handles the specified matching rule.

When the server finds a plug-in that handles the matching rule, the server creates an association between the plug-in and the matching rule OID for future reference.

If no matching rule plug-in supports the specified OID, the server returns an LDAP_UNAVAILABLE_CRITICAL_EXTENSION error back to the client.

Finding a Plug-in for Indexing

To determine which matching rule plug-in is responsible for indexing an attribute with a given matching rule (based on its OID), the server does the following for each plug-in:

  1. In a new Slapi_PBlock parameter block, the server sets the OID in the SLAPI_PLUGIN_MR_OID parameter.
  2. Next, the server calls the indexer factory function (specified in the SLAPI_PLUGIN_MR_INDEXER_CREATE_FN parameter) for the plug-in.
  3. The server checks the SLAPI_PLUGIN_MR_INDEX_FN parameter.
    • If the parameter is NULL, the plug-in does not handle the matching rule specified by that OID.
    • If the parameter returns an indexer function, this plug-in handles the matching rule specified by that OID.
  4. Finally, the server frees the parameter block from memory.

At some point in time, the server may also call the indexer destructor function (specified in the SLAPI_PLUGIN_MR_DESTROY_FN parameter) to free the indexer object that was created by the indexer factory function.

Finding a Plug-in for Searching

To determine which matching rule plug-in is responsible for handling an extensible match filter for a given matching rule (based on its OID), the server does the following for each plug-in:

  1. In a new Slapi_PBlock parameter block, the server sets the following parameters:
    • Sets the OID in the SLAPI_PLUGIN_MR_OID parameter.
    • Sets the type (from the filter) in the SLAPI_PLUGIN_MR_TYPE parameter.
    • Sets the value (from the filter) in the SLAPI_PLUGIN_MR_VALUE parameter.
  2. Next, the server calls the filter factory function (specified in the SLAPI_PLUGIN_MR_FILTER_CREATE_FN parameter) for the plug-in.
  3. The server checks the SLAPI_PLUGIN_MR_FILTER_MATCH_FN parameter.
    • If the parameter is NULL, the plug-in does not handle the matching rule specified by that OID.
    • If the parameter returns a filter matching function, this plug-in handles the matching rule specified by that OID.
  4. Finally, the server gets the following information from the plug-in for future use:
    • The filter index function specified in the SLAPI_PLUGIN_MR_FILTER_INDEX_FN parameter.
    • The value specified in the SLAPI_PLUGIN_MR_FILTER_REUSABLE parameter.
    • The filter reset function specified in the SLAPI_PLUGIN_MR_FILTER_RESET_FN parameter.
    • The filter object specified in the SLAPI_PLUGIN_OBJECT parameter.
    • The filter destructor function specified in the SLAPI_PLUGIN_DESTROY_FN parameter.

Information specified in the filter object is used by both the filter index function and the filter matching function.

How the Server Uses Parameter Blocks

The server uses parameter blocks as a means to pass information to and from plug-in functions.

When calling your matching rule plug-in functions, the server will create a new Slapi_PBlock parameter block, set some input parameters, and pass the parameter block to your function. After retrieving output parameters from the block, the server typically frees the parameter block from memory.

In general, you should not expect a parameter block to be passed from plug-in function to plug-in function. The value of a parameter set by one plug-in function may not necessarily be accessible to other plug-in functions since each function is usually passed a new and different parameter block.

Indexing Based on Matching Rules

This section explains how to set up the server to index entries using a matching rule. The following topics are covered:

You also need to define an initialization function to register your indexer factory function.

How the Server Sets Up the Index

When the server encounters a matching rule OID in an index directive in the server configuration file, the server determines which plug-in supports the matching rule identified by the OID. See "How the Server Associates Plug-ins with OIDs," on page 135, for details.

The server gets the OID returned in the SLAPI_PLUGIN_MR_OID parameter and associates this OID with the rest of the attribute indexing information (such as the attribute type and the type of index) for future reference.

When adding, modifying, or deleting the values of an attribute, the server will check this information to determine if the attribute is indexed. See "How the Server Updates the Index," on page 138, for information on how attributes are indexed.

How the Server Updates the Index

When a value is added, modified, or removed from an attribute in an entry (or when the RDN of an entry is changed), the server does the following if that attribute has an index that uses matching rules:

  1. In a new Slapi_PBlock parameter block, the server sets the following parameters:
    • Sets the OID in the SLAPI_PLUGIN_MR_OID parameter.
    • Sets the attribute type (of the value being added, modified, or removed) in the SLAPI_PLUGIN_MR_TYPE parameter.
  2. Next, the server calls the indexer factory function (specified in the SLAPI_PLUGIN_MR_INDEXER_CREATE_FN parameter) for the plug-in to create the indexer object.
  3. The server generates the index keys for the values to be added or deleted:
    • The server first verifies that the SLAPI_PLUGIN_MR_INDEX_FN parameter specifies an indexer function and the SLAPI_PLUGIN_MR_OID parameter specifies the official OID of the matching rule.
    • If these are both set, the server sets the SLAPI_PLUGIN_MR_VALUES parameter to the array of berval structures containing the new or modified values that need to be indexed and calls the indexer function.
    • Next, the server gets the value of the SLAPI_PLUGIN_MR_KEYS parameter, which is an array of berval structures containing the keys corresponding to the values.
  4. The server inserts or deletes the keys and values in the index for that attribute.
  5. The server calls the indexer destructor function (specified in the SLAPI_PLUGIN_MR_DESTROY_FN parameter) to free the indexer object.

When the server is done, it frees any parameter blocks that were allocated during this process.

Writing the Indexer Factory Function

The indexer factory function takes a single Slapi_PBlock argument. This function should be thread-safe. The server may call this function concurrently.

The indexer factory function should do the following:

  1. Get the OID from the SLAPI_PLUGIN_MR_OID parameter, and determine whether that OID is supported by your plug-in.
    • If the OID is not supported, you need to return the result code LDAP_UNAVAILABLE_CRITICAL_EXTENSION.
    • If the OID is supported, continue with this process.
  2. Get the value of the SLAPI_PLUGIN_MR_USAGE parameter. This parameter should have one of the following values:
    • If the value is SLAPI_PLUGIN_MR_USAGE_SORT, the server is calling your function to sort search results. See "Handling Sorting by Matching Rules," on page 150, for more information.
    • If the value is SLAPI_PLUGIN_MR_USAGE_INDEX, the server is calling your function to index an entry.
You can use this information to set different information in the indexer object or to set a different indexer function, based on whether the function is being called to index or to sort.
  1. You can also get any data that you set in the SLAPI_PLUGIN_PRIVATE parameter during initialization. (See "Writing an Initialization Function," on page 151.)
  2. Create an indexer object containing any information that you want passed to the indexer function.
  3. Set the following parameters:
    • Set the SLAPI_PLUGIN_MR_OID parameter to the official OID of the matching rule (if the value of that parameter is not the official OID).
    • Set the SLAPI_PLUGIN_OBJECT parameter to the indexer object.
    • Set the SLAPI_PLUGIN_MR_INDEX_FN parameter to the indexer function. (See "Writing the Indexer Function," on page 141.)
    • Set the SLAPI_PLUGIN_DESTROY_FN parameter to the function responsible for freeing any memory allocated by the factory function, such as the indexer object. See "Writing a Destructor Function," on page 151, for details.
  4. Return 0 (or the result code LDAP_SUCCESS) if everything completed successfully.

Getting and Setting Parameters in Indexer Factory Functions

The following table summarizes the different parameters that the indexer factory function should get and set in the parameter block that is passed in.

Table 11-1 Input and Output Parameters Available to an Indexer Factory Function  
Parameter Name
Data Type
Description
SLAPI_PLUGIN_MR_OID
char *
Input parameter. Matching rule OID (if any) specified in the index directive.
SLAPI_PLUGIN_MR_TYPE
char *
Input parameter. Attribute type (if any) specified in the index directive.
SLAPI_PLUGIN_MR_USAGE
unsigned int
Input parameter. Specifies the intended use of the indexer object. This parameter can have one of the following values:
  • SLAPI_PLUGIN_MR_USAGE_INDEX specifies that the indexer object should be used to index entries.
  • SLAPI_PLUGIN_MR_USAGE_SORT specifies that the indexer object should be used to sort entries.
You can use this to specify different information in the indexer object or different indexer functions, based on whether the plug-in is used for indexing or sorting.
For information on sorting search results, see "Handling Sorting by Matching Rules," on page 150.
SLAPI_PLUGIN_PRIVATE
void *
Input parameter. Pointer to any private data originally specified in the initialization function. See "Writing an Initialization Function," on page 151, for details.
SLAPI_PLUGIN_MR_OID
char *
Output parameter. Official matching rule OID of the index.
SLAPI_PLUGIN_MR_INDEX_FN
void *
(function pointer)
Output parameter. Name of the function called by the server to generate a list of keys used for indexing a set of values.
SLAPI_PLUGIN_DESTROY_FN
void *
(function pointer)
Output parameter. Name of the function to be called to free the indexer object.
SLAPI_PLUGIN_OBJECT
void *
Output parameter. Pointer to the indexer object created by your factory function.

Writing the Indexer Function

The indexer function takes a single Slapi_PBlock argument. This function will never be called for the same indexer object concurrently. (If you plan to manipulate global variables, keep in mind that the server can call this function concurrently for different indexer objects.)

The indexer function should do the following:

  1. Get the values of the following parameters:
    • Get the indexer object from the SLAPI_PLUGIN_OBJECT parameter (if the parameter is set).
    • Get the array of values that you want indexed from the SLAPI_PLUGIN_MR_VALUES parameter.
  2. Generate index keys for these values, and set the SLAPI_PLUGIN_MR_KEYS parameter to the array of these keys.
  3. Return 0 (or the result code LDAP_SUCCESS) if everything completed successfully.

The server adds or removes the keys and the corresponding values from the appropriate indexes.

Getting and Setting Parameters in Indexer Functions

The following table summarizes the different parameters that the indexer function should get and set in the parameter block that is passed in.

Table 11-2 Input and Output Parameters Available to an Indexer Function  
Parameter Name
Data Type
Description
SLAPI_PLUGIN_MR_VALUES
struct berval **
Input parameter. Pointer to an array of berval structures containing the values of the entry's attributes that need to be indexed.
SLAPI_PLUGIN_OBJECT
void *
Input parameter. Pointer to the indexer object created by the indexer factory function. See "Writing the Indexer Factory Function," on page 139, for details.
SLAPI_PLUGIN_MR_KEYS
struct berval **
Output parameter. Keys generated for the values specified in the SLAPI_PLUGIN_MR_VALUES parameter. The server creates indexes using these keys.

Handling Extensible Match Filters

This section explains how to set up the server to process searches that use extensible match filters (matching rules). The following topics are covered:

You also need to define an initialization function to register your filter factory function.

How the Server Handles the Filter

When the server processes a search request that has an extensible match filter, the server does the following:

  1. First, the server finds the plug-in associated with this OID, if an association between the OID and plug-in has already been made.
If no association has been made yet, the server attempts to find a matching rule plug-in that handles the OID. See "How the Server Associates Plug-ins with OIDs," on page 135, for details.
  1. Next, the server attempts to generate a list of search result candidates from the indexes. In a new Slapi_PBlock parameter block, the server does the following:
    • The server puts the filter object in the SLAPI_PLUGIN_OBJECT parameter and calls the filter index function (specified in the SLAPI_PLUGIN_MR_FILTER_INDEX_FN parameter).
    • The server checks the value of the SLAPI_PLUGIN_MR_QUERY_OPERATOR parameter. If the operator is a known type (such as SLAPI_OP_EQUAL), the server will use the operator when searching the index for candidates. For details, see "Query Operators in Matching Rules," on page 144.
    • The server sets the SLAPI_PLUGIN_MR_VALUES parameter to each of the values specified in the filter and calls the indexer function (which is specified in the SLAPI_PLUGIN_MR_INDEX_FN parameter) to generate the key (specified in the SLAPI_PLUGIN_MR_KEYS parameter).
    • The server uses the keys and the query operator to find potential candidates in the indexes.
The server considers all entries to be potential candidates if at least one of the following is true:
  • The matching rule plug-in has no indexer function (specified in the SLAPI_PLUGIN_MR_INDEX_FN parameter).
  • No index applies to the search (for example, if the query operator does not correspond to an index).
  • No keys are generated for the specified values.
  1. For each candidate entry, the server checks to see if the entry matches the search filter by doing the following:
    • The server calls the filter matching function (which is specified in the SLAPI_PLUGIN_MR_FILTER_MATCH_FN parameter), passing in the filter object, the entry, and the attributes of the entry.
    • If the entry does not match but the search request also specifies that the attributes in the DN should be searched, the server calls the filter matching function again, passing in the filter object, the entry, and the attributes in the DN.
The server checks the value returned by the filter matching function:
  • If the function returns 0, the entry matched the search filter.
  • If the function returns -1, the entry did not match the search filter.
  • If the function returns an LDAP error code (a positive value), an error occurred.
  1. If the entry matches the filter, the server verifies that the entry is in the scope of the search before returning the entry to the LDAP client as a search result.

Query Operators in Matching Rules

As mentioned in "How the Server Handles the Filter," on page 143, the server uses a query operator when searching the index for possible candidates.

This applies to the ldbm default backend database. If you are using your own backend or if you have not set up indexing by matching rules, the server does not make use of the query operator.

The server checks the value of the SLAPI_PLUGIN_MR_QUERY_OPERATOR parameter to determine which operator is specified. The following table lists the possible values for this parameter.

Table 11-3 Query Operators in Extensible Match Filters  
Operator
Description
SLAPI_OP_LESS
<
SLAPI_OP_LESS_OR_EQUAL
<=
SLAPI_OP_EQUAL
=
SLAPI_OP_GREATER_OR_EQUAL
>=
SLAPI_OP_GREATER
>

If the query operator is SLAPI_OP_EQUAL, the server attempts to find the keys in the index that match the value specified in the search filter. In the case of the other query operators, the server attempts to find ranges of keys that match the value.

Writing a Filter Factory Function

The filter factory function takes a single Slapi_PBlock argument. This function should be thread-safe. The server may call this function concurrently. (Each incoming LDAP request is handled by a separate thread. Multiple threads may call this function if processing multiple requests that have extensible match filters.)

The filter factory function should do the following:

  1. Get the OID from the SLAPI_PLUGIN_MR_OID parameter and determine whether that OID is supported by your plug-in.
    • If the OID is not supported, you need to return the result code LDAP_UNAVAILABLE_CRITICAL_EXTENSION. The server will send this back to the client.
    • If the OID is supported, continue with this process.
  2. Get and check the values of the SLAPI_PLUGIN_MR_TYPE and SLAPI_PLUGIN_MR_VALUE parameters.
The values of these parameters are the attribute type and value specified in the extensible match filter.
  1. You can also get any data that you set in the SLAPI_PLUGIN_PRIVATE parameter during initialization. See "Writing an Initialization Function," on page 151.
  2. Create a filter object, putting the following information in the object:
    • The official OID of the matching rule. Optional.
    • The attribute type specified in the filter.
    • The value specified in the filter.
    • Any additional data that you want made available to the filter index function (for example, the query operator, if specified in the filter).
The server will call your filter index function at a later time to extract this information from the filter object.
  1. Set the following parameters:
    • Set the SLAPI_PLUGIN_MR_OID parameter to the official OID of the matching rule if the value of that parameter is not the official OID. Optional.
    • Set the SLAPI_PLUGIN_OBJECT parameter to the filter object.
    • Set the SLAPI_PLUGIN_MR_FILTER_INDEX_FN parameter to the filter index function (cf. "Writing a Filter Index Function," on page 147) if you have set up indexes based on this matching rule. Optional.
    • Set the SLAPI_PLUGIN_MR_FILTER_MATCH_FN parameter to the filter matching function. See "Writing a Filter Matching Function," on page 149.
    • Set the SLAPI_PLUGIN_DESTROY_FN parameter to the function responsible for freeing the filter object, if you have defined this function. Optional. See "Writing a Destructor Function," on page 151, for details.
  2. Return 0 (or the result code LDAP_SUCCESS) if everything completed successfully.

Getting and Setting Parameters in Filter Factory Functions

The following table summarizes the different parameters that the filter factory function should get and set in the parameter block that is passed in.

Table 11-4 Input and Output Parameters Available to a Filter Factory Function  
Parameter Name
Data Type
Description
SLAPI_PLUGIN_MR_OID
char *
Input parameter. Matching rule OID (if any) specified in the extensible match filter.
SLAPI_PLUGIN_MR_TYPE
char *
Input parameter. Attribute type (if any) specified in the extensible match filter.
SLAPI_PLUGIN_MR_VALUE
struct berval *
Input parameter. Value specified in the extensible match filter.
SLAPI_PLUGIN_PRIVATE
void *
Input parameter. Pointer to any private data originally specified in the initialization function. See "Writing an Initialization Function," on page 151, for details.
SLAPI_PLUGIN_MR_FILTER_MATCH_FN
mrFilterMatchFn
(function pointer)
Output parameter. Name of the function called by the server to match an entry's attribute values against the value in the extensible search filter.
SLAPI_PLUGIN_MR_FILTER_INDEX_FN
void *
(function pointer)
Output parameter. Name of the function called by the server to generate a list of keys used for indexing a set of values.
SLAPI_PLUGIN_DESTROY_FN
void *
(function pointer)
Output parameter. Name of the function to be called to free the filter object.
SLAPI_PLUGIN_OBJECT
void *
Output parameter. Pointer to the filter object created by your factory function.

Writing a Filter Index Function

The filter index function takes a single Slapi_PBlock argument. This function will never be called for the same filter object concurrently. (If you plan to manipulate global variables, keep in mind that the server can call this function concurrently for different filter objects.)

The filter index function should do the following:

  1. Get the filter object from the SLAPI_PLUGIN_OBJECT parameter (if the parameter is set).
  2. Using data from the object, determine and set the values of the following parameters:
    • Set the SLAPI_PLUGIN_MR_OID parameter to the official OID of the matching rule.
    • Set the SLAPI_PLUGIN_MR_TYPE parameter to the attribute type in the filter object.
    • Set the SLAPI_PLUGIN_MR_VALUES parameter to the values in the filter object.
    • Set the SLAPI_PLUGIN_MR_QUERY_OPERATOR parameter to the query operator that corresponds to this search filter. See "Query Operators in Matching Rules," on page 144, for possible values for this parameter.
    • Set the SLAPI_PLUGIN_OBJECT parameter to the filter object.
    • Set the SLAPI_PLUGIN_MR_INDEX_FN parameter to the indexer function. See "Writing the Indexer Function," on page 141.
  3. Return 0 (or the result code LDAP_SUCCESS) if everything completed successfully.

Getting and Setting Parameters in Filter Index Functions

The following table summarizes the different parameters that the filter index function should get and set in the parameter block that is passed in.

Table 11-5 Input and Output Parameters Available to a Filter Index Function  
Parameter Name
Data Type
Description
SLAPI_PLUGIN_OBJECT
void *
Input and Output parameter. Pointer to the filter object created by the factory function. For details, see "Writing a Filter Factory Function," on page 145.
SLAPI_PLUGIN_MR_QUERY_OPERATOR
int
Output parameter. Query operator used by the server to determine how to compare the keys generated from SLAPI_PLUGIN_MR_VALUES and SLAPI_PLUGIN_MR_INDEX_FN against keys in the index.
For a list of possible values for this parameter, see "Query Operators in Matching Rules," on page 144.
SLAPI_PLUGIN_MR_OID
char *
Output parameter. Official matching rule OID (if any) specified in the extensible match filter.
SLAPI_PLUGIN_MR_TYPE
char *
Output parameter. Attribute type (if any) specified in the extensible match filter.
SLAPI_PLUGIN_MR_VALUES
struct berval **
Output parameter. Pointer to an array of berval structures containing the values specified in the extensible match filter.
SLAPI_PLUGIN_MR_INDEX_FN
void *
(function pointer)
Output parameter. Name of the function called by the server to generate a list of keys used for indexing a set of values.

Writing a Filter Matching Function

The filter matching function has the following prototype:

  #include "slapi-plugin.h"

  typedef int (*mrFilterMatchFn) (void* filter, 

    Slapi_Entry* entry, Slapi_Attr* attrs);
 

This function passes the following arguments:

This function will never be called for the same filter object concurrently. (If you plan to manipulate global variables, keep in mind that the server can call this function concurrently for different filter objects.)

The filter matching function should do the following:

  1. From the filter object, get the attribute type, the values, and the query operator.
  2. Find the corresponding attribute in the attributes passed into the function. Make sure to check for subtypes of an attribute (for example, cn=lang-ja) in the filter and in the attributes specified by attrs.
You can call the slapi_attr_type_cmp() function to compare the attribute in the filter against the attributes passed in as arguments.
  1. Using the query operator to determine how the values should be compared, compare the values from the filter against the values in the attribute.
  2. Return one of the following values:
    • 0 if the values of the attribute match the value specified in the filter.
    • -1 if the values don't match.
    • An LDAP error code (a positive number) if an error occurred.

Handling Sorting by Matching Rules

If you have set up indexing by a matching rule, you can also sort search results by that matching rule. The server can use the keys in the index to sort the search results.

When processing a request to sort by a matching rule, the server does the following:

  1. In a new Slapi_PBlock parameter block, the server sets the following parameters:
    • Sets the OID in the SLAPI_PLUGIN_MR_OID parameter.
    • Sets the attribute type (of the value being added, modified, or removed) in the SLAPI_PLUGIN_MR_TYPE parameter.
    • Sets the SLAPI_PLUGIN_MR_USAGE parameter to SLAPI_PLUGIN_MR_USAGE_SORT. (This indicates that the created indexer object will be used for sorting, not indexing.)
  2. Next, the server calls the indexer factory function (specified in the SLAPI_PLUGIN_MR_INDEXER_CREATE_FN parameter) for the plug-in.
  3. The server generates the index keys for the values to be sorted:
    • The server sets the SLAPI_PLUGIN_MR_VALUES parameter to the array of berval structures containing the values to be sorted.
    • The server calls the indexer function (specified by the SLAPI_PLUGIN_MR_INDEXER_FN parameter).
    • Next, the server gets the value of the SLAPI_PLUGIN_MR_KEYS parameter, which is an array of berval structures containing the keys corresponding to the values.
  4. The server compares the keys to sort the results.

Writing a Destructor Function

The server calls the destructor function to free any memory that you've allocated; for example, to the indexer object or the filter object.

The destructor function takes a single Slapi_PBlock argument. The following table summarizes the different parameters that the destructor function should get and set in the parameter block that is passed in.

Table 11-6 Input and Output Parameters Available to a Destructor Function
Parameter Name
Data Type
Description
SLAPI_PLUGIN_OBJECT
void *
Input parameter. Pointer to the filter object or indexer object created by your factory function.

For example, your destructor function can get the indexer object from the SLAPI_PLUGIN_OBJECT parameter and free the object from memory.

This function will never be called for the same indexer or filter object concurrently. (If you plan to manipulate global variables, keep in mind that the server can call this function concurrently for different filter or indexer objects.)

Writing an Initialization Function

Internally, the server keeps a list of matching rule plug-ins. When dealing with matching rules, the server attempts to find the matching rule plug-in to handle the given matching rule. See "How the Server Associates Plug-ins with OIDs," on page 135, for details.

In order to add your plug-in to that internal list, you need to write an initialization function. The initialization function takes a single Slapi_PBlock argument. The function should set the following parameters:

You need to register the initialization function so that the server runs the function when starting up. For how to register matching rule functions, see "Registering Matching Rule Functions," on page 153.

The following table summarizes the different parameters that the initialization function should get and set in the parameter block that is passed in.

Table 11-7 Input and Output Parameters Available to a Matching Rule Plug-in Initialization Function  
Parameter Name
Data Type
Description
SLAPI_PLUGIN_ARGC
int
Input parameter. Number of arguments in the plugin directive, not including the library name and initialization function name.
SLAPI_PLUGIN_ARGV
char **
Input parameter. Array of string arguments in the plugin directive, not including the library name and initialization function name.
SLAPI_PLUGIN_MR_FILTER_CREATE_FN
void *
(function pointer)
Output parameter. The factory function used for creating filters.
SLAPI_PLUGIN_MR_INDEXER_CREATE_FN
void *
(function pointer)
Output parameter. The factory function used for creating indexers.
SLAPI_PLUGIN_CLOSE_FN
void *
(function pointer)
Output parameter. The close function, which the server calls before shutting down.
SLAPI_PLUGIN_PRIVATE
void *
Output parameter. Pointer to any private data you want passed to your plug-in functions.

Registering Matching Rule Functions

Depending on the Directory Server version, add the appropriate information for your plug-in function.

In current releases of Directory Server, shut down the server, add the plug-in parameters to the dse.ldif file, and restart the server (see Chapter 3, "Configuring Plug-ins"). For example, your plug-in entry might look like this:

dn: cn=Test MatchineRule,cn=plugins,cn=config

objectClass: top

objectClass: nsSlapdPlugin

objectClass: extensibleObject

cn: Test MatchingRule

nsslapd-pluginPath: 
/opt/redhat-ds/servers/slapd-host1/plugins/slapd/slapi/

	examples/libtest-plugin.so

nsslapd-pluginInitfunc: testmatchrule_init

nsslapd-pluginType: matchingRule

nsslapd-pluginEnabled: on

nsslapd-pluginId: test-matchingrule

nsslapd-pluginarg0: /opt/redhat-ds/servers/slapd-host1/

customplugins/filename.conf
 

Specifying Start and Close Functions

For each matching rule operation plug-in, you can specify the name of a function to be called after the server starts and before the server is shut down. These functions take a single Slapi_PBlock argument.

The following table summarizes the different parameters that the initialization function should get and set in the parameter block that is passed in.

Table 11-8 Input and Output Parameters Available to a Matching Rule Plug-in Initialization Function  
Parameter Name
Data Type
Description
SLAPI_PLUGIN_START_FN
void *
(function pointer)
Output parameter. The function called after the Directory Server starts up.
SLAPI_PLUGIN_CLOSE_FN
void *
(function pointer)
Output parameter. The function called before the Directory Server shuts down.

If you register multiple plug-ins with different start and close functions, the functions are called in the order that the plug-ins are registered; in other words, in the order that the plugin directives appear in the server configuration file.




Previous
Contents
Index
Next

© 2001 Sun Microsystems, Inc. Used by permission. © 2005 Red Hat, Inc. All rights reserved.
Read the Full Copyright and Third-Party Acknowledgments.

last updated May 26, 2005