Netscape logo Plug-In ProgrammerĘs Guide
Netscape Directory Server

Previous      Contents      Index      DocHome      Next     

Chapter 10   Writing Extended Operation Plug-Ins


This chapter explains how to write plug-in functions to handle extended operations. Extended operations are are defined in the LDAP v3 protocol.

The chapter contains the following sections:

How Extended Operation Plug-Ins Work


You can define your own operation that you want the Netscape Directory Server (Directory Server) to perform. If you create a custom extended operation, you assign an object identification (OID) to identify that operation. LDAP clients request the operation by sending an extended operation request. Within the request, the client specifies:

When the Directory Server receives the request, the server calls the plug-in registered with the specified OID. The plug-in function has access to both the OID and the data in the client's request. The plug-in function can send back to the client a response containing an OID plus any additional data that might be needed.

In order to use extended operations, you need to configure both the Directory Server and the client so they understand the specific extended operation that you want performed.

Writing Extended Operation Functions


Like other plug-in functions, extended operation functions pass a single parameter block (Slapi_PBlock) and return an integer value, as shown in the following example declaration:

int my_ext_func( Slapi_PBlock *pb );

Extended operation functions should return a value of 0 if they are successful and a non-zero value if they are unsuccessful.

When the Directory Server receives an extended operation request, the front-end calls the extended operation function with the OID value specified in the request. The front-end makes the following information available to the extended function in the form of parameters in a parameter block.


Table 10-1    Extended Function Parameter Block Arguments  


Parameter ID

Data Type

Description

SLAPI_EXT_OP_REQ_OID

char *

Object ID (OID) of the extended operation specified in the request.

SLAPI_EXT_OP_REQ_VALUE

struct berval*

Value specified in the request.

SLAPI_EXT_OP_RET_OID

char *

Object ID (OID) that you want sent back to the client.

SLAPI_EXT_OP_RET_VALUE

struct berval*

Value that you want sent back to the client.



Typically, your function should perform an operation on the value specified in the SLAPI_EXT_OP_REQ_VALUE parameter. After the extended operation completes, your function should return a single value, according to the following:

Registering Extended Operation Functions


As is the case with other server plug-in functions (see Passing Data with Parameter Blocks), extended operation functions are specified in a parameter block that you can set on server startup.

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.

You can write your initialization function so that the OID is passed in from the directive. (See 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.


Code Example 10-1    Sample Initialization Function for Passing an OID  


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_init",
    "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_01 ) != 0 ||

/* Specify the OID of the extended operation */
    slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLISTs,
      (void*) oids ) != 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",
    "Plug-in sucessfully registered.\n" );
  return(0);
}




Depending on the Directory Server version, add a directive in the appropriate form to specify the name and location of your plug-in function and to specify the object identification (OID) of the operation.

In Directory Server 6.x, shut down the server, add the plug-in parameters to the dse.ldif file, and restart the server (see Chapter 3 "Configuring Plug-Ins"). For example, your plug-in entry might look like this:

dn: cn=Test ExtendedOp,cn=plugins,cn=config
objectClass: top
objectClass: nsSlapdPlugin
objectClass: extensibleObject
cn: Test ExtendedOp
nsslapd-pluginPath: /usr/netscape/servers/plugins/slapd/slapi/
   examples/libtest-plugin.so
nsslapd-pluginInitfunc: testexop_init
nsslapd-pluginType: extendedop
nsslapd-pluginEnabled: on
nsslapd-plugin-depends-on-type: database
nsslapd-pluginId: test-extendedop
nsslapd-pluginarg0: 1.2.3.4

For an example plug-in function that implements an extended operation, take a look at this source file: <server_root>/plugins/slapd/slapi/examples/testextendedop.c

In Netscape Directory Server 4.x, add this directive to the slapd.ldbm.conf file:

plugin extendedop [on|off] "<name of plugin>" /
  <library_name> <function_name> <OID>

<library_name> is the name and path to your shared library or dynamic link library, <function_name> is the name of your plug-in function, and <OID> is the object identifier of the extended operation.

For example, the following directive registers the function named my_ext_op() as the extended operation plug-in function for the operation with the OID 1.2.3.4.

plugin extendedop on "my extended op plugin" /
  /serverroot/myext.so my_ext_op 1.2.3.4

Specifying Start and Close Functions


For each extended operation plug-in, you can specify the name of a function to be called after the server starts and before the server is shut down.

Use the following parameters to specify these functions:



SLAPI_PLUGIN_START_FN

Specifies the function called after the Directory Server starts up.

SLAPI_PLUGIN_CLOSE_FN

Specifies the function called before the Directory Server shuts down.



If you register multiple plug-ins with different start and close functions, the functions are called in the order that the plug-ins are registered (in other words, in the order that the plugin directives appear in the server configuration file).



Previous      Contents      Index      DocHome      Next     

© 2001 Sun Microsystems, Inc. Portions copyright 1999, 2002 Netscape Communications Corporation. All rights reserved.


Last Updated August 23, 2002