IDM 4 Generate Password with Excluded Characters

If you are familiar with NetIQ Identity Manager (formerly Novell Identity Manager) then you are probably familiar with the ability to define password policies in eDirectory that can be applied to users, containers, groups, etc. that determine everything from how many characters a password must have to how long the password is valid and what characters or values are not allowed to be included in a password.  What you may or may not be familiar with is the ability to generate random passwords from a NetIQ Identity Manager driver based on a password policy defined in eDirectory.  In fact, this is actually accomplished very easily using the Generate Password noun in the Designer policy builder and supplying the DN of the password policy (in slash notation) for the policy to use (see example below).

do-set-src-password>

   <arg-string>

      token-geerate-passwordpolicy-dn=“[root]SecurityPassword PoliciesInitial Password Policy”/>

   /argstring>

/do-set-src-password>

If you were to paste this XML into your driver policy and execute it the rule would try to get the configuration for a password policy name “Initial Password Policy” in the Password Policies OU under the Security Organization (o=).  Once the rule had that policy’s information the Generate Password function in the driver would create a random password value that would fulfill the policy’s requirements.  After the password value was generated the driver would then attempt to modify the user/object from the current operation with the new password value.  It is a very clean and very simple method to creating passwords for users in a secure environment that does not require any complex comprehensive coding effort.

There is, however, a cost currently associated with this simple approach to generating passwords in a driver.  There is a known issue where if you have characters or values specified in the password policy’s exclude list that the Generate Password method used by the drivers does not take those values into consideration.  This means that if you add the character % to your policy’s exclude list and then generate passwords from your driver using that policy that the Generate Password method will continue to create passwords that include the percent sign (%) despite it being in the policy’s exclude list.  This oversight leads to a rather cryptic error in your driver logs:

Message: Code(-9010) An exception occurred: novell.jclient.JCException: generateKeyPair -16019 UNKNOWN ERROR

The true meaning of this error is that the password the driver is trying to assign to the user/object violates the password policy assigned to that user/object.  This can be very frustrating since in many cases it is often the same policy used to generate the password that is being violated and therefore blocking the assignment and generating this error.

So how can you use this method to generate passwords but still exclude certain characters?

NetIQ is working on a patch to fix this issue but at the time of this post there is no scheduled release date for that fix.  In the meantime, if you are only dealing with a few characters you can use another simple action in the driver to create a simple workaround until the fix is released.

In the Designer policy editor there is a verb for Replace All that lets you define values and patterns via regular expressions to look for in another value, like a password, and replace any matches it finds with a different specified value. This means that if you wanted to exclude percent signs (%) in a password you could use the Replace All verb with a search value of “%” and a replace value of “#”, or some other character of your choice, and assign that function to the Generate Password call (as seen below).  This would tell your driver to generate the password based on the specified policy and then perform the search and replace function on the value returned.

The Replace All action can be stacked multiple times in the event that you have multiple characters that you need replaced too.  

However, there is one thing to be cautious of when using this workaround.  Do not attempt to replace a character with a dollar sign ($).  If you are an experienced driver developer you know that global configuration variables (GCV’s) are referenced in driver policies by a preceding $ so what happens is if you specify the dollar sign as your new value the driver assumes you are making a reference to a GCV but since there is no variable name following the symbol the driver errors out:

     Message:  Code(-9010) An exception occurred: java.lang.StringIndexOutOfBoundsException: String index out of range: 1

at java.lang.String.charAt(Unknown Source)

at java.util.regex.Matcher.appendReplacement(Unknown Source)

at java.util.regex.Matcher.replaceAll(Unknown Source)

at com.novell.nds.dirxml.engine.rules.TokenReplaceFirst.expand(TokenReplaceFirst.java:96)

at com.novell.nds.dirxml.engine.rules.Arg.evaluate(Arg.java:460)

at com.novell.nds.dirxml.engine.rules.TokenReplaceFirst.expand(TokenReplaceFirst.java:93)

at com.novell.nds.dirxml.engine.rules.Arg.evaluate(Arg.java:460)

at com.novell.nds.dirxml.engine.rules.TokenReplaceFirst.expand(TokenReplaceFirst.java:93)

at com.novell.nds.dirxml.engine.rules.Arg.evaluate(Arg.java:460)

at com.novell.nds.dirxml.engine.rules.DoSetLocalVariable.apply(DoSetLocalVariable.java:100)

at com.novell.nds.dirxml.engine.rules.ActionSet.apply(ActionSet.java:178)

at com.novell.nds.dirxml.engine.rules.DoIf.apply(DoIf.java:84)

at com.novell.nds.dirxml.engine.rules.ActionSet.apply(ActionSet.java:178)

at com.novell.nds.dirxml.engine.rules.DirXMLScriptProcessor.applyRules(DirXMLScriptProcessor.java:307)

at com.novell.nds.dirxml.engine.rules.DirXMLScriptProcessor.applyRules(DirXMLScriptProcessor.java:429)

at com.novell.nds.dirxml.engine.rules.DirXMLScriptProcessor.applyRules(DirXMLScriptProcessor.java:429)

at com.novell.nds.dirxml.engine.Subscriber.processEvents(Subscriber.java:894)

at com.novell.nds.dirxml.engine.Driver.submitTransaction(Driver.java:628)

at com.novell.nds.dirxml.engine.DriverEntry.submitTransaction(DriverEntry.java:1065)

at com.novell.nds.dirxml.engine.DriverEntry.processCachedTransaction(DriverEntry.java:949)

at com.novell.nds.dirxml.engine.DriverEntry.eventLoop(DriverEntry.java:771)

at com.novell.nds.dirxml.engine.DriverEntry.run(DriverEntry.java:561)

at java.lang.Thread.run(Unknown Source)

 

This error results in the password not being set on the target user and prevents any additional logic from being applied to the current operation which could leave your user/object in an invalid state in the defined provisioning process.

*******************************************************************************************************

UPDATE: Novell Support is aware of this issue and have begun developing a fix.  You may want to consider contact Novell Support for possible patch information before implementing any coded solution.