Show Table of Contents
10.3. Registering Extended Operation Functions
Extended operation functions are specified in a parameter block that you can set on server startup, in the same fashion as other server plug-in functions (refer to Section 2.1.2, “Passing Data with Parameter Blocks”).
In your initialization function, you can call the slapi_pblock_set() function to set the
SLAPI_PLUGIN_EXT_OP_FN parameter to your function and the SLAPI_PLUGIN_EXT_OP_OIDLIST parameter to the list of OIDs of the extended operations supported by your function.
Note
Previously, Red Hat recommended to use the
SLAPI_PLUGIN_EXTENDEDOP parameter to register extended operation plug-ins. However, this function registration point has certain limitations. For example, this function registration is not correctly linked in a back end transaction, which can cause deadlock scenarios. To avoid similar issues, use the SLAPI_PLUGIN_BETXNEXTENDEDOP parameter. This parameter adds a database transaction to the extended operation.
The
SLAPI_PLUGIN_EXT_OP_BACKEND_FN parameter enables the plug-in to inform the server which back end will be used. After that, the server initiates a transaction. The following diagram illustrates the process:

Figure 10.1. Registering Extended Operation Functions
You can write your initialization function so that the OID is passed in from the directive (refer to Section 3.4, “Passing Extra Arguments to Plug-ins”, for details.) For example, the following initialization function sets the
SLAPI_PLUGIN_EXT_OP_OIDLIST parameter to the additional parameters specified.
#include "dirsrv/slapi-plugin.h"
/****************************************************
* Pre Extended Operation, Backend selection
***************************************************/
static int extend_exop_backend(Slapi_PBlock *pb, Slapi_Backend **target)
{
Slapi_DN *shared_sdn = NULL;
char *shared_dn = NULL;
int res = -1;
/* Parse the oid and what exop wants us to do - You need to implement this function! */
res = parse_exop_ber(pb, &shared_dn);
if (res == LDAP_SUCCESS && shared_dn) {
shared_sdn = slapi_sdn_new_dn_byref(shared_dn);
/* Take the SDN of the operation, and use it to find
The backend we plan to operate on.
*/
*target = slapi_be_select(shared_sdn);
slapi_sdn_free(&shared_sdn);
res = LDAP_SUCCESS;
}
return res;
}
int
extended_init( Slapi_PBlock *pb )
{
int i;
char **argv;
char **oids;
/* Get the additional arguments specified in the directive */
if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0 ) {
slapi_log_error( SLAPI_LOG_PLUGIN, "extended_initx" , "Server could not get argv.\n" );
return( -1 );
}
if ( argv == NULL ) {
slapi_log_error( SLAPI_LOG_PLUGIN, "extended_init" , "Required argument oiD is missing\n" );
return( -1 );
}
/* Get the number of additional arguments and copy them. */
for ( i = 0; argv[i] != NULL; i++ );
oids = (char **) slapi_ch_malloc( (i+1) * sizeof(char *) );
for ( i = 0; argv[i] != NULL; i++ ) {
oids[i] = slapi_ch_strdup( argv[i] );
}
oids[i] = NULL;
/* Specify the version of the plug-in */
if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03 ) != 0 ||
/* Specify the OID of the extended operation */
slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, (void*) oids ) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_EXT_OP_BACKEND_FN, (void *)extend_exop_backend) != 0 ||
/* Specify the function that the server should call */
slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_FN, (void*)extended_op ) != 0 )
{
slapi_log_error( SLAPI_LOG_PLUGIN, "extended_init" , "An error occurred.\n" );
return( -1 );
}
slapi_log_error( SLAPI_LOG_PLUGIN, "extended_init" , "Plugin successfully registered.\n" );
return(0);
}
To add the plug-in configuration, use
ldapmodify to add the entry. For example:
# ldapmodify -a -D "cn=Directory Manager" -W -p 389 -h server.example.com -x
dn: cn=Test ExtendedOp,cn=plugins,cn=config
objectClass: top
objectClass: nsSlapdPlugin
objectClass: extensibleObject
cn: Test ExtendedOp
nsslapd-pluginPath: /path/to/test-plugin.so
nsslapd-pluginInitfunc: testexop_init
nsslapd-pluginType: beextendedop
nsslapd-pluginEnabled: on
nsslapd-plugin-depends-on-type: database
nsslapd-pluginId: test-extendedop
nsslapd-pluginarg0: 1.2.3.4
Alternatively, shut down the server, add the plug-in parameters to the
dse.ldif file, and restart the server.
Check out the
testextendedop.c source file has for an example plug-in function that implements an extended operation. Example files are installed in /usr/lib64/dirsrv/plugins.

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.