The following example is a pre-operation plug-in for the LDAP search operation. Two functions are included in this example:
These functions illustrates the data in the parameter block that is available to your function. You can get and manipulate the data by calling the front-end API functions.
Writing the Plug-In Example
The following section of code includes the sample pre-operation search function and the sample initialization function.
#include <stdio.h>
#include <string.h>
#include "slapi-plugin.h"
/* function prototypes */
int test_preop_init( Slapi_PBlock *pb );
int test_preop_search( Slapi_PBlock *pb );
/* Description of the plug-in */
Slapi_PluginDesc srchpdesc = { "test-search", "Airius.com", "0.5",
"sample pre-operation search plugin" };
/* Initialization function
This function registers your plug-in function as a
pre-operation search function in the Directory Server.
You need to specify this initialization function in the
slapd.conf configuration file so that the server calls
this initialization function on startup. */
#ifdef _WIN32
__declspec(dllexport)
#endif
int
test_preop_init( Slapi_PBlock *pb )
{
/* Specify the version of the plug-in ("01" in this release ) */
if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
SLAPI_PLUGIN_VERSION_01 ) != 0 ||
/* Specify the description of the plug-in */
slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&srchpdesc ) != 0 ||
/* Set test_preop_search() as the function to call before
executing LDAP search operations. */
slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_SEARCH_FN,
(void *) test_preop_search ) !=0 ) {
/* Log an error message and return -1 if a problem occurred */
slapi_log_error( SLAPI_LOG_PLUGIN, "test_preop_init",
"Error registering the plug-in.\n" );
return( -1 );
}
/* If successful, log a message and return 0 */
slapi_log_error( SLAPI_LOG_PLUGIN, "test_preop_init",
"Plug-in successfully registered.\n" );
return( 0 );
}
/* Pre-operation plug-in function for LDAP search operations
This function is called by the server before processing an LDAP
search operation. The function gets data about the search request
from the parameter block and prints the data to the error log. */
int
test_preop_search( Slapi_PBlock *pb )
{
char *base, *filter_str, *attr_type, *substr_init, *substr_final;
char **substr_any;
int scope, deref, filter_type, i;
Slapi_Filter *filter;
struct berval *bval;
/* Log a message to indicate when the plug-in function starts */
slapi_log_error( SLAPI_LOG_PLUGIN, "test_preop_search",
"*** PREOPERATION SEARCH PLUGIN ***\n");
/* Get and log the base DN of the search criteria */
if ( slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &base ) == 0 )
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_TARGET",
"%s\n", base );
/* Get and log the search scope */
if ( slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ) == 0 ) {
switch( scope ) {
case LDAP_SCOPE_BASE:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_SCOPE",
"LDAP_SCOPE_BASE\n" );
break;
case LDAP_SCOPE_ONELEVEL:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_SCOPE",
"LDAP_SCOPE_ONELEVEL\n" );
break;
case LDAP_SCOPE_SUBTREE:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_SCOPE",
"LDAP_SCOPE_SUBTREE\n" );
break;
default:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_SCOPE",
"unknown value specified: %d\n", scope );
break;
}
}
/* Get and log the alias dereferencing setting */
if ( slapi_pblock_get( pb, SLAPI_SEARCH_DEREF, &deref ) == 0 ) {
switch( deref ) {
case LDAP_DEREF_NEVER:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"LDAP_DEREF_NEVER\n" );
break;
case LDAP_DEREF_SEARCHING:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"LDAP_DEREF_SEARCHING\n" );
break;
case LDAP_DEREF_FINDING:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"LDAP_DEREF_FINDING\n" );
break;
case LDAP_DEREF_ALWAYS:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"LDAP_DEREF_ALWAYS\n" );
break;
default:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"unknown value specified: %d\n", deref );
break;
}
}
/* Get and log the search filter information */
if ( slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter ) == 0 ) {
/* Get and log the filter type */
filter_type = slapi_filter_get_choice( filter );
switch( filter_type ) {
case LDAP_FILTER_AND:
case LDAP_FILTER_OR:
case LDAP_FILTER_NOT:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"Complex search filter. See value of
SLAPI_SEARCH_STRFILTER.\n" );
break;
case LDAP_FILTER_EQUALITY:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_EQUALITY\n" );
break;
case LDAP_FILTER_GE:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_GE\n" );
break;
case LDAP_FILTER_LE:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_LE\n" );
break;
case LDAP_FILTER_APPROX:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_APPROX\n" );
break;
case LDAP_FILTER_SUBSTRINGS:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_SUBSTRINGS\n" );
/* For substring filters, get and log the attribute type and
the substrings in the filter */
slapi_filter_get_subfilt( filter, &attr_type, &substr_init,
&substr_any, &substr_final );
if ( attr_type != NULL )
slapi_log_error( SLAPI_LOG_PLUGIN, "\tAttribute type",
"%s\n", attr_type );
if ( substr_init != NULL )
slapi_log_error( SLAPI_LOG_PLUGIN, "\tInitial substring",
"%s\n", substr_init );
if ( substr_any != NULL ) {
for ( i = 0; substr_any[i] != NULL; i++ ) {
slapi_log_error( SLAPI_LOG_PLUGIN, "\tSubstring",
"# %d: %s\n", i, substr_any[i] );
}
}
if ( substr_final != NULL )
slapi_log_error( SLAPI_LOG_PLUGIN, "\tFinal substring",
"%s\n", substr_final );
break;
case LDAP_FILTER_PRESENT:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_PRESENT\n" );
/* For presence filters, get and log the attribute type */
slapi_filter_get_type( filter, &attr_type );
if ( attr_type != NULL )
slapi_log_error( SLAPI_LOG_PLUGIN, "\tSearch for presence
of attr",
"%s\n", attr_type );
break;
case LDAP_FILTER_EXTENDED:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_EXTENDED\n" );
break;
default:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"Unknown filter type: slapi_filter_get_choice returned
%d\n",
filter_type );
break;
}
}
/* For comparison filters, get and log the attribute type */
if ( filter_type == LDAP_FILTER_EQUALITY || LDAP_FILTER_GE ||
LDAP_FILTER_LE ||
LDAP_FILTER_APPROX ) {
slapi_filter_get_ava( filter, &attr_type, &bval );
if ( ( attr_type != NULL ) && ( bval->bv_val != NULL ) ) {
slapi_log_error( SLAPI_LOG_PLUGIN, "\tAttribute type",
"%s\n", attr_type );
slapi_log_error( SLAPI_LOG_PLUGIN, "\tAttribute value",
"%s\n", bval->bv_val );
}
}
/* Get and log the string representation of the filter */
if ( slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &filter_str) == 0 )
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_STRFILTER",
"%s\n", filter_str );
slapi_log_error( SLAPI_LOG_PLUGIN, "test_preop_search",
"*** DONE ***\n\n" );
return( 0 );
}
Compling the Plug-In Example
On Solaris, you can use the following makefile to compile the example. (This sample makefile assumes that the source code is stored in srchxmpl.c and that you are compiling a plug-in named srchxmpl.so.)
# SOLARIS Makefile for Directory Server plug-in examples
#
CC = cc
LD = ld
INCLUDE_FLAGS = -I../include
CFLAGS = $(INCLUDE_FLAGS) -D_REENTRANT -KPIC
LDFLAGS = -G
OBJS = srchxmpl.o
all: srchxmpl.so
srchxmpl.so: $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS)
.c.o:
$(CC) $(CFLAGS) -c $<
clean:
-rm -f $(OBJS) srchxmpl.so
On Windows NT, make sure to link to the libslapd.lib import library (located under the <server_root>\plugins\slapd\slapi\lib directory).
Registering the Plug-In Example
To register this example plug-in, you should do the following:
Edit the slapd.conf file in a text editor, and add a plugin directive after the database directive:
plugin preoperation <path_to_library> test_preop_init
(Each pre-operation plug-in is associated with a back-end. The directive
that registers the plug-in must fall within the database-specific section for
that database in the slapd.conf file.)
In the Administration Server, click the Apply button in the top frame to save and apply your changes.
In the server manager, click Server Preferences | LDAP, and verify that the Plugins log level is selected. (The sample source code logs messages to the error log with the Plugins severity level.)
Running the Plug-In Example
Restart the Directory Server and check the error log. (In the server manager, click Server Status | View Error Log.) Perform a few searches against the directory. The pre-operation search plug-in function should write data about the search to the error log.