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

Example Extended Operation Plug-In

This section explains how the extended operation plug-in works.

Registering the Extended Operation Plug-In

Before using the plug-in function as described here, build the plug-in. Also, configure Directory Server to load the plug-in.

Notice that OID 1.2.3.4 is passed as an argument through the configuration entry. The configuration entry could specify more than one nsslapd-pluginarg attribute if the plug-in supported multiple extended operations, each identified by a distinct OID, for example.

ProcedureTo Register the Plug-In

If you have not already done so, build the example plug-in library and activate both plug-in informational logging and the example plug-in.

  1. Build the plug-in.

    Hint Use install-path/examples/Makefile or install-path/examples/Makefile64.

  2. Configure Directory Server to log plug-in informational messages and load the plug-in.

    Hint Use the commands specified in the comments at the outset of the plug-in source file.

  3. Restart Directory Server.


    $ dsadm restart instance-path
    

Initializing the Extended Operation Plug-In

As for other plug-in types, extended operation plug-ins include an initialization function that registers other functions in the plug-in with Directory Server. For extended operation plug-ins, this initialization function also registers the OIDs handled by the plug-in. The function registers OIDs by setting SLAPI_PLUGIN_EXT_OP_OIDLIST in the parameter block Directory Server, which the function passes to the initialization function.


Example 10–1 Registering Plug-In Functions and OIDs (testextendedop.c)

This example demonstrates how the OID list is built and registered.

#include "slapi-plugin.h"

Slapi_PluginDesc expdesc = {
    "test-extendedop",                 /* plug-in identifier       */
    "Sun Microsystems, Inc.",          /* vendor name              */
    "6.0",                             /* plug-in revision number  */
    "Sample extended operation plug-in"/* plug-in description      */
};

#ifdef _WIN32
__declspec(dllexport)
#endif
int
testexop_init(Slapi_PBlock * pb)
{
    char ** argv;                      /* Args from configuration  */
    int     argc;                      /* entry for plug-in.       */
    char ** oid_list;                  /* OIDs supported           */
    int     rc = 0;                    /* 0 means success          */
    int     i;

    /* Get the arguments from the configuration entry.             */
    rc |= slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv);
    rc |= slapi_pblock_get(pb, SLAPI_PLUGIN_ARGC, &argc);
    if (rc != 0) {
        slapi_log_info_ex(
            SLAPI_LOG_INFO_AREA_PLUGIN,
            SLAPI_LOG_INFO_LEVEL_DEFAULT,
            SLAPI_LOG_NO_MSGID,
            SLAPI_LOG_NO_CONNID,
            SLAPI_LOG_NO_OPID,
            "testexop_init in test-extendedop plug-in",
            "Could not get plug-in arguments.\n"
        );
        return (rc);
    }

    /* Extended operation plug-ins may handle a range of OIDs.     */
    oid_list = (char **)slapi_ch_malloc((argc + 1) * sizeof(char *));
    for (i = 0; i < argc; ++i) {
        oid_list[i] = slapi_ch_strdup(argv[i]);
        slapi_log_info_ex(
            SLAPI_LOG_INFO_AREA_PLUGIN,
            SLAPI_LOG_INFO_LEVEL_DEFAULT,
            SLAPI_LOG_NO_MSGID,
            SLAPI_LOG_NO_CONNID,
            SLAPI_LOG_NO_OPID,
            "testexop_init in test-extendedop plug-in",
            "Registering plug-in for extended operation %s.\n",
            oid_list[i]
        );
    }
    oid_list[argc] = NULL;
        
    rc |= slapi_pblock_set(            /* Plug-in API version      */
        pb,
        SLAPI_PLUGIN_VERSION,
        SLAPI_PLUGIN_CURRENT_VERSION
    );
    rc |= slapi_pblock_set(            /* Plug-in description      */
        pb,
        SLAPI_PLUGIN_DESCRIPTION,
        (void *) &expdesc
    );
    rc |= slapi_pblock_set(            /* Extended op. handler     */
        pb,
        SLAPI_PLUGIN_EXT_OP_FN,
        (void *) test_extendedop
    );
    rc |= slapi_pblock_set(            /* List of OIDs handled     */
        pb,
        SLAPI_PLUGIN_EXT_OP_OIDLIST,
        oid_list
    );
    return (rc);
}

Notice that you extract OIDs from the arguments passed by Directory Server. Directory Server passes the arguments from the configuration entry to the parameter block, by using slapi_ch_strdup() on each argv[] element. The OID list is then built by allocating space for the array by using slapi_ch_malloc() and placing the OIDs in each oid_list[] element. You then register the plug-in OID list by using SLAPI_PLUGIN_EXT_OP_OIDLIST. You register the extended operation handler function, test_extendedop(), using SLAPI_PLUGIN_EXT_OP_FN as shown.

Refer to Part II, Directory Server Plug-In API Reference for details about parameter block arguments and plug-in API functions.


Handling the Extended Operation

The plug-in function test_extendedop() gets the OID and value for the operation from the client request. The function then sends the client a response, as shown in Developing the Extended Operation Client.

Notice how the function obtains the OID and value from the request by using SLAPI_EXT_OP_REQ_OID and SLAPI_EXT_OP_REQ_VALUE. The function then uses slapi_ch_malloc() to construct a string to return to the client through the pointer to a berval structure, result_bval. A different extended operation plug-in might do something entirely different at this point.

Also notice that the function sends a different OID back to the client than the OID in the client request. The OID that is sent back can be used to indicate a particular result to the client, for example. The function uses slapi_send_ldap_result() to indicate success as well as to send the OID and value to the client. The function then frees the memory that was allocated. Finally, the function returns SLAPI_PLUGIN_EXTENDED_SENT_RESULT to indicate to Directory Server that processing of the plug-in function is complete.

If the function had not sent a result code to the client, it would return an LDAP result code to Directory Server. Directory Server would then send the result code to the client.

If the function cannot handle the extended operation with the specified OID, the function returns SLAPI_PLUGIN_EXTENDED_NOT_HANDLED. Then Directory Server sends an LDAP_PROTOCOL_ERROR result code to the client.