Walking through the Bidirectional eDirectory Driver – Part 3

The release of IDM 4 SP2 will include a new eDirectory driver that does not need a full install of Identity Manager in both trees, rather just a changelog plugin will be needed on the connected eDirectory.

This is something people have wanted for a long time, and should be quite interesting.

In the first article in this series I discussed the packages used to deliver this driver, and then some of the configuration settings.

In the second article I discussed the GCVs (Global Configuration Variables) that come with the driver, and then on to policy walkthroughs, making it as far as the end of the Subscriber Placement policy.

In this article let's see if we can make it through the Subscriber Command Transform policy set.

The Command Transform policy set has a couple of package specific policies, but also the traditional Password Synchronization rules that come from the Common Password Synchronization package. The basics of how these work are discussed in these two articles (one for Sub and the other for the Pub channel set) in some detail.

Password Transformation Rule Sets
Password Transformation Rules in the Publisher Channel

The way Novell implements this is quite clever. The Common package delivers the policy objects. (4 and 5 policy objects for the Command Transforms. Sub has 4, Pub has 5. An ITP and OTP rule for emailing on password failures). But it does not link them into the policy flow. That is, if you just add this one package you get the objects but they are not shown as linked into the Command Transform.

Each driver has its own driver specific Password Synchronization policy, where the linkage is delivered. This also delivers the GCV's used to control Password SYnc behavior. These are the GCV's that the Password Management item in Designer's context menu shows, and iManagers Server Variables tab shows.

Now if you were building a driver that wanted only one way password sync, if you changed these settings you in fact dirty the package and run out of factory mode. The answer from Novell is copy the driver specific package as your own name. Then modify the default GCV values. Maybe you do not care about emailing messages on errors? In that case, do not link in the policy objects for the ITP and OTP. And so on. Customize it as you see fit. If Novell decides to upgrade the policy objects, that is a change to the Common package and you can apply it. This package you just made is more configuration (what links where, and GCV settings) so you can keep your own viable that way.

If you want to go see how this looks, go look at the package catalog. In any package, usually if you expand it down to a policy object level the Properties page has a linkage tab which shows you where this policy object is to be linked. However Password SYnc in the Common group does not have this for any object.

If you then expand say the Active Directory (or even this driver's) specific Password Synchronization package, look on the properties page for the Package, and the side tab of Linkage and you will see 11 or so entries as the various components are linked in. This is how you link to content in another Package without including the policy in yours. I.e. Sharing content, perhaps in a Library of the like.

In this drivers specific case there is an extra rule linked into the Sub Create that was discussed in the previous article that basically does a veto if no password in the operation. There is also a rule in the Pub command that is linked in and we will get to later in this series.

That was a sort of out of order description of the last four rules in the policy set. The first three rules are custom to this driver and of interest.

  • NOVLEDIR2ENT-cub-ctp-EntitlementsImpl

  • NOVLEDIR2ENT-cub-ctp-TagEvents

  • NOVLEDIR2DFC-cub-ctp-TransformLoginExpTime


Login Disabled attribute change in IDVault

The Entitlements support has a neat quirk here that is somewhat clever. If entitlements are controlling the access to this system, what do you do if Login Disabled changes? You can make useful arguments both ways. Propagate it soonest, since a Login Disabled is usually intended to lock out an account. Or maybe you want the entitlements to be correct and if you need to lock someone you should remove the entitlements to do it.

Thus if the GCV drv.entitlement.Account is true (i.e. Entitlements are in use and control access) then if the drv.sync.disabled GCV is false, (and its a modify, and Login Disabled is being added in the document) then strip out the operation attribute Login Disabled.

Thus you can now control this via a GCV. Very clever approach.

Disable account for delete operation when using account entitlement

Similarly, if a delete event comes out of the vault, there is no entitlement being removed per se. In which case you would probably want to clean up connected systems.

This rule however seems incomplete. If you delete the user and Entitlements are in use (GCV that controls it is tested) then you disable the user and veto the delete. I guess since you did not actually remove the entitlement first?

Seems like a check of the GCV of what to do when entitlements are removed would make more sense. I.e. As the next couple of rules will process. Consider the drv.entitlement.remove GCV and do this action if set to disable, and let the delete through if set to delete. After all, a delete in the Identity Vault is mostly equivalent to removing an entitlement, isn't it? The object no longer has the entitlement after all.

Account entitlement change (Delete Option)

This is the pretty typical by now (if you have been reading my walk through series articles) approach of looking at the entitlement state and if it is absent, being removed or being revoked, to handle the User Account case by either deleting or disabling, and using a GCV to control that setting.

If the GCV controlling entitlements usage for Accounts is true, and the remove GCV is set to delete, and this is a user, modify event, and the entitlement Account is changing then this rule fires.

Because it is often possible (and in those cases, desirable) to have more than one entitlement the rule loops via a For Each over the Removed entitlements token, and deletes the destination object, removes the association, and then does a break.

Then because we are checking for changing entitlements an add entitlement is a possibility, in which case we consider this a reactivate case, because it is a modify by the Command Transform. If the object did not yet exist in the connected eDirectory we would have gotten a synthetic add and this would be an event.

Regardless, for each Added Entitlement, we set the GCV provided status attribute (drv.accTrk.statusAttr) to false. There is a problem as this is a GCV from the Account Tracking package, and this rule is from the Entitlements package. So there is a hidden dependency here. This is a pretty clever approach, to use the GCV to control it, and since Account Tracking needs it to understand how to decide if an account is active or not (for use in the DirXML-Accounts attribute for Sentinel's Identity Audit functionality). However the crossing of Package lines can cause an issue potentially if you like me do not think so highly of the Account Tracking package. Of course you will quickly get an error on your first attempt to start the driver, I imagine and it is pretty easy to figure out the problem.

Account entitlement change (Disable Option)

If the GCV controlling entitlements usage for Accounts is true, and the remove GCV is set to disable this time, and this is a user, modify event, and the entitlement Account is changing then this rule fires.

Again a loop over removed entitlements to set the drv.acctTrk.statusAttr to true, and for each added entitlement a loop setting it to false.

Same issues as before with the package cross over.

Group Entitlement change

Group entitlements have values, so often you will have many, one with the name (well usually GUID for eDirectory and Active Directory at least. You want a value that can survive move and rename events in the connected systems. Names may change buy GUIDs are forever.) as the parameter.

Now the format of the parameter is now on its third value. Used to be there was just one parameter. So you could say the value of the entitlement and get just the single simple value. Then with IDM 3.6.1 to support the SAP UM fanout drivers, they said, well still one value but lets pipe (}) separate it. So now we can have multiple values in one single string with a separator.

With IDM 4 they more correctly said, lets extend this in a more useful fashion and make it JSON. Now you have three possible formats for the data, so how do you get at it?

Well originally, the text node would suffice, that is the raw value of the entitlement, was the simple value.

With the pipe separated versions they had to process the simple value (using the SPlit token I guess. Amusingly, the separator field in Split and Join tokens are actually regular expression fields, and thus it would not be | but rather \| and escaped pipe, since a single pipe in Regular Expressions means logical OR, and thus everything is selected).

With the new JSON format, which is basically {"key" , "value} , {"key2" , "value2"} format they wrote an ECMA function. This is kind of clever since they check in the function to see if it looks like JSON, if so, handle it as JSON, if not, handle it as the previous format and thus you get nice backwards compatibility.

The function is called as: es:getEntParamField($current-node,'ID') which takes the current value of the Entitlement (the simple value, which is now more complex) and looks for the key ID, and returns the value out of the JSON.

Thus if a Group entitlement is changing, then you loop over all the removed group entitlements first and remove the user from the group using the ID value (which should be the groups GUID, since GUIDs survive renames and moves). The last step is to use set XML attribute to add an association-ref value to the modify event for a group, of the current user, to add the association of the current user, to the event.

The same is done for Added Entitlements.

Now to explain what that set XML attribute is doing is worthwhile as a diversion.

The action looks like this:

<do-set-xml-attr expression="../modify[last()]/modify-attr[last()]/remove-value[last()]/value[last()]" name="association-ref">

The target expression is:

This says, go up one node from the current node, which in XPATH in IDM is always the current event (i.e. Our original document) and then look for the node, where it is the last() one. (The [] mean WHERE as a predicate). Then find the last modify-attr node, and the last remove-value node, and the last value node, so that we know we are getting the even we just added.

If you do not use last() as a predicate of each of those node tests, then if there is more than one in any case, all that match get the value.

This can be really annoying and hard to troubleshoot until you understand what is going on. I discussed this with some clear examples in this article:
Common Mistakes Newcomers to IDM Make – Part 10

You can read the entire series I wrote about mistakes newcomers to IDM make if you are interested as there is lots of good content to learn there. I based it on questions a new team of IDM developers I was helping kept asking me.

Common Mistakes Newcomers to IDM Make Series

Anyway, the token before this one had just done a remove of a Member from a group. This generates a second <modify> event, since it is a different object. This is a <modify class-name='Group'> and it is identified by the association value of the group (which we got from the Entitlement ID value).

Thus we need to modify the <value> node and add an XML attribute association-ref so it changes from:

<modify-attr attr-name='Member">

To a value node that looks more like:

<modify-attr attr-name='Member">
<value association-ref="123ADEF498342">cn=SomeUser,ou=groups,ou=acme.o=com</value>

Anyway, stay tuned for more in the next article in the series.


How To-Best Practice
Comment List