Generate Unique CN In Bean Shell Using LDAP Search

While working on Joiner workflow I had a requirement to generate unique Common Name, Email address and Display Name. I wrote a bean shell code to search the user in IIQ repository by using filter string. My code was working well and I did not face any issue in development box. When I moved my code to the UAT environment, the joiner workflow failed multiple times, and then when I did the investigation I found that the CN generated was not unique in the Employee/Contractor OU because there were orphan/old/disabled accounts already present in AD with the same CN.

Logically this issue should not have occurred because all AD accounts will be aggregated in IIQ, but for the 1% chance where the orphan/old/disabled accounts are present in production AD, this issue can come up while executing joiners.

To make this as error free in all aspects, I recommend that the user should be searched directly in the AD, and if found, the unique logic should be implemented.

The below code will help you to search the user directly from the Active Directory and then generate the unique attribute values directly from the Active Directory:

By changing the searchString in below code any value of the AD attribute can be searched.

* Input: firstname and lastname of the user
* Rule for unique CN :
CN=(LastName, FirstName) if exist then CN=(LastName, FirstName1) if exist then CN=(LastName, FirstName2) and so on
* Return the Active Directory unique CN in a map for the user.
public Map generateUniqueADAttribute(String firstname,String lastname)

Application application = (Application) context.getObjectByName(Application.class, <>); // change the name of the AD application in below line

List dsList = (List)application.getAttributeValue(“domainSettings”);
Map dsMap = (Map)dsList.get(0);
String user = dsMap.get(“user”);
List servers = dsMap.get(“servers”);
String host = servers.get(0);
String port = dsMap.get(“port”);
String encryptedPassword = dsMap.get(“password”);
String decryptedPassword = context.decrypt(encryptedPassword);
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, “ldap://” + host + “:” + port);
env.put(Context.SECURITY_AUTHENTICATION, “simple”);
env.put(Context.SECURITY_PRINCIPAL, user);
env.put(Context.SECURITY_CREDENTIALS, decryptedPassword);
env.put(Context.REFERRAL, “follow”);
//env.put(Context.SECURITY_PROTOCOL, “ssl”);
// Initialize variables.
String CNN = “false”;
int count=1;
Map uniqueAttributes = new HashMap();
// We build the actual ldap search context and pass in the environment variables.
InitialDirContext ctx1 = new InitialDirContext(env);
SearchControls searchControls = new SearchControls();
String[] array = new String[1];
array[0] = “name”;

String searchBase= “OU=Accounts,DC=TestUsers,DC=TestDomain,DC=com”; // Change your Base DN as per need
String ristrictedChars = “['' '~`@#$%^*?]”; // Append the list of restricted char if needed
firstname = firstname.replaceAll(ristrictedChars,””);
lastname = lastname.replaceAll(ristrictedChars,””);

String searchString = “(|(cn=” + lastname +”,”+ firstname + “)(cn=” + lastname+”, “+firstname + “))”;
//logger.debug(“CNExists: search string set to: ” + searchString);
//return searchString;
NamingEnumeration list = ctx1.search(searchBase,searchString, searchControls);
String lname = lastname;
boolean notUnique = true;
lname = lastname+count;
String searchString = “(|(cn=” + lname+ “,” + firstname + “)(cn=” + lname+”, “+firstname + “))”;
//logger.debug(“CNExists: search string set to: ” + searchString);
NamingEnumeration list = ctx1.search(searchBase,searchString, searchControls);
uniqueAttributes.put(“CN”,(“CN=”+lname+”, “+ firstname));
return uniqueAttributes;
uniqueAttributes.put(“CN”,(“CN=”+lastname+”, “+ firstname));
return uniqueAttribute;

Questions, comments or concerns? Feel free to reach out to us below, or email us at IDMWORKS to learn more about how you can protect your organization and customers.

Leave a Reply

Your email address will not be published. Required fields are marked *