11.4. Handling Extensible Match Filters

This section explains how to set up the server to process searches that use extensible match filters (matching rules).

Note

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

11.4.1. How the Server Handles the Filter

When the server processes a search request that has an extensible match filter, the server performs the following tasks:
  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, the server attempts to find a matching rule plug-in that handles the OID. Refer to Section 11.2.3, “How the Server Associates Plug-ins with OIDs”, for details.
  2. The server then attempts to generate a list of search result candidates from the indexes. In a new Slapi_PBlock parameter block:
    1. 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).
    2. 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, refer to Section 11.4.2, “Query Operators in Matching Rules”.
    3. 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).
    4. 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.
  3. For each candidate entry, the server performs the following tasks to determine if the entry matches the search filter:
    1. 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.
    2. 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.
  4. The server then 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.
  5. 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.

11.4.2. Query Operators in Matching Rules

As discussed in Section 11.4.1, “How the Server Handles the Filter”, 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 back-end 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.

11.4.3. 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.)
file:///home/joakes/svn/8.0/Plugin_Programming_Guide/tmp/en-US/html/Plugin_Programming_Guide-Handling_Extensible_Match_Filters-Getting_and_Setting_Parameters_in_Filter_Factory_Functions.html The filter factory function should perform the following tasks:
  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.
  3. You can also get any data that you set in the SLAPI_PLUGIN_PRIVATE parameter during initialization. Refer to Section 11.7, “Writing an Initialization Function”.
  4. Create a filter object, and include the following information:
    • 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.
  5. Set the following parameters:
  6. Return 0 (or the result code LDAP_SUCCESS) if everything completed successfully.

11.4.4. 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. Refer to Section 11.7, “Writing an Initialization Function”, 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.

11.4.5. 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, remember that the server can call this function concurrently for different filter objects.)
The filter index function should perform the following tasks:
  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:
    • SLAPI_PLUGIN_MR_OID - Set to the official OID of the matching rule.
    • SLAPI_PLUGIN_MR_TYPE - Set to the attribute type in the filter object.
    • SLAPI_PLUGIN_MR_VALUES - Set to the values in the filter object.
    • SLAPI_PLUGIN_MR_QUERY_OPERATOR - Set to the query operator that corresponds to this search filter. Refer to Section 11.4.2, “Query Operators in Matching Rules”, for possible values for this parameter.
    • SLAPI_PLUGIN_OBJECT - Set to the filter object.
    • SLAPI_PLUGIN_MR_INDEX_FN - Set to the indexer function. Refer to Section 11.3.5, “Writing the Indexer Function”.
  3. Return 0 (or the result code LDAP_SUCCESS) if everything completed successfully.

11.4.6. 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, refer to Section 11.4.3, “Writing a Filter Factory Function”.
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, refer to Section 11.4.2, “Query Operators in Matching Rules”.
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.

11.4.7. 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:
  • filter is a pointer to the filter object.
  • entry is a pointer to the Section 14.22, “Slapi_Entry” entry that should be compared against the filter.
  • attrs is the first Slapi_Attr attribute in the entry or in the set of DN attributes. (The extensible match filter might specify that the attributes in the DN of an entry should also be included in the search.)
This function will never be called for the same filter object concurrently. (If you plan to manipulate global variables, remember that the server can call this function concurrently for different filter objects.)
The filter matching function should perform the following tasks:
  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. Remember to search 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.
  3. Using the query operator to determine how the values should be compared, compare the values from the filter against the values in the attribute.
  4. Return one of the following values:
    • 0 if the values of the attribute match the value specified in the filter.
    • -1 if the values do not match.
    • An LDAP error code (a positive number) if an error occurred.