Sun Java System Directory Server Enterprise Edition 6.1 Developer's Guide

Filter Matching Function

The filter matching function takes pointers to the filter object, the entry, and the first attribute to check for a match.

The following figure shows how Directory Server uses the filter matching function.

Figure 11–2 Filter Match Function Context

Flow diagram shows Directory Server calling the filter
match function for each candidate match.

Notice that the filter matching function returns 0 (match) -1 (no match) or an LDAP error code for each entry processed.


Example 11–3 Filter Match Function (matchingrule.c)

This example shows the filter match function for the case exact matching rule where a match occurs when the two berval structures match.

#include "slapi-plugin.h"

typedef struct plg_filter_t            /* For manipulating filter obj. */
{   char          *  f_type;           /* Attribute type to match      */
    int              f_op;             /* Type of comparison
                                        * (<, <=, ==, >=, >, substr)
                                        * for the filter.              */
    struct berval ** f_values;         /* Array of values to match     */
} plg_filter_t;

/* Check for a match against the filter.
 * Returns:  0 filter matched
 *          -1 filter did not match
 *         > 0 an LDAP Error code                                      */
static int
plg_filter_match(
    void        * obj,                 /* Matching rule object         */
    Slapi_Entry * entry,               /* Entry to match               */
    Slapi_Attr  * attr                 /* Attributes to match          */
)
{
    plg_filter_t  * fobj  = (plg_filter_t *)obj;
    struct berval * mrVal = NULL;      /* Values handled as bervals... */
    Slapi_Value   * sval;              /* ...and as Slapi_Value structs*/
    int             rc    = -1;        /* No match                     */

    if (fobj && fobj->f_type && fobj->f_values && fobj->f_values[0]) {

        mrVal = fobj->f_values[0];

        /* Iterate through the attributes, matching subtypes.          */
        for (; attr != NULL; slapi_entry_next_attr(entry, attr, &attr)) {

            char * type = NULL;        /* Attribute type to check      */

            if ((slapi_attr_get_type(attr, &type) == 0) &&
                (type != NULL)                          &&
                (slapi_attr_type_cmp(fobj->f_type, type, 2) == 0)
            ) { /* slapi_attr_type_cmp(type1, type2, ==>2<==)
                 * matches subtypes, too. Refer to the reference
                 * documentation for details.                          */

                /* Type and subtype match, so iterate through the
                 * values of the attribute.                            */
                int hint = slapi_attr_first_value(attr, &sval);
                while (hint != -1) {
                    const struct berval * val =
                        slapi_value_get_berval(sval);

                    /* The case exact matching rule
                     * compares the two bervals.
                     *
                     * Your matching rule may do
                     * lots of different checks here.                  */
                    rc = slapi_berval_cmp(val, mrVal);
                    if (rc == 0)  {    /* Successful match             */
                    /* If you have allocated memory for a custom
                     * matching rule, do not forget to release it.     */
                        return 0;
                    }

                    hint = slapi_attr_next_value(attr, hint, &sval);
                }
            }
        }
    }
    return rc;
}

Notice that checking for a case exact match involves only slapi_berval_cmp(), which performs a byte by byte comparison. Your plug-in might do something more complex for the comparison.


Subtype Matches

Notice in the code for iterating through the attributes that slapi_attr_type_cmp() takes 2, the value assigned to SLAPI_TYPE_CMP_SUBTYPE, as its third argument. The argument forces a comparison of attribute subtypes, such as the locale of an attribute, in addition to attribute types. Refer to Part II, Directory Server Plug-In API Reference for details on plug-in API functions and their arguments.

Thread Safety and Filter Matching Functions

Directory Server never calls a filter matching function for the same filter object concurrently. Directory Server can, however, call the function concurrently for different filter objects. If you use global variables, ensure that your filter matching function handles such variables safely.