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

Filter Factory Function

The filter factory function takes a parameter block from Directory Server. The function then sets parameters such that Directory Server can build a list of candidate entries, candidates the server checks for matches.

The following figure shows how the filter factory function operates.

Figure 11–3 Filter Factory Function Context

Flow diagram shows Directory Server calling the filter
factor function to create a filter object.

The following example shows the filter factory function for the case exact matching rule.


Example 11–5 Filter Factory Function (matchingrule.c)

#include "slapi-plugin.h"

#define PLG_OID       "1.3.6.1.4.1.42.2.27.999.4.1"
#define SUBSYS        "CaseExactMatching Plugin"

/* Functions to obtain connection information for logging.             */
static long mypblock_get_msgid( Slapi_PBlock * pb);
static int  mypblock_get_connid(Slapi_PBlock * pb);
static int  mypblock_get_opid(  Slapi_PBlock * pb);

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;

static int
plg_filter_create(Slapi_PBlock * pb)
{
    int             rc       = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
    char          * mr_oid   = NULL;   /* MR OID from the server       */
    char          * mr_type  = NULL;   /* Attr type to match           */
    struct berval * mr_value = NULL;   /* Attr value to match          */
    plg_filter_t  * fobj     = NULL;   /* Object to create             */
        
    if (
        slapi_pblock_get(pb, SLAPI_PLUGIN_MR_OID, &mr_oid) ||
        (mr_oid == NULL)
    ) {
        slapi_log_error_ex(
            -1, /* errorId */
            mypblock_get_msgid(pb),
            mypblock_get_connid(pb),
            mypblock_get_opid(pb),
            SUBSYS,
            SLAPI_INTERNAL_ERROR,
            "plg_filter_create failed: NULL OID values are invalid.\n"
        );
        }
    else if (strcmp(mr_oid, PLG_OID) == 0) {
        /* The MR OID from the server is handled by this plug-in.      */
        if (
            (slapi_pblock_get(pb, SLAPI_PLUGIN_MR_TYPE,  &mr_type) == 0)  &&
            (mr_type  != NULL)                                            &&
            (slapi_pblock_get(pb, SLAPI_PLUGIN_MR_VALUE, &mr_value) == 0) &&
            (mr_value != NULL)
        ) { /* ...provide a pointer to a filter match function.        */
            int op            = SLAPI_OP_EQUAL;
            fobj              = (plg_filter_t *)slapi_ch_calloc(
                                    1,
                                    sizeof (plg_filter_t)
                                );
            fobj->f_type      = slapi_ch_strdup(mr_type);
            fobj->f_op        = op;
            fobj->f_values    = (struct berval **)slapi_ch_malloc(
                                    2 * sizeof(struct berval *)
                                );
            fobj->f_values[0] = slapi_ch_bvdup(mr_value);
            fobj->f_values[1] = NULL;

            rc  = slapi_pblock_set(        /* Set object destructor.   */
                pb,
                SLAPI_PLUGIN_DESTROY_FN,
                (void *)plg_filter_destroy
            );
            rc |= slapi_pblock_set(        /* Set object itself.       */
                pb,
                SLAPI_PLUGIN_OBJECT,
                (void  *)fobj
            );
            rc |= slapi_pblock_set(        /* Set filter match fcn.    */
                pb,
                SLAPI_PLUGIN_MR_FILTER_MATCH_FN,
                (void *)plg_filter_match
            );
            rc |= slapi_pblock_set(        /* Set sorting function.    */
                pb,
                SLAPI_PLUGIN_MR_FILTER_INDEX_FN,
                (void *)plg_filter_index
            );

            if (rc == 0) {
                slapi_log_info_ex(
                    SLAPI_LOG_INFO_AREA_PLUGIN,
                    SLAPI_LOG_INFO_LEVEL_DEFAULT,
                    mypblock_get_msgid(pb),
                    mypblock_get_connid(pb),
                    mypblock_get_opid(pb),
                    SUBSYS,
                    "plg_filter_create (oid %s; type %s) OK\n",
                    mr_oid, mr_type
                );
            } else {
                slapi_log_error_ex(
                    -1, /* errorId */
                    mypblock_get_msgid(pb),
                    mypblock_get_connid(pb),
                    mypblock_get_opid(pb),
                    SUBSYS,
                    SLAPI_INTERNAL_ERROR,
                    "plg_filter_create (oid %s; type %s) - pblock error \n",
                    mr_oid, mr_type
                );
            }
        } else { /* Missing parameters in the pblock                   */
            slapi_log_error_ex(
                -1,
                mypblock_get_msgid(pb),
                mypblock_get_connid(pb),
                mypblock_get_opid(pb),
                SUBSYS,
                "Parameter errors ",
                "plg_filter_create: invalid input pblock.\n"
            );
        }
    }

    return rc;
}

Notice that this function returns LDAP_UNAVAILABLE_CRITICAL_EXTENSION if the function does not handle the matching rule OID in the parameter block. Refer to Handling an Unknown Matching Rule.


Input Parameters for Filter Factory Functions

A filter factory function can get values for the following from the parameter block:

Output Parameters for Filter Factory Functions

An indexer factory function should set values for the following in the parameter block before returning control to Directory Server:

Refer to Chapter 18, Parameter Block Reference for details.

Thread Safety and Filter Factory Functions

This function must be thread safe. Directory Server can call this function concurrently.