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 ***