E Java Server Plug-in Developer's Reference

In response to both customer and internal requests, Oracle has added a Java API to the server plug-in framework for Oracle Internet Directory. Some of the new Oracle Internet Directory features, such as server chaining, were developed using the Java plug-in API.

This chapter contains the following sections:

E.1 Advantages of Java Plug-ins

In addition to the advantages of the Java language itself, Java server plug-ins offer the following advantages over PL/SQL plug-ins:

  • Bidirectional communication between the server and the plug-in

  • The ability of the plug-in to return a search result

  • Support for the moddn operation

  • Better performance

  • No knowledge of database required

  • Enhanced security

  • Enhanced debugging capability

E.2 Setting Up a Java Plug-in

Set up a Java plug-in as follows:

  1. Create the standalone Java program using the pre-defined class definition and methods. You can implement the plug-in as a jar file or as a package.

  2. Compile the plug-in file or package. Before compiling, ensure that your CLASSPATH is set to $ORACLE_HOME/ldap/jlib/ospf.jar. Make sure the compilation completes without error.

  3. Place the class file, jar, or package in the pre-defined class location $ORACLE_HOME/ldap/server/plugin.

  4. Register the Java plug-in by adding the plug-in configuration entry.

    You can add the entry by using the command line or by using Oracle Directory Services Manager. For details, see "Registering a Plug-in From the Command Line" and "Managing Plug-ins by Using Oracle Directory Services Manager".

The jar file can have any name. The manifest file must contain the attribute Main-Class, followed by the name of the Java plug-in. For example:

Main-Class: myjavaplugin

The value of the orclPluginName attribute in the plug-in configuration entry must correspond with one of the following:

  • The name of a class in a class file

  • The fully qualified name of a class in a package

  • A jar file name.

The value of the orclPluginName attribute determines where the server expects to find the class or jar file. Table E-1 shows some examples.

Table E-1 Plug-in Names and Corresponding Paths

orclPluginName Path

myjavaplugin

ORACLE_HOME/ldap/server/plugin/myjavaplugin.class

myjavaplugin.jar

ORACLE_HOME/ldap/server/plugin/myjavaplugin.jar

my.package.myjavaplugin

ORACLE_HOME/ldap/server/plugin/my/package/myjavaplugin


After you perform these steps, the server invokes the plug-in whenever the invocation criteria are met.

The classes included in the jar file must not occur in the environment. If they do, unexpected errors might occur. To correct this problem, remove the classes from the environment and restart the Oracle Internet Directory server. If the JAR or class file depends on other JAR files or class files, then append the dependent JAR files or paths of the class files to the CLASSPATH and restart the Oracle Internet Directory server.

You can control whether the server reloads the Java plug-in class every time the plug-in executes. If the value of the attribute orclPluginClassReloadEnabled is 1, the server reloads the plug-in class every time. If it is 0, the server loads the class only the first time the plug-in executes.

The path of the Oracle Internet Directory Server Plug-in Framework jar file is $ORACLE_HOME/ldap/jlib/ospf.jar.

E.3 Java Plug-in API

This section presents a high-level overview of the API and explains the role of the main classes and interfaces. For detailed information about all the Java server plug-in classes and interfaces, please see the Javadoc Oracle Fusion Middleware Java API Reference for Oracle Internet Directory.

This sections contains the following topics:

Note:

Do not use System.exit() in a Java plug-in. Doing so might lead to unpredictable behavior by the Oracle directory server.

E.3.1 Communication Between the Server and Plug-in

All Java plug-ins use the ServerPlugin interface for communication between the plug-in and the Oracle Internet Directory server. When the server invokes a Java plug-in, it constructs a PluginDetail object and passes information to the plug-in in that object. The plug-in constructs a PluginResult object. After it completes its task, the plug-in passes the PluginResult object back to the server. In some cases, the plug-in changes or adds to the information it received in the PluginDetail and passes the information back to the server in the PluginResult object. Figure E-1 shows the communication between the Oracle Internet Directory server and the Java Plug-ins.

Figure E-1 Communication Between the Server and the Java Plug-in

Explained in text.

The Java plug-in can also use a ServerLog class to log messages in a log file.

E.3.2 Java Plug-in Structure

The general structure for a Java plug-in is:

public class Java_Plug-in_Class_Name {extends ServerPluginAdapter} {
        public PluginResult 
Name_of_ServerPlugin_Method(PluginDetail plgObj)
throws Exception {
      // Plug-in Code
      }
}

or

public class Java_Plug-in_Class_Name {implements ServerPlugin}  {
        public PluginResult 
Name_of_ServerPlugin_Method(PluginDetail plgObj)
throws Exception {
      // Plug-in Code
      }
}

E.3.3 PluginDetail

The PluginDetail contains the following information:

E.3.3.1 Server

This object contains metadata information about the Oracle Internet Directory Server where the plug-in is being executed. It contains the following information:

  • Hostname

  • Port

  • LdapContext

The Hostname and the Port indicate the host and port on which the server is running.

The LdapContext object allows the plug-in to connect back to the server and inform it that the connection is being acquired from the plug-in. This is necessary, for example, in an ldapbind plug-in that performs an ldapbind itself. By connecting back to the server using this LdapContext object, the plug-in prevents the server from invoking the same plug-in, resulting in an infinite loop.

The following code fragment shows how the plug-in retrieves the Server object from the PluginDetail and connects back to the server:

// An LDAP Bind Plug-in
public class MyBindPlugin extends ServerPluginAdapter
{
  …..
  // Retrieve the Server Object from the PluginDetail
  Server srvObj = plgObj.getServer();
  ……
  // This bind will not result in the LDAP Bind Plug-in being called  
  // in an infinite loop
  InitialLdapContext myConn = 
                           
(InitialLdapContext)srvObj.getLdapContextFromServerPlugin();
  myConn.bind(…);
  ….
}

See the Javadoc Oracle Fusion Middleware Java API Reference for Oracle Internet Directory for information about the methods used in the example.

E.3.3.2 LdapBaseEntry

The LdapBaseEntry contains the following information:

  • DN

  • Attributes

The server must send DN information for all of the operations, except ldapadd. The meaning of the DN for each operation is shown in Table E-2.

Table E-2 The Meaning of the DN Information for Each LDAP Operation

Operation Meaning of DN

ldapadd

No DN sent

ldapbind

The entry to which the directory server is attempting to bind

ldapcompare

The base entry on which to perform the compare

ldapdelete

For Pre and When timings, the entry which is to be deleted

For Post timing, no DN sent

ldapmoddn

The base entry to be moved

ldapmodify

For Pre and When timings, the entry on which the modification is being performed

For Post timing, the modified entry

ldapsearch

The base entry for the search


The Attributes are JNDI attributes.

The LdapBaseEntry has methods for accessing the DN and Attributes. For performance reasons, if the LdapBaseEntry is a group entry, and the entry cache capability is disabled, the attributes uniquemember and member are not accessible.

See Also:

The Oracle Internet Directory chapter in Oracle Fusion Middleware Performance and Tuning Guide for information about performance tuning.

E.3.3.3 LdapOperation

Every plug-in is associated with one of the seven basic LDAP operations: add, bind, compare, delete, moddn, modify, or search. The LdapOperation object contains the following information, which is passed to all seven operations:

  • Bind DN

  • Server Controls

  • Operation Result Code

The Bind DN is the DN of the identity that is requesting the LDAP operation. Server Controls is a vector that contains control information. If any server controls are passed to the server during an operation, then the control information is passed to the Java plug-in in the Server Controls. The meaning of the Operation Result Code depends on the timing of the operation, as shown in Table E-2. Note that in the case of a when_replace operation, the plug-in can change the information in the Operation Result Code and pass it to the server in the PluginResult.

Table E-3 Behavior of Operation Result Code

Plug-in Timing Meaning and Behavior of Operation Result Code

Pre

When

Not used

When_replace

Error status of the LDAP operation performed by the plug-in. Output from the plug-in to the server.

Post

Error status of LDAP operation performed by the server. Input to the plug-in from the server.


LdapOperation also has methods for retrieving and modifying its contents.

Seven different classes representing the seven LDAP operations extend the LdapOperation class. Each of the subclasses includes class-specific information, in addition to the LdapOperation information. The classes and class-specific information are shown in Table E-4. Each class name in Table E-4 is a link to the section describing the details of that class:

Table E-4 Subclasses of LdapOperation and Class-specific information.

Class Class-Specific information

AddLdapOperation

LdapEntry

BindLdapOperation

Bind Password

CompareLdapOperation

Attribute Name

Attribute Value

DeleteLdapOperation

Delete DN

ModdnLdapOperation

New Parent DN

New Relative DN

Delete Old RDN

New DN

ModifyLdapOperation

LdapModification

SearchLdapOperation

Filter

Required Attributes

Scope

SearchResultSet (Not sent by server; created by plug-in to return data)


Each class has methods for creating, modifying, and retrieving its information. The class-specific information represents either input to the plug-in, output from the plug-in to the server, or both.

The rest of this section discusses the operation-specific classes in detail.

E.3.3.3.1 AddLdapOperation

When invoking an ldapadd plug-in, the server constructs an AddLdapOperation object containing a LdapEntry object to pass information about the entry that is being added. The LdapEntry Object contains the following information:

  • DN

  • Attributes

The DN represents the DN of the entry to be added. The Attributes are the entry's JNDI Attributes. As Table E-5 shows, for all operations except the post-operation, the plug-in can modify the information in the LdapEntry and return it to the server.

Table E-5 Behavior of LdapEntry Information for Each Plug-in Timing

Plug-in Timing Behavior of LdapEntry Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


E.3.3.3.2 BindLdapOperation

The server passes the following information to an ldapbind plug-in:

  • Bind Password

  • Proxy Requester DN

Bind Password is the password for the bind. Proxy Requester DN is the DN of the identity requesting a Proxy Switch.

E.3.3.3.3 CompareLdapOperation

The server passes the following information to an ldapcompare plug-in:

  • Attribute Name

  • Attribute Value

The Attribute Name is the name to be compared during the ldapcompare operation. As Table E-6 shows, for all operations except the post-operation, the plug-in can modify the information in the Attribute Name and return it to the server.

Table E-6 Behavior of the AttributeName for Each Plug-in Timing

Plug-in Timing Behavior of the Attribute Name Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


The Attribute Value is the value to be compared during the ldapcompare operation. As Table E-7 shows, for all operations except the post-operation, the plug-in can modify the information in the Attribute Value and return it to the server.

Table E-7 Behavior of the Attribute Value for Each Plug-in Timing

Plug-in Timing Behavior of the Attribute Value Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


E.3.3.3.4 DeleteLdapOperation

The server passes the Delete DN object to an ldapdelete plug-in. This is the DN to be deleted. As Table E-8 shows, for all operations except the post-operation, the plug-in can modify the information in the Delete DN and return it to the server.

Table E-8 Behavior of the Delete DN for Each Plug-in Timing

Plug-in Timing Behavior of the DeleteDN Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


E.3.3.3.5 ModdnLdapOperation

The server passes the following information to ldapmoddn plug-ins:

  • New Parent DN

  • New Relative DN

  • Delete Old RDN

  • New DN

The New Parent DN contains the new parent of the RDN that was specified in the LdapBaseEntry of the PluginDetail. As Table E-9 shows, for all operations except the post-operation, the plug-in can modify the information in the New Parent DN and return it to the server.

Table E-9 Behavior of New Parent DN Information for Each Plug-in Timing

Plug-in Timing Behavior of the New Parent DN Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


The New Relative DN is the new RDN that is to replace the RDN that was specified in the LdapBaseEntry of the PluginDetail. As Table E-10 shows, for all operations except the post-operation, the plug-in can modify the information in the New Relative DN and return it to the server.

Table E-10 Behavior of New Relative Dn Information for Each Plug-in Timing

Plug-in Timing Behavior of the New Relative Dn Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


The Delete Old RDN value specifies whether the old RDN specified in the LdapBaseEntry of the PluginDetail is to be retained after it is replaced by the new relative DN. As Table E-11 shows, for all operations except the post-operation, the plug-in can modify the value in Delete Old RDN and return it to the server.

Table E-11 Behavior of Delete Old RDN Information for Each Plug-in Timing

Plug-in Timing Behavior of the Delete Old RDN Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


The New DN specifies the target DN in of the ldapmoddn operation. This information is only an input from the server to the plug-in. The plug-in cannot modify this information and return it to the server.

E.3.3.3.6 ModifyLdapOperation

The server passes an LdapModification object to ldapmodify plug-ins. The LdapModification object contains Modification Items, which are JNDI modification items. As Table E-12 shows, for all operations except the post-operation, the plug-in can modify the information in the LdapModification and return it to the server.

Table E-12 Behavior of LdapModification Information for Each Plug-in Timing

Plug-in Timing Behavior of the LdapModification Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


E.3.3.3.7 SearchLdapOperation

The SearchLdapOperation object contains the following information:

  • Filter

  • Required Attributes

  • Scope

  • SearchResultSet

The Filter, Required Attributes, and Scope are passed by the server.

The Filter contains the LDAP search filter specified for the ldapsearch operation. This is only an input to the plug-in. The plug-in cannot modify this information and return it to the server.

The Required Attributes contains the required attributes specified for the ldapsearch operation. As Table E-13 shows, for all operations except the post-operation, the plug-in can modify the information in the Required Attributes and return it to the server.

Table E-13 Behavior of the Required Attributes for Each Plug-in Timing

Plug-in Timing Behavior of the Required Attributes Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


The Scope contains the scope of the search to be performed by the ldapsearch operation. As Table E-14 shows, for all operations except the post-operation, the plug-in can modify the information in the Scope and return it to the server.

Table E-14 Behavior of the Scope for Each Plug-in Timing

Plug-in Timing Behavior of the Scope Information

Pre

When

When_replace

Both input and output. The plug-in can modify the information and return it to the server.

Post

Input only.


The SearchResultSet defines search results returned from the Java plug-in to the server. A plug-in performing an ldapsearch operation can construct this object. As Table E-15 shows, only the when and when_replace plug-ins can return a SearchResult Set to the server.

Table E-15 Behavior of the SearchResultSet for Each Plug-in Timing

Plug-in Timing Behavior of the SearchResultSet Information

Pre

The plug-in cannot return the object.

When

When_replace

The plug-in can return this object to the server.

Post

The plug-in cannot return the object.


E.3.3.4 PluginFlexfield

When you register a plug-in, you can store custom information in the plug-in configuration entry. When the server invokes the plug-in, it passes this information to the plug-in in the PluginFlexfield.

There are three schema attributes for storing custom information in the configuration entry. You can store text information in the orclPluginFlexfield attribute. You can use sub-types to provide more meaning to the kind of custom information being stored. For example, you could use the subtype orclPluginFlexfield;ad-host to store the host name of an Active Directory server that the plug-in must connect to.

You can store a binary value in the orclPluginBinaryFlexfield attribute. You can only store one value in orclPluginBinaryFlexfield for a plug-in because the server does not support attribute subtypes for binary attributes.

You can use orclPluginSecuredFlexfield to store custom text information that must never be displayed in clear text. The value is stored and displayed in encrypted form. Be sure that Oracle Internet Directory has privacy mode enabled to ensure that users cannot retrieve this attribute in clear text. See "Configuring Privacy of Retrieved Sensitive Attributes". You can use sub-types to provide more meaning to the kind of custom information being stored. Use the same subtype format as for orclPluginFlexfield.

When the server invokes the plug-in, it passes the information from the orclPluginFlexfield, orclPluginBinaryFlexfield, and orclPluginSecuredFlexfield to the plug-in in the PluginFlexfield object. The plug-in can interpret the information and use it. It cannot return the PluginFlexfield to the server.

In the following configuration entry example, subtypes of orclPluginFlexfield specify that the minimum password length is 8 characters, that the password must contain a digit, and that the password cannot contain repeated characters:

dn: cn=pre_add replace,cn=plugin,cn=subconfigsubentry
orclPluginFlexfield;minPwdLength: 8
orclPluginFlexfield;isDigitPwd: 1
orclPluginFlexfield;isRepeatCharsPwd: 0
objectclass: orclPluginConfig
objectclass: top
orclpluginname: MyJavaPwdCheckPlugin
orclplugintype: configuration
orclplugintiming: pre
orclpluginldapoperation: ldapadd
orclpluginenable: 1
orclpluginsubscriberdnlist: cn=users,dc=us,dc=oracle,dc=com
orclpluginattributelist: userpassword
orclPluginKind: Java

E.3.4 PluginResult

To return the results of its execution to the server, a Java plug-in constructs a PluginResult object and passes it back to the server. The PluginResult contains one object: an LdapOperation or one of its operation-specific subclasses. These objects were described in the section "LdapOperation". As explained in that section, for some operations and timings, the plug-in can modify the information in the "LdapOperation" subclass object it received in the PluginDetail and send that object back to the server in the PluginResult.

E.3.5 ServerPlugin Interface

All Java plug-ins use the ServerPlugin interface. The interface has pre-defined methods to communicate with the server. It has one method for each LDAP operation and timing. Each method takes a PluginDetail object as input and returns a PluginResult object back to the Oracle Internet Directory Server.

The ServerPluginAdapter class implements the ServerPlugin interface. The ServerPluginAdapter class has default (NULL) implementations of the ServerPlugin methods. This class enables you to code a Java plug-in without having to implement every method.

The rest of this section lists the ServerPlugin methods for each LDAP operation. It includes:

E.3.5.1 ServerPlugin Methods for Ldapbind

public PluginResult pre_bind(PluginDetail pc) throws Exception;
public PluginResult when_bind_replace(PluginDetail pc) throws Exception; 
public PluginResult post_bind(PluginDetail pc) throws Exception;

E.3.5.2 ServerPlugin Methods for Ldapcompare

public PluginResult pre_compare(PluginDetail pc) throws Exception;
public PluginResult when_compare_replace(PluginDetail pc) throws Exception; 
public PluginResult post_compare(PluginDetail pc) throws Exception; 

E.3.5.3 ServerPlugin Methods for Ldapadd

public PluginResult pre_add(PluginDetail pc) throws Exception;
public PluginResult when_add(PluginDetail pc) throws Exception;
public PluginResult when_add_replace(PluginDetail pc) throws Exception;
public PluginResult post_add(PluginDetail pc) throws Exception;

E.3.5.4 ServerPlugin Methods for Ldapmodify

public PluginResult pre_modify(PluginDetail pc) throws Exception;
public PluginResult when_modify(PluginDetail pc) throws Exception;
public PluginResult when_modify_replace(PluginDetail pc) throws Exception; 
public PluginResult post_modify(PluginDetail pc) throws Exception;

E.3.5.5 ServerPlugin Methods for Ldapmoddn

public PluginResult pre_moddn(PluginDetail pc) throws Exception;
public PluginResult when_moddn(PluginDetail pc) throws Exception;
public PluginResult when_moddn_replace(PluginDetail pc) throws Exception; 
public PluginResult post_moddn(PluginDetail pc) throws Exception;

E.3.5.6 ServerPlugin Methods for Ldapsearch

public PluginResult pre_search(PluginDetail pc) throws Exception;
public PluginResult when_search(PluginDetail pc) throws Exception;
public PluginResult when_search_replace(PluginDetail pc) throws Exception;
public PluginResult post_search(PluginDetail pc) throws Exception;

E.3.5.7 ServerPlugin Methods for Ldapdelete

public PluginResult pre_delete(PluginDetail pc) throws Exception;
public PluginResult when_delete(PluginDetail pc) throws Exception;
public PluginResult when_delete_replace(PluginDetail pc) throws Exception; 
public PluginResult post_delete(PluginDetail pc) throws Exception;Java plug-in API

E.4 Java Plug-in Error and Exception Handling

The Oracle Internet Directory server catches all unhandled exceptions during the execution of the plug-in. The exception stack trace and message for each exception is logged in the server log file. These exceptions fall into three categories:

  • Run-time errors and exceptions occur due to faulty plug-in code or logic. The server catches all run-time errors and exceptions, including NullPointerExceptions, raised during the execution of the Java plug-in. These errors and exceptions are logged in the server log file.

  • Expected exceptions thrown by the plug-in are logged in the Oracle Internet Directory server log file. In addition, a plug-in can catch an exception and throw it back to the server to log it in the server log file.

  • A plug-in can use the PluginException class to raise an error. The error message passed to the server with the PluginException object or its subclasses is passed on to the LDAP client. The server also logs this message in the server log file along with the exception stack trace and message.

This section includes three examples. They are:

E.4.1 Run-time Exception Example

The log entry for a typical exception raised during execution of a plug-in looks like this:

….
06:17:03 * 
    ERROR * gslpg_exceptionHndlr * Exception Message : Error
    ERROR * gslpg_exceptionHndlr * Exception Stack Trace :
              MyCompareJavaPlugin.post_compare(Prog2.java:75)
END
              
BEGIN
2004/10/19:01:52:13 * 
    ServerWorker (REG):4 * ConnID:0 * OpID:1 * OpName:compare
    ERROR * gslpg_exceptionHndlr * Exception Stack Trace :
               java.lang.NullPointerException
              java.util.Hashtable.put(Hashtable.java:393)
               oracle.ldap.ospf.PluginDetail.put(PluginDetail.java:41)
END

E.4.2 Run-time Error Example

The error occurred because the plug-in MyJavaPlugin did not exist in the $ORACLE_HOME/ldap/server/plugin directory. The log file entry looks like this:

BEGIN
2004/10/19:01:52:13 * 
    ServerWorker (REG):4 * ConnID:0 * OpID:1 * OpName:compare
    ERROR * gslpg_exceptionHndlr * Exception Stack Trace :
               java.lang.NoClassDefFoundError: MyJavaPlugin                
END

E.4.3 PluginException Example

The Oracle Internet Directory server returns the standard plug-in error message to the LDAP client along with the additional error message if a PluginException object is thrown back to the server. The error displayed by the LDAP client looks something like this:

ldap_compare: UnKnown Error Encountered
ldap_compare: additional info: Error Message returned by the Java Plug-in 

E.5 Java Plug-in Debugging and Logging

A plug-in can maintain its own log file and log to it in real time. In addition, a plug-in can log debug messages in the Oracle Internet Directory server log file during execution by using the ServerLog class. The method for logging messages in the ServerLog class is:

public static void log(String message);

Messages logged by the ServerLog.log() method are preceded by the string:

* Server Java Plug-in *

For example:

2006/05/11:01:11:28 * ServerWorker (REG):7
  ConnID:241 * mesgID:2 * OpID:1 * OpName:bind
01:11:28 * Server Java Plug-in * MESSAGE FROM PLUGIN
01:11:28 * Server Java Plug-in * Bind DN :
 cn=ad_user,cn=oiddvusers,cn=oraclecontext,dc=us,dc=oracle,dc=com

To log plug-in debug messages to the server log, you must start the Oracle Internet Directory server using one of the following debug levels:

Table E-16 Debug Levels for Java Plug-in Logging

Oracle Internet Directory Server Debug Level Debug Level Meaning

134217728

All Java plug-in debug messages and internal server messages related to the Java plug-in framework

268435456

All messages passed by a Java plug-in using the ServerLog object.

402653184

Both of the above


The ServerLog.log() method is thread safe. Execution of this method can degrade performance.

E.6 Java Plug-in Examples

This sections includes two examples. They are:

Note:

Do not use System.exit() in a Java plug-in. Doing so might lead to unpredictable behavior by the Oracle directory server.

E.6.1 Example 1: Password Validation Plug-in

This example illustrates a Java plug-in that validates a userPassword before the ldapmodify operation. A pre Java plug-in is registered with the Oracle Internet Directory server. The plug-in configuration includes the minimum password length to be checked for in the plug-in. This information is registered in the plug-in configuration entry using an orclPluginFlexfield attribute. The subtype minPwdLength specifies the minimum length. This information is passed to the plug-in using the PluginFlexfield. The orclPluginName specifies the name of the Java Plug-in to be invoked by the Oracle Internet Directory server.

The input to the plug-in is a PluginDetail and the output from the plug-in is a PluginResult.

E.6.1.1 Password Validation Plug-in Configuration Entry

dn: cn=checkuserpassword,cn=plugin,cn=subconfigsubentry
orclPluginFlexfield;minPwdLength: 8
objectclass: orclPluginConfig
objectclass: top
orclpluginname: CheckPassword
orclplugintype: configuration
orclplugintiming: pre
orclpluginldapoperation: ldapmodify
orclpluginenable: 1
orclpluginsubscriberdnlist: cn=users,dc=us,dc=oracle,dc=com
orclpluginattributelist: userPassword
orclPluginKind: Java

E.6.1.2 Password Validation Plug-in Code Example

import java.io.*;
import java.lang.*;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
import oracle.ldap.ospf.*;
/**
 * This PRE modify plug-in will check whether the "userPassword"
 * is greater than 8 characters in length
 */
public class CheckPassword extends ServerPluginAdapter {
 
    // This PRE modify plug-in takes in a PluginDetail Object
    // and returns a PluginResult Object
    public PluginResult pre_modify(PluginDetail plgObj)
       throws Exception
    {
       try {
         // Retrieve the LdapOperation Object from the PluginDetail
         ModifyLdapOperation opObj = (ModifyLdapOperation)
plgObj.getLdapOperation();
 
        
         // Retrieve the LdapModification Object from the LdapOperation
            LdapModification modObj = opObj.getLdapModification();
 
 
        
         // Retrieve the PluginFlexfield Object from the PluginDetail
         PluginFlexfield flxFldObj = plgObj.getPluginFlexfield();
        
         // Retrieve the custom information from the PluginFlexfield
         // Get the minimum password length
 String passwdlength =
            flxFldObj.getFlexfield("minPwdLength");
 
        // Create a Result Object to return to the OID server
           PluginResult plgResObj = new PluginResult();
 
         // Check if the LdapModification Object is a NULL
         // set the appropriate error and error message
         if (modObj==null)
         {
            throw new PluginException("CheckPassword Plug-in Execution
Error");
         }
 
          // Retrieve the "userPassword" Attribute Value
         ModificationItem modItem = modObj.getModificationItemAt(0);
         BasicAttribute attr = (BasicAttribute)modItem.getAttribute();
         String attrval = null;
          if ((attr.getID()).equals("userpassword"))
     attrval = attr.get(0);
 
         // Check for the password length and set appropriate error
         // and error message
          if (attrval.length() < Integer.parseInt(passwdlength))
         {
             throw new PluginException("userPassword is less than 8
characters");
         }
        
        // Return the PluginResult Object to the OID Server
        return plgResObj;
    }
    // Catch any unexpected exception which may occur and throw
    // it back to the OID server to log it
    catch (Exception e)
    {
        throw e;
    }
  }
} 

E.6.2 Example 2: External Authentication Plug-in for Active Directory

This example illustrates an external authentication plug-in for Active Directory. When a client requests an ldapcompare operation for userPassword, the server invokes this Java plug-in to authenticate the user against Active Directory.

E.6.2.1 External Authentication Plug-in Configuration Entry

dn: cn=when_rep_comp,cn=plugin,cn=subconfigsubentry
orclpluginsubscriberdnlist: cn=users,dc=us,dc=oracle,dc=com;
orclpluginflexfield;ad-host: dlin-pc2.us.example.com
orclpluginflexfield;ad-port: 3060
orclpluginflexfield;ad-su-dn: administrator@dlin.net
orclpluginflexfield;ad-su-passwd: password1
objectclass: orclPluginConfig
objectclass: top
orclpluginname: ExtAuthAD
orclplugintype: configuration
orclplugintiming: when
orclpluginisreplace: 1
orclpluginldapoperation: ldapcompare
orclpluginversion: 1.0.1
cn: when_rep_comp
orclpluginkind: Java
orclpluginenable: 1

E.6.2.2 External Authentication Plug-in Code

public class ExtAuthAD extends ServerPluginAdapter {

public PluginResult when_compare_replace(PluginDetail plgObj)
   throws Exception {
   try {

       // Retrieve the LdapOperation from the PluginDetail
       CompareLdapOperation opObj = 
           (CompareLdapOperation) plgObj.getLdapOperation();       String baseDn = plgObj.getLdapBaseEntry().getDN();

       // Retrieve the Base DN, Attribute and Attribute Value
       String bdn = baseDn.substring(0,
             baseDn.lastIndexOf("cn=users,dc=us,dc=oracle,dc=com")-1)
             +",cn=users,dc=dlin,dc=net";
       String ban = opObj.getAttributeName();       String bav = opObj.getAttributeValue().toString();

       // Retrieve the AD Information from the PluginFlexfield
       PluginFlexfield flxObj = plgObj.getPluginFlexfield();
       String adhost = flxObj.getFlexfield("ad-host");
       String adport = flxObj.getFlexfield("ad-port");
       String adsudn = flxObj.getFlexfield("ad-su-dn");
       String adsupasswd = flxObj.getFlexfield("ad-su-passwd");

       // Create a PluginResult Object to return to the OID server
       PluginResult plgResObj = new PluginResult();


       // Create a Hashtable with values required to connect to AD
       Hashtable env = new Hashtable();

       env.put(Context.INITIAL_CONTEXT_FACTORY,
               "com.sun.jndi.ldap.LdapCtxFactory");
       env.put(Context.PROVIDER_URL, "ldap://"+adhost+":"+adport);
       env.put(Context.SECURITY_AUTHENTICATION, "simple");
       env.put(Context.SECURITY_PRINCIPAL, bdn);
       env.put(Context.SECURITY_CREDENTIALS, bav);

       // Try to connect to AD
       DirContext dirContext = null;
       try {
         dirContext = new InitialDirContext(env);
         if (dirContext != null) {
             // User has been successfully authenticated, add the appropriate
             // result code to the LdapOperation
             opObj.setOperationResultCode(6);
         }
       }
       catch(NamingException ne) {
        // Unable to connect to the AD directory server with the given
        // credentials, add the appropriate result code to the LdapOperation
         opObj.setOperationResultCode(5);
       }

       // Add the LdapOperation to the PluginResult
       plgResObj.setLdapOperation(opObj);

       // Return the PluginResult
       return plgResObj;

  } catch(Exception e) {
     // In case of any unexpected errors in the plug-in, throw the Exception
     // back to the OID server to log it     throw e;
   }
  }
 }