This is a short one because I came across it the other day and I almost freaked out. I ssh'd into an AWS Alpine Linux instance using MobaXterm on Windows, and I edited a file with vi. I then saved it and re-opened it, and any lines that I added or modified were just messed up. I didn't get to the root of the issue, but I found that using the nano editor did NOT have this same problem. Strange, but wanted to document it in the hope that it may help someone else.
Friday, September 5, 2025
Sunday, June 8, 2025
IBM Identity Manger recons hanging and apparent memory leak in JVM
Background
Two-node WebSphere cell, with two clusters - ITIM_Application and ITIM_Messaging, so two application servers per node (timapp1 and timmsg1, timapp2 and timmsg2). It's a fairly large system (6ooo services and 200000 person objects), and it has been running for almost a decade. It started as ISIM 6.0 and is now at version 10.0. The problem we initially saw was that scheduled recons would just go into a Pending state, and others wouldn't be started at all. The log files on both servers looked very similar, and nothing really stuck out, other than errors about hung threads. After more digging, I saw that timapp2, on the secondary server, would start and almost immediately start growing in heap memory size (I could see the memory usage in 'top' and also with 'jconsole'). Also, that application server would have very high CPU usage (200-500% on a 6-cpu VM). The workaournd was to restart all of the VMs once things got into a hang condition.
Solution
Wednesday, June 4, 2025
COMPLETELY cryptographically synchronizing two IBM Directory Servers
Background
This documentation exists to cryptographically sync two IBM Directory Server instances. That mostly works for the main LDAP directory data - essentially anything under the visible suffixes. HOWEVER, if you need to also cryptographically synchronize the data in the invisible "cn=Configuration" suffix, that's what this post is for.
The story of how I came across this issue is a normal one for a consultant. I was hired to help a customer work on an decade-old ISIM implementation that had been customized and configured by several different implementers. The customer needed to sunset their old AIX LDAP server and move the functionality to a new Red Hat Linux server. The existing server had multiple users defined with names like "cn=acmereadonly" or "cn=xyzservice", where there are multiple (but unknown and undocumented) integrations using these credentials, but no one actually knew the passwords. These users were all visible in ibmslapd.conf, with their AESS256-encrypted passwords, so it was extremely important to copy these users and their encrypted passwords to the new server so that existing integrations would continue to work.
There are actually TWO .KSF files
What are the steps?
To cryptographically synchronize two server instances, assuming that you created the first server instance do the following steps.
- Create the second server instance, but do not start the server instance. do not run the idsbulkload command, or run the idsldif2db command on the second server instance.
- Copy the ibmslapddir.ksf file (the ldap key stash file) AND the ibmslapdcfg.ksf file from the first server instance to the second server instance. The file is in the idsslapd-instance_name\etc directory on Windows systems, or in the idsslapd-instance_name/etc directory on AIX®, Linux, and Solaris systems. The instance_name is the name of the server instance.
- Replace the ibmslapddir.ksf file AND the ibmslapdcfg.ksf file of the target server instance with the ibmslapddir.ksf file AND the ibmslapdcfg.ksf file of the source server instance.
- Edit the ibmslapd.conf file on the second server to set the value of ibm-slapdCryptoSync: under dn: cn=Configuration to be the exact same as the value on the first server.
- If you have any users with passwords defined in ibmslapd.conf on the first server, you can copy those entries directly into the same place in the ibmslapd.conf file on the second server. They will be correctly loaded when the server starts.
- Run the idsbulkload command from the second server instance.
- Start the second server instance.
- If you copied any users in step 5 above, try to log in with them on the second server instance, and you should be successful.
Tuesday, April 1, 2025
ldapsearch error: "scope is required for a null based search"
This command:
- While the command is running, ANY user on the system can see the entire command line with the 'ps -ef' command.
- If you're using a shared account (like a service account), any other people sharing that account can see all previous commands with the 'history' command.
Monday, March 31, 2025
Customizing IDI Linux Adapter - javax.naming.NameNotFoundException: isDollarAllowedInPwd
I was just looking at customizing the IDI Linux Adapter. I unzipped PosixLinuxProfile.jar and imported posixAdd.xml into my project in the IDI CE. When I clicked on the posixConn connector in the AssemblyLine, I got the error:
javax.naming.NameNotFoundException: isDollarAllowedInPwd
I unzipped the PosixConnector.jar file and found the idi.inf file (that's not documented anywhere - this function is now performed with a tdi.xml file, but this older adapter still has this old file). In there, everything mainly looks good EXCEPT I noticed in the parameter section that isDollarAllowedInPwd didn't have a space before the following open curly brace, while every other parameter did. So I changed it from:
isDollarAllowedInPwd{
to
isDollarAllowedInPwd {
Then saved the idi.inf file, re-created the jar file, copied PosixConnector.jar to jars/connectors, and restarted IDI. Once I did that, I no longer got the error. I'm certain this doesn't affect the operation of the adapter, since this is simply for the Connector form in the CE, but I just didn't like seeing the error.
Additionally, another error you might see is a complaint about "_Default" and " Default". These are two properties files that are defined in all of the Linux Adapter assemblylines. The way to eliminate these errors (again, which only affect the CE; they don't affect the operation of the adapter) is to create two new tdiproperties files, one named "_Default" and one named " Default" (that is <space>Default). The GUI will let you create that weird name - just put a space in front of "Default". Then the CE won't complain about these two properties files any more.
There you go. Just wanted to share in case someone is encountering the problem.
Sunday, February 16, 2025
Using IDI to convert ISIM audit XML data into HTML
Related to my last post, I made a video covering the IDI assemblyline I wrote to convert ISIM audit XML data to HTML. Here's the video:
And here's the link to the Github repo with the project containing the assemblyline: https://github.com/franktate/IBM-Directory-Integrator
XSLT for ISIM Audit XML Data
I made a video on using XSLT to convert ISIM's XML reconciliation audit data into more readable XML. Specifically, it takes XML that looks like this:
And turn it into HTML that renders like this:
The video is here: https://youtu.be/7yEkGZGN1Lg and the files used are available in my github repo here: https://github.com/franktate/ISIM-Audit-XML-XSLT
Tuesday, January 21, 2025
Decrypting the idisrv.sth file from IBM Directory Integrator
Background
The idisrv.sth file that's included in IBM Directory Integrator isn't a normal stash file. A normal stash file can be decrypted with a simple Perl script (see my previous post). However, this one is different. Happily, IBM does include a method to read this file, though it's hidden in a Jar file and requires some Java know-how.
Java Code
Monday, January 20, 2025
Decrypting properties in IBM Directory Integrator
If you look at the usage from the IDI encryption utility (cryptoutils.sh), you'll see this:
CTGDKD446I Usage:
-input <input file>
-output <output file>
-mode <encrypt|decrypt|encrypt_config|decrypt_config>
-keystore <keystore file>
-storepass <keystore password>
-alias <encryption key alias>
[ -keypass <key password> ]
[ -transformation <encryption transformation> ]
[ -storetype <keystore type> ]
[ -cryptoproviderclass <security provider used for encryption> ]
Unfortunately, none of those "-mode" options will let you decrypt values in any of the *.properties files (e.g. global.properties, solution.propterties, etc.) So how do you do it?
To get the answer, you need to find the online documentation here to find that there are two additional options that aren't listed above. They are:
decrypt_props
Once you know that, you're over the largest obstacle. But now you have several additional flags with values to provide, and the documentation doesn't give you an example of doing exactly this. So here's the example:
In the above case, I wanted to decrypt the encrypted values in my solution.properties file. My solution directory is /opt/IBM/TDI/ftsoldir. Notice also that you MUST provide the certificate alias that points to the server certificate in the solution directory. By DEFAULT (meaning: all of this can be changed), the alias of that certificate is "server", it is stored in the $SOLDIR/testserver.jks keystore, and the password of the keystore is "server". The name of the keystore and the alias are specified in these two properties in solution.properties:
com.ibm.di.server.encryption.key.alias = server
If, however, you forget the password, that's not a good thing. Normally you can decrypt an IBM stash file with a perl script like this:
#!/usr/bin/perl
use strict;
die "Usage: $0 <stash file>n" if $#ARGV != 0;
my $file=$ARGV[0];
open(F,$file) || die "Can't open $file: $!";
my $stash;
read F,$stash,1024;
my @unstash=map { $_^0xf5 } unpack("C*",$stash);
foreach my $c (@unstash) {
last if $c eq 0;
printf "%c",$c;
}
printf " ";
However, that doesn't work on the IDI stash file (idisrv.sth) because this isn't a GSKit stash file. From the docs:
The stash file contains the Server keystore password values encrypted with AES128 with a fixed key.
Check back later to find out later how to read this stash file - I think I've figured out how to decrypt it.
I did figure it out, and here's the video.
And NOTE: This only matters if you want to CHANGE the password of the keystore and keep the keystore. If all you need to do is add a server certificate to the keystore for a new web connection, you can simply use the "Get Certificate" button in the HTTP Server Connector to get the server's certificate and add it to the keystore.
Friday, January 10, 2025
IBM Identity Manger: Adding a new attribute
Background
Details
ldapmodify: invalid format (line 5 of entry: cn=schema)
After a bit of pain, I figured out that the whitespace in the lines are the problem. You need to either concatenate the continued lines together OR have some white space at the front of the continued lines. Additionally, there should be a space in betwee "oid" and "DBNAME". So if you change the file to the following, you will no longer get the error:
dn: cn=schema changetype: modify add: attributetypes attributetypes: ( myAttribute-oid NAME ( 'myAttribute' ) DESC 'An attribute I defined for my LDAP application' EQUALITY 2.5.13.2 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 {200} USAGE userApplications ) - add: ibmattributetypes ibmattributetypes: ( myAttribute-oid DBNAME ( 'myAttrTable' 'myAttrColumn' ) ACCESS-CLASS normal LENGTH 200 )
What about updating the objectclass?
That's what I was wondering! Simply adding an attribute doesn't really help you much until you add it as a MUST or a MAY attribute to an objectclass. IBM has an almost complete guide to doing that here, But it is incomplete. For one thing, the format of the data is wrong again. The long attribute values should all be on a single line, like this:
dn: cn=schema changetype: modify replace: objectclasses objectclasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC 'Defines entries representing people in an organizations enterprise network.' SUP 'organizationalPerson' Structural MAY ( audio $ businessCategory $ carLicense $ departmentNumber $ employeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledURI $ mail $ manager $ mobile $ pager $ photo $ preferredLanguage $ roomNumber $ secretary $ uid $ userCertificate $ userSMIMECertificate $ x500UniqueIdentifier $ mytest ) )
Additionally, where did that value for "objectclasses" come from?? Well, that came from this command:
ldapsearch -b cn=schema -s base objectclass=* objectclasses | grep \'inetOrgPerson\'
Running that, you will get a result similar to:
objectclasses=( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC 'Defines entries representing people in an organizations enterprise network.' SUP organizationalPerson STRUCTURAL MAY ( audio $ businessCategory $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $ preferredLanguage $ roomNumber $ secretary $ uid $ userCertificate $ userPKCS12 $ userSMIMECertificate $ x500UniqueIdentifier ) )
Modify that to include your new attribute, then put that into the LDIF file. Then run idsldapmodify to import that LDIF file into your server. After that, you'll have your new attribute added to the inetOrgPerson objectclass.