The search filter that you obtain from the parameter block must be considered. testpreop_search() gets the filter from the parameter block both as a Slapi_Filter structure, filter, and as a string, filter_str. Depending on what kind of search filter is passed to Directory Server and retrieved in the Slapi_Filter structure, the plug-in breaks the filter down in different ways. If the function were post-search rather than pre-search, you would likely want to access the results that are returned through the parameter block. See Part II, Directory Server Plug-In API Reference for instructions on accessing the results.
The plug-in API offers several functions for manipulating the search filter. testpreop_search() uses slapi_filter_get_choice() to determine the kind of filter used. The preoperation search function also uses slapi_filter_get_subfilt() to break down substrings that are used in the filter. The preoperation search function further uses slapi_filter_get_type() to find the attribute type when searching for the presence of an attribute. The preoperation search function uses slapi_filter_get_ava() to obtain attribute types and values used for comparisons.
The following example shows a code excerpt that retrieves information from the search filter.
#include "slapi-plugin.h"
int
testpreop_search(Slapi_PBlock * pb)
{
char * attr_type = NULL;/* For substr and compare */
char * substr_init= NULL;/* For substring filters */
char * substr_final=NULL;
char ** substr_any = NULL;
int i, rc =0;
Slapi_Filter * filter;
rc |= slapi_pblock_get(pb, SLAPI_SEARCH_FILTER, &filter);
if (rc == 0) {
filter_type = slapi_filter_get_choice(filter);
switch (filter_type) {
case LDAP_FILTER_AND:
case LDAP_FILTER_OR:
case LDAP_FILTER_NOT:
LOG1("Search filter: complex boolean\n");
break;
case LDAP_FILTER_EQUALITY:
LOG1("Search filter: LDAP_FILTER_EQUALITY\n");
break;
case LDAP_FILTER_GE:
LOG1("Search filter: LDAP_FILTER_GE\n");
break;
case LDAP_FILTER_LE:
LOG1("Search filter: LDAP_FILTER_LE\n");
break;
case LDAP_FILTER_APPROX:
LOG1("Search filter: LDAP_FILTER_APPROX\n");
break;
case LDAP_FILTER_SUBSTRINGS:
LOG1("Search filter: LDAP_FILTER_SUBSTRINGS\n");
slapi_filter_get_subfilt(
filter,
&attr_type,
&substr_init,
&substr_any,
&substr_final
);
if (attr_type != NULL)
LOG2("\tAttribute type: %s\n", attr_type);
if (substr_init != NULL)
LOG2("\tInitial substring: %s\n", substr_init);
if (substr_any != NULL)
for (i = 0; substr_any[i] != NULL; ++i) {
LOG3("\tSubstring# %d: %s\n", i, substr_any[i]);
}
if (substr_final != NULL)
LOG2("\tFinal substring: %s\n", substr_final);
break;
case LDAP_FILTER_PRESENT:
LOG1("Search filter: LDAP_FILTER_PRESENT\n");
slapi_filter_get_attribute_type(filter, &attr_type);
LOG2("\tAttribute type: %s\n", attr_type);
break;
case LDAP_FILTER_EXTENDED:
LOG1("Search filter: LDAP_FILTER_EXTENDED\n");
break;
default:
LOG2("Search filter: unknown type %d\n", filter_type);
break;
}
}
return (rc);
}
Before using the plug-in function as described here, set up the example suffix and register the plug-in. See Extending the Bind Operation and “To register the Plug-in”, as described previously.
After the example suffix and plug-in have been loaded into the directory, run a search to generate output in instance-path/logs/errors.
$ ldapsearch -h localhost -p 1389 -b "dc=example,dc=com" "(uid=*go*iv*)" |
When you ignore the housekeeping information in the error log, the search filter breakdown occurss as shown in the following example.
*** PREOPERATION SEARCH PLUG-IN - START ***
Target DN: dc=example,dc=com Scope: LDAP_SCOPE_SUBTREE
Dereference setting: LDAP_DEREF_NEVER
Search filter: LDAP_FILTER_SUBSTRINGS
Attribute type: uid
Substring# 0: go
Substring# 1: iv
String representation of search filter: (uid=*go*iv*)
*** PREOPERATION SEARCH PLUG-IN - END ***