Referential integrity plug-in

Building from source files
All the necessary files to build the plug-in library files on the Windows NT systems are available in the <SDS_INSTALL_ROOT>\examples\plug-in directory, and for AIX®, Linux, and Solaris systems are available in the <SDS_INSTALL_ROOT>/examples/plug-in directory. The example source code files for the referential integrity plug-in are also available in the directory. To build the source files on a particular operating system, run the following commands:
  • For Windows NT systems: nmake –f makefile.plugin
  • For AIX, Solaris, and Linux systems: make –f makefile.plugin
    Note: On Solaris, you might need the -KPIC compiler flag to create position independent code.
Note: The makefile might require changes that are based on the differences in individual machine configurations. An example makefile to build the library files on a Linux system:
##################################################################### 
##  Linux Makefile
#####################################################################
#DEFINES=-D LINUX -D LDAP_STATIC_LINK -DLOCAL_LDAP_CACHE

IDS_LDAP_HOME=/opt/ibm/ldap/V8.0
IDS_LDAP_INCLUDES= -I$(IDS_LDAP_HOME)/include

#********************************************
# ------ Options for building 32-bit targets 
#********************************************

IDS_LDAP_LIBS = $(IDS_LDAP_HOME)/lib
OS_LIBS = /usr/lib COMPILER_TARGET_FLAG =

#********************************************
# ------ Options for building 64-bit targets
#********************************************
#IDS_LDAP_LIBS = $(IDS_LDAP_HOME)/lib64
#OS_LIBS = /usr/lib64
#COMPILER_TARGET_FLAG = -m64

DEBUG=-g
OPTIMIZED=-O2
OPT=${DEBUG}

CC_ARGS=$(DEFINES) $(IDS_LDAP_INCLUDES) $(CFLAGS)

CC=/usr/bin/gcc -g -DSTRINGS $(COMPILER_TARGET_FLAG)

LD=/usr/bin/gcc -g -shared $(COMPILER_TARGET_FLAG)

#To work with 64-bit compiler use the -fPIC flag
#CC=/usr/bin/gcc -g -DSTRINGS $(COMPILER_TARGET_FLAG) -fPIC
#LD=/usr/bin/gcc -g -shared $(COMPILER_TARGET_FLAG)

API_LIB_DIR=./lib
API_OBJ_DIR=./obj

API_I_POSTFILE=libpostrefint.so
API_I_POST=${API_LIB_DIR}/${API_I_POSTFILE}
API_I_PREFILE=libprerefint.so
API_I_PRE=${API_LIB_DIR}/${API_I_PREFILE}

LDAPLIB=-lslapi -lldap -lpthread -L$(OS_LIBS)-L$(IDS_LDAP_LIBS)

TAR_FILE=${API_OBJ_DIR}/libdelref.tar
TAR_SOURCE=$(API_E)

API_OBJS_POST= \
		${API_OBJ_DIR}/DeleteReference.o\
		${API_OBJ_DIR}/ModRdnReference.o \
		${API_OBJ_DIR}/ReferenceUtils.o \
		${API_OBJ_DIR}/PostReferenceUtils.o

API_OBJS_PRE= \
		${API_OBJ_DIR}/AddReference.o \
		${API_OBJ_DIR}/ReferenceUtils.o \
		${API_OBJ_DIR}/ModReference.o \
		${API_OBJ_DIR}/PreReferenceUtils.o

all: debug

debug:
		@OPT="${DEBUG}" make -f makefile.plugin -e build

optimized:
		@OPT="${OPTIMIZED}" make -e build

build: libpost libpre

${API_LIB_DIR}:
		mkdir -p ${API_LIB_DIR}

${API_OBJ_DIR}:
		mkdir -p ${API_OBJ_DIR}

libpost: ${API_LIB_DIR} ${API_OBJ_DIR} $(API_I_POST)

libpre: ${API_LIB_DIR} ${API_OBJ_DIR} $(API_I_PRE)

$(API_I_POST): $(API_OBJS_POST)
		rm -f $(API_I_POST)
		$(LD) -o ${API_I_POST} $(API_OBJS_POST) $(LDAPLIB)

$(API_I_PRE): $(API_OBJS_PRE)
		rm -f $(API_I_PRE)
		$(LD) -o ${API_I_PRE}$(API_OBJS_PRE) $(LDAPLIB)

$(TAR_FILE).tar.Z: ${TAR_SOURCE}
		rm -f ${TAR_FILE}.*
		tar cvf $(TAR_FILE).tar $(TAR_SOURCE)
		compress $(TAR_FILE).tar

${API_OBJ_DIR}/DeleteReference.o: DeleteReference.c
		${CC} -c ${CC_ARGS} DeleteReference.c -o $@

${API_OBJ_DIR}/ModRdnReference.o: ModRdnReference.c
		${CC} -c ${CC_ARGS} ModRdnReference.c -o $@

${API_OBJ_DIR}/ReferenceUtils.o:ReferenceUtils.c
		${CC} -c ${CC_ARGS} ReferenceUtils.c -o $@

${API_OBJ_DIR}/PostReferenceUtils.o:PostReferenceUtils.c
		${CC} -c ${CC_ARGS} PostReferenceUtils.c -o $@

${API_OBJ_DIR}/AddReference.o: AddReference.c
		${CC} -c ${CC_ARGS} AddReference.c -o $@

${API_OBJ_DIR}/ModReference.o: ModReference.c
		${CC} -c ${CC_ARGS} ModReference.c -o $@

${API_OBJ_DIR}/PreReferenceUtils.o:PreReferenceUtils.c
		${CC} -c ${CC_ARGS} PreReferenceUtils.c -o $@

clean:
		rm -rf ${API_OBJ_DIR} ${API_LIB_DIR}
Output directory of the library files
The referential integrity plug-in library files that are generated as a result of build are stored in the <SDS_INSTALL_ROOT>/examples/plug-in/lib directory on AIX, Linux, and Solaris systems and in the <SDS_INSTALL_ROOT>\examples\plug-in\lib directory on the Windows NT system. On Windows NT system, the library files are libprerefint.dll and libpostrefint.dll. On AIX, Linux, and Solaris systems, the library files are libprerefint.so and libpostrefint.so.
Input and log files of referential integrity plug-in
Input file
The referential integrity plug-in is initialized by reading referential integrity constraint information from the file that is specified by <input-file-path>, which is a requirement for using the plug-in. Here in the examples, the refIntegInput file is used. You can use any input file that has constraint in the following format:
at=<DN-style-attribute><\n> dn=<search-base-DN><\n>
The input file can contain multiple DN style attribute, and search base DN entry in any order. The plug-in treats each entry as it is and therefore white space before and after the specification is not allowed and might lead to undesirable results. On a Linux system an example input file, refIntegInput, is provided in the <SDS_INSTALL_ROOT>/examples/plug-in/input directory, and an example ldif file, add.ldif, in the <SDS_INSTALL_ROOT>/examples/plug-in/ldif directory. A copy of example input file, refIntegInput, is used that is stored in the <instance_home>/ idsslapd-myinst1/etc directory. In the example input file, the constraints is checked against the following format:
at=seeAlso dn=o=ibm,c=us
Here, the attribute seeAlso is checked for referential integrity constraints for entries that fall under the DN o=ibm, c=us.
Log file
The plug-in performs referential integrity checks for the LDAP operations that it is designed for and logs the report to the ibmslapd.log file. If the debug version of the plug-in initialization function is used, the log status becomes more verbose and can be used to trace execution.
Registering the referential integrity plug-in
To use referential integrity plug-in libraries, they must be registered with Directory Server. To register the plug-in, first you must add an entry for the plug-in in the configuration file, ibmslapd.conf. It is done by adding ibm-slapdPlugin specifications to the ibmslapd.conf file. You can add an entry to the configuration file by using the ldapmodify command, provided you must have the required permissions. The plug-in initialization functions that are used in the <init-function> specification are preReferenceInit and postReferenceInit. For debugging purposes, the preReferenceInitDebug, and postReferenceInitDebug can be substituted in the <init-function> specification to get more verbose logging. To add entries, issue the idsldapmodify command of the following format:
# idsldapmodify -p 3389 -D cn=root -w root -f <filename>
where, <filename> contains:
dn: cn=Directory, cn=RDBM Backends, cn=IBM Directory, cn=Schemas, cn=Configuration
changetype: modify
add: ibm-slapdPlugin
ibm-slapdPlugin: preoperation /opt/ibm/ldap/V8.0/examples/plug-in/lib/libprerefint.so
preReferenceInit /home/myinst1/idsslapd-myinst1/etc/refIntegInput
-
add: ibm-slapdPlugin
ibm-slapdPlugin: postoperation /opt/ibm/ldap/V8.0/examples/plug-in/lib/libpostrefint.so
postReferenceInit /home/myinst1/idsslapd-myinst1/etc/refIntegInput
To verify that the entries are added under the specified entry DN, issue the idsldapsearch command of the following format:
# idsldapsearch -D cn=root -w root -p 3389 -s sub -b \
"cn=Directory, cn=RDBM Backends, cn=IBM Directory, cn=Schemas, cn=Configuration"\
-L objectclass=*

dn: cn=Directory, cn=RDBM Backends, cn=IBM Directory, cn=Schemas, cn=Configuration
cn: Directory
ibm-slapdDbAlias: ldapdb2b
ibm-slapdDbConnections: 15
ibm-slapdDbInstance: myinst1
ibm-slapdDbLocation: /home/myinst1
ibm-slapdDbName: myinst1
ibm-slapdDbUserID: myinst1
ibm-slapdDbUserPW: {AES256}hCUF8fpN7J0gVcFaZau8jw==
ibm-slapdEnableRemotePWPExOps: TRUE
ibm-slapdGroupMembersCacheBypassLimit: 25000
ibm-slapdGroupMembersCacheSize: 25
ibm-slapdLanguageTagsEnabled: FALSE
ibm-slapdNumRetry: 5
ibm-slapdPagedResAllowNonAdmin: TRUE
ibm-slapdPagedResLmt: 3
ibm-slapdPlugin: database    libback-rdbm.so rdbm_backend_init
ibm-slapdPlugin: replication libldaprepl.so  replInit
ibm-slapdPlugin: preoperation /opt/ibm/ldap/V8.0/examples/plug-in/lib/libprerefint.so
preReferenceInit /home/myinst1/idsslapd-myinst1/etc/refIntegInput
ibm-slapdPlugin: postoperation /opt/ibm/ldap/V8.0/examples/plug-in/lib/libpostrefint.so
postReferenceInit /home/myinst1/idsslapd-myinst1/etc/refIntegInput
ibm-slapdReadOnly: FALSE
ibm-slapdSortKeyLimit: 3
ibm-slapdSortSrchAllowNonAdmin: TRUE
ibm-slapdSuffix: cn=localhost
ibm-slapdSuffix: cn=ibmpolicies
ibm-slapdSuffix: cn=Deleted Objects
ibm-slapdSuffix: o=ibm, c=us
ibm-slapdTombstoneEnabled: FALSE
ibm-slapdTombstoneLifetime: 168
objectclass: top
objectclass: ibm-slapdConfigEntry
objectclass: ibm-slapdRdbmBackend
After you add the referential integrity plug-in entries in the configuration file, you must restart Directory Server instance for the registration and loading of the library files to take effect. An example excerpt of the messages that the Directory Server generates at starting the instance:
# ibmslapd -I myinst1 -n –c

GLPSRV041I Server starting.
GLPCTL113I Largest core file size creation limit for the process
						(in bytes): '0'(Soft limit) and '-1'(Hard limit).
GLPCTL119I Maximum Data Segment(Kbytes) soft ulimit for the process
						is -1 and the prescribed minimum is 262144.
GLPCTL119I Maximum File Size(512 bytes block) soft ulimit for the process
						is -1 and the prescribed minimum is 2097152.
GLPCTL122I Maximum Open Files soft ulimit for the process
						is 1024 and the prescribed minimum is 500.
GLPCTL119I Maximum Stack Size(Kbytes) soft ulimit for the process is -1
						and the prescribed minimum is 10240.
GLPCTL119I Maximum Virtual Memory(Kbytes) soft ulimit for the process is -1
and the prescribed minimum is 1048576.
GLPCOM024I The extended Operation plug-in is successfully loaded from libevent.so.
GLPCOM024I The extended Operation plug-in is successfully loaded from libtranext.so.
GLPCOM024I The extended Operation plug-in is successfully loaded from libldaprepl.so.
GLPSRV155I The DIGEST-MD5 SASL Bind mechanism is enabled in the configuration file.
...
GLPCOM024I The extended Operation plug-in is successfully loaded from libpsearch.so.
GLPCOM022I The database plug-in is successfully loaded from libback-rdbm.so.
GLPCOM010I Replication plug-in is successfully loaded from libldaprepl.so.
GLPCOM021I The preoperation plug-in is successfully loaded from
/opt/ibm/ldap/V8.0/examples/plug-in/lib/libprerefint.so.
GLPCOM023I The postoperation plug-in is successfully loaded from
/opt/ibm/ldap/V8.0/examples/plug-in/lib/libpostrefint.so.
GLPSRV189I Virtual list view support is enabled.
GLPCOM021I The preoperation plug-in is successfully loaded from libpta.so.
...
GLPSRV180I Pass-through authentication is disabled.
GLPCOM003I Non-SSL port initialized to 3389.
GLPRPL137I Restricted Access to the replication topology is set to false.
GLPSRV009I 8.0 server started.
GLPRPL136I Replication conflict resolution mode is set to true.
GLPSRV048I Started 15 worker threads to handle client requests.
Examples
Examples to verify the working of referential integrity plug-in
After you create and configure a Directory Server instance, add data to Directory Server instance from the example ldif file, add.ldif, available in the <SDS_INSTALL_ROOT>/examples/plug-in/ldif directory on a Linux system. An example of the idsldapadd command with its output:
#idsldapadd -p 3389 -D cn=root -w root -f add.ldif
Operation 0 adding new entry o=ibm, c=us
Operation 1 adding new entry cn=sullyBoss,o=ibm,c=us
Operation 2 adding new entry cn=sullyEmp,o=ibm,c=us
Operation 3 adding new entry cn=sully1,o=IBM,c=US
To search for the newly added entries, run the idsldapsearch command. An example of the idsldapsearch command with its output:
#idsldapsearch -p 3389 -s sub -b "o=ibm, c=us" objectclass=*
o=ibm,c=us
objectclass=organization
objectclass=top
o=ibm

cn=sullyBoss,o=ibm,c=us
objectclass=inetOrgPerson
objectclass=organizationalPerson
objectclass=person objectclass=top
objectclass=ePerson
sn=sullyEmpSN
cn=sullyEmp
cn=sullyBoss

cn=sullyEmp,o=ibm,c=us
objectclass=inetOrgPerson
objectclass=organizationalPerson
objectclass=person objectclass=top
objectclass=ePerson
sn=sullyEmpSN
cn=sullyEmp
seealso=cn=sullyBoss,o=ibm,c=us

cn=sully1,o=IBM,c=US
objectclass=person
objectclass=organizationalPerson
objectclass=top
cn=sully1
sn=sullivan
telephonenumber=1-812-855-8541
internationalisdnnumber=755-8541
title=Mechanical Ana. Thermal
seealso=cn=sullyBoss,o=ibm,c=us
postalcode=4502
Checking the plug-in for pre-operation referential integrity
To check for pre-operation referential integrity when, you add wrong data. An example of the idsldapadd command with its output:
#idsldapadd -p 3389 -D cn=root -w root
cn=sully2,o=ibm,c=us
objectclass=person
objectclass=organizationalPerson
objectclass=top
cn=sully2
sn=bob
seealso=cn=sully1, o=sample
Operation 0 adding new entry cn=sully2,o=ibm,c=us
ldap_add: Unknown error
ldap_add: additional info: plug-in function failed
To check for pre-operation referential integrity when you modify an existing entry. An example of the idsldapmodify command with its output:
#idsldapmodify -p 3389 -D cn=root -w root
dn: cn=sully1,o=IBM,c=US
changetype: modify
replace: seealso
seealso:
Operation 0 modifying entry cn=sully1,o=IBM,c=US
ldap_modify: Unknown error
ldap_modify: additional info: plug-in function failed
Checking the plug-in for post-operation referential integrity
To check for post-operation referential integrity by modifying the RDN. An example of the idsldapmodrdn command with its output:
# idsldapmodrdn -p 3389 -D cn=root -w root cn=sullyBoss,o=ibm,\
c=us cn=sullyManager
copying cn=sullyBoss,o=ibm,c=us to cn=sullyManager
Verifying the data in the Directory Server:
# idsldapsearch -p 3389 -s sub -b "o=ibm, c=us" objectclass=*
o=ibm,c=us
objectclass=organization
objectclass=top
o=ibm

cn=sullyManager,o=ibm,c=us
objectclass=inetOrgPerson
objectclass=organizationalPerson
objectclass=person
objectclass=top
objectclass=ePerson
sn=sullyEmpSN
cn=sullyEmp
cn=sullyBoss
cn=sullyManager

cn=sullyEmp,o=ibm,c=us
objectclass=inetOrgPerson
objectclass=organizationalPerson
objectclass=person
objectclass=top
objectclass=ePerson
sn=sullyEmpSN
cn=sullyEmp
seeAlso=cn=sullyManager, o=ibm,c=us

cn=sully1,o=IBM,c=US
objectclass=person
objectclass=organizationalPerson
objectclass=top
cn=sully1
sn=sullivan
telephonenumber=1-812-855-8541
internationalisdnnumber=755-8541
title=Mechanical Ana. Thermal
postalcode=4502
seeAlso=cn=sullyManager,o=ibm,c=us
Notice the changes that are made to the values of the seeAlso attribute in other entries. To check for post-operation referential integrity by deleting an entry that is referred to by the seeAlso attribute. An example of the idsldapdelete command with its output:
#idsldapdelete -p 3389 -D cn=root -w root cn=sullyManager,\
o=ibm,c=us
Deleting entry cn=sullyManager,o=ibm,c=us
Verifying the data in the Directory Server:
# idsldapsearch -p 3389 -s sub -b "o=ibm, c=us" objectclass=*
o=ibm,c=us
objectclass=organization
objectclass=top
o=ibm

cn=sullyEmp,o=ibm,c=us
objectclass=inetOrgPerson
objectclass=organizationalPerson
objectclass=person
objectclass=top
objectclass=ePerson
sn=sullyEmpSN
cn=sullyEmp

cn=sully1,o=IBM,c=US
objectclass=person
objectclass=organizationalPerson
objectclass=top
cn=sully1
sn=sullivan
telephonenumber=1-812-855-8541
internationalisdnnumber=755-8541
title=Mechanical Ana. Thermal
postalcode=4502
Notice that the references to the value cn=sullyManager,o=ibm,c=us, in the seeAlso attribute is removed along with the deletion of the entry cn=sullyManager,o=ibm,c=us.