This chapter provides an introduction on how to write and compile Netscape Directory Server (Directory Server) plug-ins. Chapter 3, "Configuring Plug-ins," describes how to load your plug-in into the Directory Server configuration once it is successfully compiled. This chapter covers the following topics:
If you have already written a plug-in for the Directory Server, refer to the section Using Directory Server Plug-in APIs for information on migrating your plug-in to the latest version of the Directory Server.
To write a Directory Server plug-in, you must do the following in your plug-in code:
For additional information on writing specific plug-in types, refer to the following chapters:
The interface to the Directory Server plug-in API is located in the slapi-plugin.h header file. You must include this header file in the plug-ins you write. The following line of code shows an example of including this header file:
When you install the Directory Server, slapi-plugin.h gets installed into the following directory:
<server_root>/plugins/slapd/slapi/include
Often, plug-in functions make use of a parameter block, Slapi_PBlock, for passing information to and from the Directory Server. The following plug-in function types pass a parameter block as a function argument:
When invoking these types of plug-in functions, you pass to the Directory Server a single argument of type Slapi_PBlock. This argument contains the parameter values needed to complete the function request. Your plug-in function should have a prototype similar to the following:
int myFunction(Slapi_PBlock pb);
In this prototype, pb is the parameter block that contains the parameters pertaining to the operation or function.
For example, the parameter block for an add operation will contain the target DN and the entry to be added; the parameter block for a bind operation will contain the DN of the user, the authentication method, and the user's credentials.
In the functions you write, you set values in the parameter block that pertain to the operation you are performing. You can also get data from the parameter block which you can use within your functions. This process is described in the next section, Getting Data from the Parameter Block.
You can also set values in the parameter block during the processing of your plug-in functions. The Directory Server can then use the new data values to complete an operation which it might be processing. For details on this, see Setting Data in the Parameter Block.
Some of the data that you can retrieve from
the parameter block include entries, attributes, search filters, and
distinguished names (DNs). Once you retrieve a piece of data, you can
manipulate it using the front-end API functions. For example, you can
use front-end API functions to verify that an entry complies with the
schema or you can split up a search filter into its individual
components. For details, see Calling
Front-End Functions.
When the Directory
Server calls your plug-in function, it passes any relevant data to your
function in a parameter block. The parameter block is defined as a Slapi_PBlock
data type. To access the data in a parameter block, call the slapi_pblock_get()
function.
In the following example, the searchdn_preop_search() function gets the DN of the base DN for the LDAP search operation. It then normalizes the DN, converts all characters to lowercase, and writes the converted DN to the error log. Note that the actual DN (not a copy of it) is normalized and converted to lowercase.
|
|
|
/* Get the base DN of the search from the parameter block. */ |
|
|
In this code example,
SLAPI_SEARCH_TARGET identifies the parameter in the parameter
block that contains the base DN of the search. For a complete listing
of the parameter block IDs, see Chapter
16, "Parameter
Block Reference."
To modify the value of a parameter in the parameter block, call the function slapi_pblock_set(). For example, you call can slapi_pblock_set() to change the value of the SLAPI_PRIVATE parameter, which stores private data for the plug-in.
In the following example, the ldif_back_init() function sets the value of the SLAPI_PRIVATE parameter to the context of the database.
|
|
|
if ( slapi_pblock_set( pb, SLAPI_PRIVATE, (void *) db ) == -1 ) |
|
|
Notice that this example uses the function slapi_new_condvar() to notify the user if an error occurred.
In this code example,
SLAPI_PRIVATE
identifies the parameter in the parameter block that contains private
data for use in the database functions. For a complete listing of the
parameter block IDs, see Chapter
16, "Parameter
Block Reference."
The types of data that you can get from a parameter block include entries, attributes, distinguished names, and search filters. If you want to manipulate these data items, you can call the associated front-end API functions provided with the Directory Server. For example, using the the front-end API functions, you can:
For more information on the front-end API, see chapter 5, "Front-End API Functions," and chapter 15, "Function Reference."
If your plug-in function is successful, it should return 0 to the front-end. If it is not successful, it should return a non-zero value, and you should call the front-end API function slapi_new_condvar() to log an error message to describe the problem (Logging Messages details this process).
In some cases, you may need to send an LDAP
result back to the client. For example, if you are writing a
pre-operation bind function and an error occurs during the processing
of the function, the function should return a non-zero value, log an
error message, and send the appropriate LDAP result code back to the
client. For information on the appropriate result code to return to the
client, refer to the chapter that documents the type of plug-in you are
writing.
Before the Directory Server can call your plug-in function, the function must be properly initialized. To do this, you must write an initialization function for your server plug-in. The initialization function should do the following:
Your initialization function should have a prototype similar to the following:
int my_init_function( Slapi_PBlock pb );
Notice that in the initialization function,
the Directory Server passes a single argument of type Slapi_PBlock.
If you are writing an initialization function for a plug-in that runs on Windows NT or Windows 2000, make sure to export the initialization function. For example:
__declspec(dllexport) int my_init_function(Slapi_PBlock pb);
On top of exporting the initialization function, you must also specify the name of the initialization function in a .def file.
In addition to the initialization function,
you might need to export other functions contained in your plug-in. In
particular, you will need to export any functions that are not
specifically registered by your initialization functions, such as the
entry store and entry fetch plug-in functions that are described in chapter 9. Registering
plug-in functions is described in detail in
the next section, Registering
Your Plug-in Functions
You need to specify the compatibility version of your plug-in so that the Directory Server can determine whether or not it supports the plug-in.
To specify the plug-in compatibility version, call the slapi_pblock_set() function, and set the SLAPI_PLUGIN_VERSION parameter to the version number associated with the plug-in. For example:
slapi_pblock_set(pb,
SLAPI_PLUGIN_VERSION, \
SLAPI_PLUGIN_VERSION_03);
You specify information about your plug-in, such as a description of the plug-in, with the Slapi_PluginDesc structure. For details on this data structure, see Slapi_PluginDesc.
It is advised that you include a plug-in description since the Netscape Console displays this information as part of the server configuration information.
To specify plug-in information, call the slapi_pblock_set() function, and set the SLAPI_PLUGIN_DESCRIPTION parameter to this structure. For example:
|
|
|
|
This example code specifies the following plug-in information:
Whether you register your plug-in through the initialization function depends upon the type of function you are registering.
For some plug-in types, you do not need to register the plug-in function from within the initialization function. For example, you register entry store and entry fetch plug-ins by specifying the function names in the plugin directive in the dse.ldif file.
For other plug-in types, such as pre-operation plug-ins and post-operation plug-ins, the Directory Server gets the pointer to your function from a parameter in the initialization function parameter block. In these cases, you use the slapi_pblock_set() function to specify the name of your plug-in function.
The full list parameters that you can use to register your plug-in functions are listed in Parameters for Registering Plug-in Functions.
For example, if you want to register searchdn_preop_search() as a pre-operation search function, include the following code in your initialization function:
slapi_pblock_set(pb,
SLAPI_PLUGIN_PRE_SEARCH_FN, \
(void *)
searchdn_preop_search)
SLAPI_PLUGIN_PRE_SEARCH_FN
is the parameter that specifies the pre-operation plug-in function for
the LDAP search operation.
|
|
|
|
If you do not register your plug-in functions, the Directory Server will not call your plug-in functions. Make sure to register your plug-in functions. |
|
|
|
|
You can register more than one plug-in function in your initialization function; you do not need to write an initialization function for each plug-in function that you need to register. You should, however, define a different initialization function for each type of plug-in that you are registering.
If the initialization function is successful, it should return 0. If an error occurs, it should return -1. If the initialization function returns -1, the Directory Server will exit.
The following is an example of an initialization function that registers the pre-operation plug-in function searchdn_preop_search(). After the initialization function returns, the server will call searchdn_preop_search() before each LDAP search operation is executed.
Keep in mind the following tips when compiling your server plug-in:
The following code shows a sample Makefile for Solaris. The example assumes that the source files are located in the following directory:
<server_root>/plugins/slapd/slapi/examples
The server plug-in API header files are located in the relative path ../include.
|
|
|
OBJS = testsaslbind.o testextendedop.o testpreop.o testpostop.o testentry.o |
|
|
| Previous |
Contents |
Index |
DocHome | Next |