Version 5.1
Note |
---|
Before using this information and the product it supports, read the general information under Appendix E, Notices. |
First Edition (November 2002)
This edition applies to version 5, release 1, of the IBM(R) Directory Server and to all subsequent releases and modifications until otherwise indicated in new editions.
(C) Copyright International Business Machines Corporation 1999, 2002. All rights reserved.
U.S. Government Users Restricted Rights -- Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
Introduction to server plug-ins
Appendix A. Supported database functions
Appendix B. Supported iPlanet APIs
Appendix D. Deprecated plug-in APIs
Use the IBM Directory Server Plug-ins Reference to help you create plug-ins that extend the capabilities of your Directory Server.
Database plug-ins can be used to integrate your own database as a back-end to the server. For example, you can write a plug-in that integrates a relational database with the Directory Server.
Server plug-ins extend the capabilities of your Directory Server. They are dynamically loaded into the LDAP server's address space when it is started. After the plug-ins are loaded, the server calls the functions in a shared library by using function pointers.
A server front-end listens to the wire, receives and parses requests from clients, and then processes the requests by calling an appropriate database back-end function.
A server back-end reads and writes data to the database containing the directory entries. In addition to the default database operations, the LDAP server Database 2(TM) (DB2(R)) back-end also provides functions for supporting replication and dynamic schema updates.
If the front-end fails to process a request it returns an error message to the client; otherwise, the back-end is called. After the back-end is called, it must return a message to the client. Either the front-end or the back-end, but not both can return a message to the client.
This release of the IBM Directory Server supports the following types of server plug-ins:
A server plug-in can return a message to the client as well. However, make sure that the server returns only one message.
A pblock is an opaque structure in which many parameters are stored. It is used to communicate between the server and your plug-ins. Application program interfaces (APIs) are provided for your plug-ins to get (or set) parameters in this structure.
Notes:
The following are examples of supported compilers:
To write your own plug-in:
The following output is received from your functions:
keyword plugin-type plugin-path init-func args ...
dn: Directory, cn=RDBM Backends, cn=IBM SecureWay, cn=Schemas, cn=Configuration ibm-slapdPlugin: database /lib/libldap-2dbm.dll rdbm -backend -init
The following rules apply when you place a plug-in directive in the configuration file:
ibm-slapdPlugin is the attribute used to specify a plug-in that can be loaded by the server. This attribute is one of the attributes contained in objectclasses, such as ibm-slapdRdbmBackend and ibm-slapdLdcfBackend. For instance, in the ibmslapd.conf file, there is an entry that identifies the rdbm back-end. In this entry, a database plug-in is specified by using the ibm-slapdPlugin attribute so that the server knows where and how to load this plug-in. If there is another plug-in to be loaded, such as a changelog plug-in, then specify it using another ibm-slapdPlugin attribute.
dn: cn=Directory,cn=RDBM Backends,cn=IBM SecureWay,cn=Schemas,cn=Configuration ... objectclass: ibm-slapdRdbmBackend ibm-slapdPlugin: database libback-rdbm.dll rdbm_backend_init ibm-slapdPlugin: preoperation libcl.dll CLInit "cn=changelog"
Database plug-ins can be used to integrate your own database as a back-end to the server. A database plug-in can consist of all or a portion of the functions discussed in this section.
The following LDAP protocol-related functions are also the default database functions:
These database back-end-related functions are used to initialize or shut down the back-end and to handle back-end-specific configuration:
The following plug-in functions can be performed before, during, or after an LDAP operation.
The following pre-operation functions can be executed before an LDAP operation is performed:
The following post-operation plug-in functions can be executed after an LDAP operation is performed:
LDAP operations can be extended with your own extended operation functions provided by a plug-in. An extended operation function might have an interface such as:
int myExtendedOp(Slapi_PBlock *pb);
In this function, you can obtain the input parameters from the parameter block passed in and communicate back from the server front-end with the output parameters. See the following sections for information about input and output parameters.
These parameters can be obtained by calling the slapi_pblock_get API.
These parameters can be put to the parameter block passed in by the server by calling the slapi_pblock_set API.
After receiving and processing an extended operation request, an extended operation plug-in function might itself send an extended operation response back to a client or let the server send such a response. If the plug-in sends a response, it might call the slapi_send_ldap_result() function and return a result code SLAPI_PLUGIN_EXTENDED_SEND_RESULT to the server indicating that the plug-in has already sent a LDAP result message to the client. If the plug-in has not sent an LDAP result message to the client, the plug-in returns an LDAP result code and the server sends this result code back to the client.
To register an extended operation function, the initialization function of the extended operation plug-in might call slapi_pblock_set() to set the SLAPI_PLUGIN_EXT_OP_FN to the extended operation function and the SLAPI_PLUGIN_EXT_OP_OIDLIST parameter to the list of extended operation OIDs supported by the function. The list of OIDs which is listed in the ibm-slapdPlugin directive in the ibmslapd.conf file can be obtained by getting the SLAPI_PLUGIN_ARGV parameter from the pblock passed in.
For example, in the Windows NT environment, add the following to specify an extended operation plug-in in the ibmslapd.conf file for the database rdbm:
dn: cn=Directory, cn=RDBM Backends, cn=IBM SecureWay, cn=Schemas, cn=Configuration ibm-slapdPlugin database /bin/libback-rdbm.dll rdbm_backend_init ibm-slapdPlugin extendedop /tmp/myextop.dll myExtendedOpInit 123.456.789
File paths starting with a forward slash ( / ) are relative to the LDAP installation directory; /tmp is changed to ldap_installation_directory\tmp, but C:\tmp is unchanged. This indicates that the function myExtendedOpInit, which can be found in the /path/myextop.dll shared library, is executed when the server starts. The myExtendedOp that is registered in the initialization is used to handle extended-operation plug-in function. This function handles extended operations with the Object Identifier (OID) 123.456.789.
Administrators on some platforms might want to use the system audit facilities to log the LDAP audit record with the system-defined record format. To allow flexibility in logging and record formats, a plug-in interface is provided. The server uses this interface to provide three types of auditing-related data to the external audit plug-ins if the auditing configuration is set to on. The data is passed to the external audit plug-ins through the standard plug-in's pblock interfaces, slapi_pblock_set() and slapi_pblock_get().
The three types of audit data available to the external audit plug-ins are:
A default audit plug-in is provided and configured with the server. This plug-in performs the logging and formatting of the LDAP audit record. This default plug-in can be replaced with the platform-specific audit plug-in, if available, by changing the plug-in configuration lines in the ibmslapd.conf configuration file or through the IBM Directory Server Web Administration Tool.
The Audit Service has the following configuration options:
These options are stored in the LDAP directory to allow dynamic configuration. A directory entry, cn=audit, cn=localhost, is created to contain these options. The access to the values of these options are controlled through the access control list (ACL) model. By default, the LDAP administrator is the owner of this cn=audit entry. However, with the current ACL functionality, an auditor role can be created so that only the auditor can change the option values and location of the audit log.
The values of the audit configuration options are returned when a search of cn=monitor is requested by the LDAP administrator. These include:
The following are examples of the various operations:
2001-07-24-15:01:01.345-06:00--V3 Bind-- bindDN:cn=test--client:9.1.2.3:12345--ConnectionID:12-- received:2001-07-24-15:01:01.330-06:00--adminAuthority:Y--success name: cn=test authenticationChoice: simple 2001-07-24-15:01:02.367-06:00--V3 Search-- bindDN:cn=test--client:9.1.2.3:12345--ConnectionID:12-- received:2001-07-24-15:01:02.360-06:00--adminAuthority:Y--success base: o=ibm_us,c=us scope: wholeSubtree derefAliases: neverDerefAliases typesOnly: false filter: (&(cn=c*)(sn=a*))
2001-07-24-15:22:33.541-06:00--V3 unauthenticated Search-- bindDN: <*CN=NULLDN*>--client:9.1.2.2:32412--ConnectionID:18-- received:2001-07-24-15:22:33.539-06:00--adminAuthority:Y--success 2001-07-24-15:22:34.555-06:00--V3 SSL unauthenticated Search-- bindDN: <*CN=NULLDN*>--client:9.1.2.2:32412--ConnectionID:19-- received:2001-07-24-15:22:34.550-06:00--adminAuthority:Y--success 2001-07-24-15:01:03.123-06:00--V3 Add-- bindDN:cn=test--client:9.1.2.3:12345--ConnectionID:12-- received:2001-07-24-15:01:03.100-06:00--adminAuthority:Y--entryAlreadyExists entry: cn=Jim Brown, ou=sales,o=ibm_us,c=us attributes: objectclass, cn, sn, telphonenumber 2001-07-24-15:01:04.378-06:00--V3 Delete-- bindDN:cn=test--client:9.1.2.3:12345--ConnectionID:12-- received:2001-07-24-15:01:04.370-06:00--adminAuthority:Y--success entry: cn=Jim Brown, ou=sales,o=ibm_us,c=us 2001-07-24-15:01:05.712-06:00--V3 Modify-- bindDN:cn=test--client:9.1.2.3:12345--ConnectionID:12-- received:2001-07-24-15:01:05.708-06:00--adminAuthority:Y--noSuchObject object: cn=Jim Brown, ou=sales,o=ibm_us,c=us add: mail delete: telephonenumber 2001-07-24-15:01:06.534-06:00--V3 ModifyDN-- bindDN:cn=test--client:9.1.2.3:12345--ConnectionID:12-- received:2001-07-24-15:01:06.530-06:00--adminAuthority:Y--noSuchObject entry: cn=Jim Brown, ou=sales,o=ibm_us,c=us newrdn: ou=r&d deleteoldrdn: true 2001-07-24-15:01:07.913-06:00--V3 Unbind-- bindDN:cn=test--client:9.1.2.3:12345--ConnectionID:12-- received:2001-07-24-15:01:07.910-06:00--adminAuthority:Y--success
The following sections show input and output parameters for the default database functions.
This section shows the input parameters of the default database functions:
The three parameters in the first stanza are passed to the nine default database functions as input:
/* backend, connection, operation */ SLAPI_BACKEND SLAPI_CONNECTION SLAPI_OPERATION /* arguments that are common to all operations */ SLAPI_CONN_DN SLAPI_CONN_AUTHTYPE SLAPI_REQCONTROLS /* add arguments */ SLAPI_ADD_TARGET SLAPI_ADD_ENTRY /* bind arguments */ SLAPI_BIND_TARGET SLAPI_BIND_METHOD SLAPI_BIND_CREDENTIALS SLAPI_BIND_SASLMECHANISM /* bind return values */ SLAPI_BIND_RET_SASLCREDS /* compare arguments */ SLAPI_COMPARE_TARGET SLAPI_COMPARE_TYPE SLAPI_COMPARE_VALUE /* delete arguments */ SLAPI_DELETE_TARGET /* modify arguments
*/ SLAPI_MODIFY_TARGET SLAPI_MODIFY_MODS /* modrdn arguments */ SLAPI_MODRDN_TARGET SLAPI_MODRDN_NEWRDN SLAPI_MODRDN_DELOLDRDN SLAPI_MODRDN_NEWSUPERIOR /* search arguments */ SLAPI_SEARCH_TARGET SLAPI_SEARCH_SCOPE SLAPI_SEARCH_DEREF SLAPI_SEARCH_SIZELIMIT SLAPI_SEARCH_TIMELIMIT SLAPI_SEARCH_FILTER SLAPI_SEARCH_STRFILTER SLAPI_SEARCH_ATTRS SLAPI_SEARCH_ATTRSONLY /* abandon arguments */ SLAPI_ABANDON_MSGID /* plugin types supported */ #define SLAPI_PLUGIN_DATABASE #define SLAPI_PLUGIN_EXTENDEDOP #define SLAPI_PLUGIN_PREOPERATION #define SLAPI_PLUGIN_POSTOPERATION #define SLAPI_PLUGIN_AUDIT /* plugin configuration params */ #define SLAPI_PLUGIN #define SLAPI_PLUGIN_PRIVATE #define SLAPI_PLUGIN_TYPE #define SLAPI_PLUGIN_ARGV #define SLAPI_PLUGIN_ARGC /* audit plugin defines */ #define SLAPI_PLUGIN_AUDIT_DATA #define SLAPI_PLUGIN_AUDIT_FN /* managedsait control */ #define SLAPI_MANAGEDSAIT /* config stuff */ #define SLAPI_CONFIG_FILENAME #define SLAPI_CONFIG_LINENO #define SLAPI_CONFIG_ARGC #define SLAPI_CONFIG_ARGV /* operational params */ #define SLAPI_TARGET_DN #define SLAPI_REQCONTROLS /* modrdn params */ #define SLAPI_MODRDN_TARGET_UP #define SLAPI_MODRDN_TARGET #define SLAPI_MODRDN_NEWRDN #define SLAPI_MODRDN_DELOLDRDN #define SLAPI_MODRDN_NEWSUPERIOR /* extended operation params */ #define SLAPI_EXT_OP_REQ_OID #define SLAPI_EXT_OP_REQ_VALUE /* Search result params */ #define SLAPI_NENTRIES
The following are the output parameters of the default database functions:
/* common for internal plugin_ops */ SLAPI_PLUGIN_INTOP_RESULT SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES SLAPI_CONN_DN SLAPI_CONN_AUTHTYPE /# Types of authentication (for SLAPI_CONN_AUTHTYPE) */ #define SLAPD_AUTH_NONE "none" #define SLAPD_AUTH_SIMPLE "simple" #define SLAPD_AUTH_SSL "SSL" #define SLAPD_AUTH_SASL "SASL " /* followed by the mechanism name */
The following iPlanet APIs are supported in this release:
int slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value ); int slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value ); Slapi_PBlock *slapi_pblock_new(); void slapi_pblock_destroy( Slapi_PBlock* );
char *slapi_ch_malloc( unsigned long size ); void slapi_ch_free( void *ptr ); char *slapi_ch_calloc( unsigned long nelem, unsigned long size ); char *slapi_ch_realloc(char *block, unsigned long size ); char *slapi_ch_strdup(char *s );
void slapi_send_ldap_result( Slapi_PBlock *pb, int err, char *matched, char *text, int nentries, struct berval **urls);
char *slapi_dn_normalize( char *dn ); char *slapi_dn_normalize_case( char *dn ); char *slapi_dn_ignore_case( char *dn ); char *slapi_dn_normalize_v3( char *dn ); char *slapi_dn_normalize_case_v3( char *dn ); char *slapi_dn_ignore_case_v3( char *dn ); char *slapi_dn_compare_v3(char *dn1, char* dn2); int slapi_dn_issuffix(char *dn, char *suffix); char *slapi_entry2str( Slapi_Entry *e, int *len ); Slapi_Entry *slapi_str2entry( char *s, int flags ); int slapi_entry_attr_find( Slapi_Entry *e, char *type, Slapi_Attr **attr ); int slapi_entry_attr_delete( Slapi_Entry *e, char *type ); char *slapi_entry_get_dn( Slapi_Entry *e ); void slapi_entry_set_dn(Slapi_Entry *e, char *dn); Slapi_Entry *slapi_entry_alloc(); Slapi_Entry *slapi_entry_dup( Slapi_Entry *e); init slapi_send_ldap_search_entry( Slapi_PBlock *pb, Slapi_Entry *e, LDAPControl **ectrls, char **attrs, int attrsonly); void slapi_entry_free( Slapi_Entry *e ); int slapi_attr_get_values( Slapi_Attr *attr, struct berval ***vals ); Slapi_Filter *slapi_str2filter( char *str ); init slapi_filter_get_choice( Slapi_Filter*f ); init slapi_filter_get_ava( Slapi_Filter*f, char *type, struct berval **bvals ); void slapi_filter_free( Slapi_Filter*f, int recurse ); Slapi_Filter *slapi_filter_list_first( Slapi_Filter*f ); Slapi_Filter *slapi_filter_list_next(Slapi_Filter*f, Slapi_Filter*fprev); int slapi_is_connection_ssl( Slapi_PBlock *pPB, int *isSSL ); init slapi_get_client_port( Slapi_PBlock *pPB, int *fromPort );
Slapi_PBlock *slapi_search_internal( char *base, int scope, char *filter, LDAPControl **controls, char **attrs, int attrsonly ); Slapi_PBlock *slapi_modify_internal( char *dn, LDAPMod **mods, LDAPControl **controls ); Slapi_PBlock *slapi_add_internal( char * dn, LDAPMod **attrs, LDAPControl **controls ); Slapi_PBlock *slapi_add_entry_internal( Slapi_Entry * e, LDAPControl **controls, int log_change ); Slapi_PBlock *slapi_delete_internal( char * dn, LDAPControl **controls ); Slapi_PBlock *slapi_modrdn_internal( char * olddn, char * newrdn, char *newParent, int deloldrdn, LDAPControl **controls); void slapi_free_search_results_internal( Slapi_PBlock *pb ); /* logging routines */ void slapi_printmessage(int catid, int level, int num, ... ); int slapi_log_error( int severity, char *subsystem, char *fmt, ... );
char **slapi_get_supported_saslmechanisms(); char **slapi_get_supported_extended_ops(); void slapi_register_supported_saslmechanism( char *mechanism ); int slapi_get_supported_controls(char ***ctrloidsp, unsigned long **ctrlopsp); void slapi_register_supported_control(char *controloid, unsigned long controlops); int slapi_control_present( LDAPControl **controls, char *oid, struct berval **val, int * iscritical);
int slapi_log_error( int severity, char *subsystem, char *fmt, ... );
slapi_pblock_get() receives the value of a name-value pair from a parameter block.
#include "slapi-plugin.h" int slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value );
slapi_pblock_set() sets the value of a name-value pair in a parameter block.
#include "slapi-plugin.h" int slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value );
slapi_pblock_new() creates a new parameter block.
#include "slapi-plugin.h" Slapi_PBlock *slapi_pblock_new();
slapi_pblock_destroy() frees the specified parameter block from memory.
#include "slapi-plugin.h" void slapi_pblock_destroy( Slapi_PBlock *pb );
slapi_ch_malloc() allocates space in memory, and calls the standard malloc() C function. The slapd server is terminated with an accompanying out of memory error message if memory cannot be allocated.
#include "slapi-plugin.h" char * slapi_ch_malloc( unsigned long size );
slapi_ch_calloc() allocates space for an array of elements of a specified size. It calls the calloc() C function. The slapd server is terminated with an accompanying out of memory error message if memory cannot be allocated.
#include "slapi-plugin.h" char * slapi_ch_calloc( unsigned long nelem, unsigned long size );
slapi_ch_realloc() changes the size of a block of allocated memory. It calls the standard realloc() C function. The slapd server is terminated with an accompanying out of memory error message if memory cannot be allocated.
#include "slapi-plugin.h" char * slapi_ch_realloc( char *block, unsigned long size );
slapi_ch_strdup() makes a copy of an existing string. It calls the standard strdup() C function. The slapd server is terminated with an accompanying out of memory error message if memory cannot be allocated.
#include "slapi-plugin.h" char * slapi_ch_strdup( char *s );
slapi_ch_free() frees space allocated by the slapi_ch_malloc(), slapi_ch_calloc(), slapi_ch_realloc(),and slapi_ch_strdup() functions. It does not set the pointer to NULL.
#include "slapi-plugin.h" void slapi_ch_free( void *ptr );
slapi_send_ldap_result() sends an LDAP result code back to the client.
#include "slapi-plugin.h" void slai_send_ldap_result( Slapi_PBlock *pb, int err, char *matched, char *text, int nentries, struct berval **urls );
slapi_dn_normalize() converts a DN to canonical format (that is, no leading or trailing spaces, no spaces between components, and no spaces around the equals sign). As an example, for the following DN: cn = John Doe, ou = Engineering , o = Darius the function returns:
cn=John Doe,ou=Engineering,o=Darius
#include "slapi-plugin.h" char *slapi_dn_normalize( char *dn );
slapi_dn_normalize_case() converts a distinguished name (DN) to canonical format (that is, no leading or trailing spaces, no spaces between components, and no spaces around the equals sign) and converts all characters to lower case. As an example, for the following DN: cn = John Doe, ou = Engineering , o = Darius the function returns:
cn=john doe,ou=engineering,o=darius
#include "slapi-plugin.h" char *slapi_dn_normalize_case ( char *dn );
slapi_dn_ignore_case() converts all of the characters in a distinguished name (DN) to lower case. As an example, for the following DN: cn = John Doe, ou = Engineering , o = Darius the function returns:
cn = john doe , ou = engineering , o = darius
#include "slapi-plugin.h" char *slapi_dn_ignore_case ( char *dn );
slapi_dn_normalize_v3() converts a distinguished name(DN) to canonical format (that is, no leading or trailing spaces, no spaces between components, and no spaces around the equals sign). The API normalizes the attribute type name to the first textual type name in the schema definition. Any semicolons used to separate relative distinguished names (RDN) are converted to commas. A compound RDN is sorted alphabetically by attribute name. The following is an example DN:
userName=johnDOE + commonName = John Doe ; ou = Engineering , o = Darius the function returns: cn=John Doe+userName=johnDOE,ou=Engineering,o=Darius
Special characters in a DN, if escaped using double-quotes, are converted to use backslash ( \ ) as the escape mechanism. For example, the following DN:
cn="a + b", o=ibm, c=us the function returns cn=a \+ b,o=ibm,c=us
An attribute value containing a backslash followed by a two-digit hex representation of a UTF-8 character is converted to the character representation. For example, the following DN:
cn=\4A\6F\68\6E Doe,ou=Engineering,o=Darius the function returns cn=John Doe,ou=Engineering,o=Darius
A ber-encoded attribute value is converted to a UTF-8 value. For example, the following DN:
cn=#04044A6F686E20446F65,ou=Engineering,o=Darius the function returns cn=John Doe,ou=Engineering,o=Darius
An invalid DN returns NULL.
#include "slapi-plugin.h" char *slapi_dn_normalize_v3(char *dn);
slapi_dn_normalize_v3() converts a distinguished name (DN) to canonical format (that is, no leading or trailing spaces, no spaces between components and no spaces around the equals sign). The API normalizes the attribute type name to the first textual type name in the schema definition. Any semicolons used to separate relative distinguished names (RDN) are converted to commas. A compound RDN is sorted alphabetically by attribute name. The case of attribute types is changed to uppercase in all cases. The case of the attribute values is converted to uppercase only when the matching rules are case insensitive. If the matching rules for the attribute are case sensitive, the case of the attribute value is preserved. In the following example, userName is a case sensitive attribute and cn, ou and o are case insensitive. For example, the following DN:
userName=johnDOE + commonName = John Doe ; ou = Engineering , o = Darius the function returns: CN=JOHN DOE+USERNAME=johnDOE,OU=ENGINEERING,O=DARIUS
Special characters in a DN, if escaped using double-quotes, are converted to use backslash ( \ ) as the escape mechanism. For example, the following DN:
cn="a + b", o=ibm, c=us the function returns CN=A \+ B,O=IBM,C=US
An attribute value containing a backslash followed by a two-digit hex representation of a UTF-8 character is converted to the character representation. For example, the following DN:
cn=\4A\6F\68\6E Doe,ou=Engineering,o=Darius the function returns CN=JOHN DOE,OU=ENGINEERING,O=DARIUS
A ber-encoded attribute value is converted to a UTF-8 value. For example, the following DN:
cn=#04044A6F686E20446F65,ou=Engineering,o=Darius the function returns CN=JOHN DOE,OU=ENGINEERING,O=DARIUS
An invalid DN returns NULL.
#include "slapi-plugin.h" char *slapi_dn_normalize_case_v3(char *dn);
slapi_dn_ignore_case_v3() normalizes a distinguished name (DN) and converts all of the characters to lower case. For example, the following DN:
userName=johnDOE + commonName = John Doe ; ou = Engineering , o = Darius the function returns: cn=john doe+username=johndoe,ou=engineering,o=darius
#include "slapi-plugin.h" char *slapi_dn_ignore_case _v3(char *dn);
slapi_dn_compare_v3() compares two distinguished names (DN).
#include "slapi-plugin.h" char *slapi_dn_compare_v3(char *dn1, char* dn2);
slapi_dn_issuffix() determines whether a DN is equal to the specified suffix.
#include "slapi-plugin.h" int slapi_dn_issuffix( char *dn, char *suffix );
slapi_entry2str() generates a description of an entry as a string. The LDIF string has the following format:
dn: <dn>\n [<attr>: <value>\n]* [<attr>:: <base_64_encoded_value>]
where:
For example:
dn: uid=rbrown2, ou=People, o=airius.com cn: Robert Brown sn: Brown ...
When you no longer need to use the string, you can free it from memory by calling the slapi_ch_free() function.
Call the slapi_entry2str() function to convert a string description in this format to an entry of the Slapi_Entry data type.
#include "slapi-plugin.h" char *slapi_entry2str( Slapi_Entry *e, int *len );
slapi_str2entry() converts an LDIF description of a directory entry (a string value) into an entry of the Slapi_Entry data type that can be passed to other API functions.
If there are errors during the conversion process, the function returns a NULL instead of the entry.
When you have finished working with the entry, call the slapi_entry_free() function. To convert an entry to a string description, call slapi_entry2str().
#include "slapi-plugin.h" Slapi_Entry *slapi_str2entry( char *s, int flags );
The flags argument can be one of the following values:
slapi_entry_attr_find() determines whether an entry has a specified attribute. If it does, this function returns that attribute.
#include "slapi-plugin.h" int slapi_entry_attr_find( Slapi_Entry *e, char *type, Slapi_Attr **attr );
slapi_entry_attr_delete() deletes an attribute from an entry.
#include "slapi-plugin.h" int slapi_entry_attr_delete (Slapi_Entry *e, char *type);
slapi_entry_get_dn() receives the DN of the specified entry.
#include "slapi-plugin.h" char *slapi_entry_get_dn( Slapi_Entry *e );
slapi_entry_set_dn() sets the DN of an entry. It sets the pointer to the DN that you specify.
#include "slapi-plugin.h" void *slapi_entry_set_dn( Slapi_Entry *e char *dn );
slapi_entry_alloc() allocates memory for a new entry of the Slapi_Entry data type. It returns an empty Slapi_Entry structure. You can call other front-end functions to set the DN and attributes of this entry. When you have finished working with the entry, free it by calling the slapi_entry_free() function.
#include "slapi-plugin.h" Slapi_Entry *slapi_entry_alloc();
slapi_entry_dup() makes a copy of an entry, its DN, and its attributes. You can call other front-end functions to change the DN and attributes of this copy of an existing Slapi_Entry structure. When you have finished working with the entry, free it by calling the slapi_entry_free() function.
#include "slapi-plugin.h" Slapi_Entry *slapi_entry_dup( Slapi_Entry *e );
slapi_send_ldap_search_entry() sends an entry found by a search back to the client.
#include "slapi-plugin.h" int slapi_send_ldap_search_entry( Slapi_PBlock *pb, Slapi_Entry *e, LDAPControl **ectrls, char **attrs, int attrsonly );
slapi_entry_free() frees an entry, its DN, and its attributes from memory.
#include "slapi-plugin.h" void slapi_entry_free( Slapi_Entry *e );
slapi_attr_get_values() receives the value of the specified attribute.
#include "slapi-plugin.h" int slapi_attr_get_values( Slapi_Attr *attr, struct berval ***vals );
slapi_str2filter() converts a string description of a search filter into into a filter of the Slapi_Filter type. When you have finished working with this filter, free the Slapi_Filter structure by calling slapi_filter_free().
#include "slapi-plugin.h" Slapi_Filter *slapi_str2filter( char *str );
slapi_filter_get_choice() gets the type of the specified filter (for example, LDAP_FILTER_EQUALITY).
#include "slapi-plugin.h" int slapi_filter_get_choice( Slapi_Filter *f );
slapi_filter_get_ava() gets the attribute type and the value from the filter. This applies only to filters of the types LDAP_FILTER_EQUALITY, LDAP_FILTER_GE, LDAP_FILTER_LE, and LDAP_FILTER_APPROX. These filter types generally compare a value against an attribute. For example: (cn=John Doe) This filter finds entries in which the value of the cn attribute is equal to John Doe.
Calling the slapi_filter_get_ava() function gets the attribute type and value from this filter. In the case of the example, calling the slapi_filter_get_ava() function gets the attribute type cn and the value John Doe.
#include "slapi-plugin.h" int slapi_filter_get_ava( Slapi_Filter *f, char **type, struct berval **bval );
slapi_filter_free() frees the specified filter and (optionally) the set of filters that comprise it; for example, the set of filters in an LDAP_FILTER_AND type filter.
#include "slapi-plugin.h" void slapi_filter_free( Slapi_Filter *f, int recurse );
slapi_filter_list_first() gets the first filter that makes up the specified filter. This applies only to filters of the types LDAP_FILTER_EQUALITY, LDAP_FILTER_GE, LDAP_FILTER_LE, and LDAP_FILTER_APPROX. These filter types generally consist of one or more other filters. For example, if the filter is (&(ou=Accounting)(l=Sunnyvale)) the first filter in this list is (ou=Accounting). Use the slapi_filter_list_first() function to get the first filter in the list.
#include "slapi-plugin.h" Slapi_Filter *slapi_filter_list_first ( Slapi_Filter *f );
slapi_filter_list_next() gets the next filter (following fprev) that makes up the specified filter f. This applies only to filters of the types LDAP_FILTER_EQUALITY, LDAP_FILTER_GE, LDAP_FILTER_LE, and LDAP_FILTER_APPROX. These filter types generally consist of one or more other filters. For example, if the filter is (&(ou=Accounting)(l=Sunnyvale)) the next filter after (ou=Accounting) in this list is (l=Sunnyvale). Use the slapi_filter_list_first() function to get the first filter in the list.
To iterate through all filters that make up a specified filter, call the slapi_filter_list_first() function and then call slapi_filter_list_next().
#include "slapi-plugin.h" Slapi_Filter *slapi_filter_list_next( Slapi_Filter *f, Slapi_Filter *fprev );
slapi_is_connection_ssl() is used by the server to determine whether the connection between it and a client is through a Secure Socket Layer (SSL).
#include "slapi-plugin.h" int slapi_is_connection_ssl( Slapi_PBlock *pPB, int *isSSL);
slapi_get_client_port() is used by the server to determine the port number used by a client to communicate to the server.
#include "slapi-plugin.h" int slapi_get_client_port( Slapi_PBlock *pPB, int *fromPort);
slapi_search_internal() performs an LDAP search operation to search the directory from your plug-in.
#include "slapi-plugin.h" Slapi_PBlock *slapi_search_internal( char *base, int scope, char *filter, LDAPControl **controls, char **attrs, int attrsonly );
slapi_modify_internal() performs an LDAP modify operation to modify an entry in the directory from a plug-in.
Unlike the standard LDAP modify operation, no LDAP result code is returned to a client; the result code is placed instead in a parameter block that is returned by the function.
#include "slapi-plugin.h" Slapi_PBlock *slapi_modify_internal( char *dn, LDAPMod **mods, LDAPControl **controls, int l );
slapi_add_internal() performs an LDAP add operation in order to add a new directory entry (specified by a DN and a set of attributes) from your plug-in. Unlike the standard LDAP add operation, no LDAP result code is returned to a client. The result code is instead placed in a parameter block that is returned by the function.
#include "slapi-plugin.h" Slapi_PBlock *slapi_add_internal( char * dn, LDAPMod **mods, LDAPControl **controls, int l );
slapi_add_entry_internal() performs an LDAP add operation to add a new directory entry (specified by an Slapi_Entry structure) from a plug-in function. Unlike the standard LDAP add operation, no LDAP result code is returned to a client. Instead, the result code is placed in a parameter block that is returned by the function.
#include "slapi-plugin.h" Slapi_PBlock *slapi_add_entry_internal( Slapi_Entry * e, LDAPControl **controls, int l );
If the DN of the new entry has a suffix that is not served by the Directory Server, SLAPI_PLUGIN_INTOP_RESULT is set to LDAP_REFERRAL.
slapi_delete_internal() performs an LDAP delete operation to remove a directory entry when it is called from your plug-in.
Unlike the standard LDAP delete operation, no LDAP result code is returned to a client. The result code is instead placed in a parameter block that is returned by the function.
#include "slapi-plugin.h" Slapi_PBlock *slapi_delete_internal( char * dn, LDAPControl **controls, int l );
slapi_modrdn_internal() performs an LDAP modify RDN operation to rename a directory entry from your plug-in.
Unlike the standard LDAP modify RDN operation, no LDAP result code is returned to a client. The result code is instead placed in a parameter block that is returned by the function.
#include "slapi-plugin.h" Slapi_PBlock *slapi_modrdn_internal( char * olddn, char * newrdn, int deloldrdn, LDAPControl **controls, int l);
slapi_free_search_results_internal() frees the memory associated with LDAP entries returned by the search.
#include "slapi-plugin.h" void slapi_free_search_results_internal( Slapi_PBlock *pb);
slapi_get_supported_saslmechanisms() obtains an array of the supported Simple Authentication and Security Layer (SASL) mechanisms names. Register new SASL mechanisms by calling the slapi_register_supported_saslmechanism() function.
#include "slapi-plugin.h" char ** slapi_get_supported_saslmechanisms( void );
slapi_get_supported_extended_ops() gets an array of the object IDs (OIDs) of the extended operations supported by the server. Register new extended operations by putting the OID in the SLAPI_PLUGIN_EXT_OP_OIDLIST parameter and calling the slapi_pblock_set() function.
#include "slapi-plugin.h" char **slapi_get_supported_extended_ops( void );
slapi_register_supported_saslmechanism() registers the specified Simple Authentication and Security Layer (SASL) mechanism with the server.
#include "slapi-plugin.h" void slapi_register_supported_saslmechanism( char *mechanism );
slapi_get_supported_controls() obtains an array of OIDs, which represent the controls supported by the directory server. Register new controls by calling the slapi_register_supported_control() function.
#include "slapi-plugin.h" int slapi_get_supported_controls( char ***ctrloidsp, unsigned long **ctrlopsp );
slapi_register_supported_control() registers the specified control with the server. It also associates the control with an OID. When the server receives a request that specifies this OID, the server makes use of this information to determine whether the control is supported by its server or its plug-ins.
#include "slapi-plugin.h" void slapi_register_supported_control( char *controloid, unsigned long controlops );
slapi_control_present() determines whether or not the specified OID identifies a control that might be present in a list of controls.
#include "slapi-plugin.h" int slapi_control_present( LDAPControl **controls, char *oid, struct berval **val, int *iscritical );
Writes a message to the error log for the directory server.
#include "slapi-plugin.h" int slapi_log_error( int severity, char *subsystem, char *fmt, ... );
The following entry in the ibmslapd.conf file results in a medium logging level:
#ibm-slapdSysLogLevel must be one of l/m/h (l=terse, h=verbose) ibm-slapdSysLogLevel: m
With this example in your ibmslapd.conf file, log messages with severity LDAP_MSG_HIGH or LDAP_MSG_MED are logged. The messages with severity LDAP_MSG_LOW are not logged. If the slapdSysLogLevel is set to h, all messages are logged.
<subsystem>: <message>
..., "%s\n", myString);
The following is an example of a pre-operation plug-in for bind in C.
#include "slapi-plugin.h" #define NEXTPLUGIN 0 #define STOP_PLUGIN_SEARCH 1 #define PWATTR "userpassword" #define CRAMMD5_MECH "CRAM-MD5" int DSPBind(Slapi_PBlock *pb); // This function registers function DSPBind as a pre-operation plug-in for // bind operations int DSPInit(Slapi_PBlock *pb) { int argc; char ** argv; if ( slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_BIND_FN, (void *)DSPBind) != 0 || slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0 || slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0 ) { printf("DSPInit couldn't get init args\n"); return(-1); } // call the following function so that CRAM-MD5 will show up // as one of the supported saslmechanisms when rootdse is queried. slapi_register_supported_saslmechanism(CRAMMD5_MECH); return 0; }; //Use internal search function to search backend to get password for the specified dn int getSecret(char *dn, char **secret) { Slapi_PBlock *pb; int rc, numEntries; Slapi_Entry **entries; Slapi_Attr *a; struct berval **attr_vals; if((pb = slapi_search_internal(dn, LDAP_SCOPE_BASE,FILTER,NULL, NULL, 0)) == NULL) { printf("Search Internal failed for dn = %s\n",dn); return(LDAP_OPERATIONS_ERROR); } // get the return code from the above internal search function slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); if(rc == LDAP_SUCCESS) { // find out how many entries the above internal search function returned slapi_pblock_get(pb,SLAPI_NENTRIES,&numEntries); if(numEntries == 0) rc=LDAP_NO_SUCH_OBJECT; else slapi_pblock_get(pb,SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); //the above internal search function should return 1 entry. //from the entry, get the value of the attribute "userpassword" if(slapi_entry_attr_find(entries[0],PWATTR,&a) != NULL) rc=LDAP_INAPPROPRIATE_AUTH; else slapi_attr_get_values(a,&attr_vals); //make a copy of the password and return if(rc == LDAP_SUCCESS) { if((*secret=slapi_ch_strdup(attr_vals[0]->bv_val)) == NULL) rc=LDAP_OPERATIONS_ERROR; } } slapi_free_search_results_internal(pb); slapi_pblock_destroy(pb); return(rc); } //actual pre-operation code for bind operations. This function handles CRAM-MD5 //bind requests. int DSPBind(Slapi_PBlock *pb) { char *mechanism; char *chal=NULL; char *dn; char *aString=NULL; char *secret; char *connDn; int rc; struct berval *credentials; struct berval returnCreds; //get the input parameters from the pblock if (slapi_pblock_get( pb, SLAPI_BIND_TARGET, &dn) != 0 || slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &credentials ) != 0 || slapi_pblock_get( pb, SLAPI_BIND_SASLMECHANISM,&mechanism ) != 0 ) { printf( "Could not get parameters for bind operation\n" ); return(NEXTPLUGIN); } //this function supports CRAM-MD5 mechanism. If the mechanism requested is //not CRAM-MD5, execute the next pre-bind plug-in or the default database // bind operation if ((mechanism == NULL) || (stricmp(mechanism, CRAMMD5_MECH) != 0 )) { return(NEXTPLUGIN); } //CRAM-MD5 related code here // calling getSecret to get the user's password if((rc=getSecret(dn,&secret)) == LDAP_SUCCESS) { //CRAM-MD5 related code here // make a copy of the DN and the authentication method and // set them to the pblock. The server will use them for the connection if((connDn=slapi_ch_strdup(dn)) == NULL) { printf("Could not duplicate connection DN"); rc=LDAP_NO_MEMORY; } else if((aString=slapi_ch_malloc(strlen(SLAPD_AUTH_SASL) + strlen(CRAMMD5_MECH) + 2)) == NULL) { printf("Could not duplicate connection authString"); rc=LDAP_NO_MEMORY; } else { sprintf(aString,"%s%s",SLAPD_AUTH_SASL,CRAMMD5_MECH); if ((slapi_pblock_set( pb, SLAPI_CONN_DN, (void *)connDn) != NULL) || (slapi_pblock_set( pb, SLAPI_CONN_AUTHTYPE,(void *)aString) != NULL )) { printf("Could not set CONN_DN, CONN_AUTHTYPE"); rc=LDAP_OPERATIONS_ERROR; } } } //CRAM-MD5 related code here slapi_send_ldap_result(pb,rc,NULL,NULL,NULL,NULL); if (connDn != NULL) slapi_ch_free(connDn); if (aString != NULL) slapi_ch_free(aString); return(STOP_PLUGIN_SEARCH); }
Although the following APIs are still supported, their use is deprecated. Use of the newer replacement APIs is strongly encouraged.
This information was developed for products and services offered in the U.S.A. IBM might not offer the products, services, or features discussed in this document in other countries. Consult your local IBM representative for information on the products and services currently available in your area. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to:
IBM Director of LicensingFor license inquiries regarding double-byte (DBCS) information, contact the IBM Intellectual Property Department in your country or send inquiries, in writing, to:
IBM World Trade Asia Corporation LicensingThe following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the information. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this information at any time without notice.
Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM product and use of those Web sites is at your own risk.
IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation to you.
Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact:
IBM CorporationSuch information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee.
The licensed program described in this document and all licensed material available for it are provided by IBM under terms of the IBM Customer Agreement, IBM International Program License Agreement, or any equivalent agreement between us.
Any performance data contained herein was determined in a controlled environment. Therefore, the results obtained in other operating environments may vary significantly. Some measurements may have been made on development-level systems and there is no guarantee that these measurements will be the same on generally available systems. Furthermore, some measurement may have been estimated through extrapolation. Actual results may vary. Users of this document should verify the applicable data for their specific environment.
Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other publicly available sources. IBM has not tested those products and cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of those products.
All statements regarding IBM's future direction or intent are subject to change or withdrawal without notice, and represent goals and objectives only.
All IBM prices shown are IBM's suggested retail prices, are current and are subject to change without notice. Dealer prices may vary.
The following terms are trademarks of International Business Machines
Corporation in the United States, or other countries, or both:
AIX
Database 2
DB2
IBM
VisualAge
Windows and Windows NT are registered trademarks of Microsoft(R) Corporation.
UNIX is a registered trademark of The Open Group in the United States and other countries.
Other company, product, and service names may be trademarks or service marks of others.