Walking through the Bidirectional eDirectory Driver – Part 4

The release of IDM 4 SP2 includes 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 GCV's (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 the third article I started in on the Subscriber Command Transform policy set.

In this article I continue through the Subscriber Command Transform.

In the previous one, I mostly got through the policy object that handles entitlements, NOVLEDIR2ENT-cub-ctp-EntitlementsImpl

In this article there are two more policy objects to get through.

  • NOVLEDIR2ENT-cub-ctp-TagEvents

  • NOVLEDIR2DFC-cub-ctp-TransformLoginExpTime


This policy is a bit odd to me. From its name, NOVLEDIR2ENT you can infer it belongs to the Entitlements processing Package. But this is just repeating the previous rules tasks on changes to the entitlements, except instead of deleting, disabling, or enabling a user it is adding operation properties to the event.

It seems like it sets the following in the various cases:


The accountAction is either accountDeleteByEntitlementRevoke or accountCreateByEntitlementGrant on the Delete approach to entitlements, or accountDisabledByEntitlementRevoke or accountEnabledByEntitlementGrant.

What is unclear is who will consume this information in the future? My guess without looking is either reporting, Account Tracking, or the Audit policies as they are the three that are usually concerned with this sort of thing. Looking ahead I see that my guess was pretty good.

In the Input Transform, there is a policy, NOVAUDTENTC-itp-SendEntitlementsEvents that reacts to this op data and sends appropriate Audit events to Sentinel or the like.

This is a downside to packages, as it is hard sometimes to bundle everything needed into one focused package, and sometimes content needs to span multiple related packages. But this is not so terrible. I think a comment in the rules that explained this minor issue would have gone a long way to helping though.

In this policy object, we have three rules.

  • Account Entitlement change (Delete Option)

  • Account Entitlement change (Disabled Option)

  • Account Entitlement remove (Delete Option)

The first two handle the op data payload for when an entitlement is changing (added or removed) and the cases where the GCV in charge says Delete or Disable the user on a removed entitlement. Thus the actionAction has a different value in terms of saying Delete or Disabled and Create or Enabled as the GCV manages it.

The third rule is interesting and clever since it handles the case as seen before where the user is just deleted in the identity vault and this event is flowing to the connected system. This is an implicit Entitlement remove since there is no entitlement anymore if the object is gone. Thus sending an event through that this user was deleted in the connected system makes sense for auditing.


There is one rule in this policy object, Transform changes to loginExpirationTime and it looks at Modify events where the Login Expiration Time attribute is changing. Then it basically removes the specific remove-value for a specific time, and replaces it with a remove-all-values node.

I wonder why they felt the need to do this, but basically the "if operation attribute is changing" test is true if there is a remove, add, remove all values, or any combination of the three. (If op attr is available is only true if there is an add value in the event).

Thus there might be a remove-value node. So this value is stored in a variable using the XPATH of:
modify-attr[@attr-name="Login Expiration Time"]/remove-value

This is pretty standard XPATH, in the modify-attr node (We can assume the current context is the event node, the <modify> that is, so we can work from there, thus why it suffices to start with modify-attr.). Then using a predicate for the one whose XML attribute (the [] means its a predicate, and the @ means the XML attribute) attr-name is Login Expiration Time, and then the remove-value node underneath that.

Then a Strip by XPath removes that same item from the event document using the same XPATH.

Then if there is actually a value in the variable storing the removed time, and thus something was already there in the connected system convert this to a set destination attribute, which means remove all values, then add in a specific value.

I guess there must be a case where the values are wrong, and you throw an error when you try to remove the wrong value, first for being unable to remove it, and then on the add-value, trying to add a second value to a single valued attribute.

I do wonder what problem they were seeing at the root that caused this error case they are trying to fix.

Next up we have three of the four very common Subscriber Command transform Password Sync rules. This is interesting as a normal driver will have 4 in the Sub channel and 5 in the Pub channel. Whereas this driver drops one in the Sub channel, and replaces on in the Pub channel.

This is a great example of why Novell delivered the Password Sync packages in the confusing fashion that they chose. That is, there are two packages. In the Common, Password Synchronization grouping in the Package catalog there is a package that delivers 11 or so policies. (4 in the Sub, 5 in the Pub, one in ITP and one in OTP) but it does not link them in at all. Then each driver has its own custom Password Sync package that uses the Linkage tab on the Package to deliver links to policies external to this package (I.e. It links to objects in the Common password sync package). This is VERY confusing as you try to figure out how they controlled this.

But you can see that here they decided they only needed a subset of the password rules, and can deliver them trivially in this model.

I personally found that when I need to deliver different settings for password sync on a custom driver, I copy the Novell shipping one, since even a change to a Password Management GCV (like from bidirectional password sync on an Active Directory driver to Subscriber only) will dirty the package, and should you inadvertently run in Factory mode, could cause issues. Rather I copy the entire package into my own, and change the GCV's and linkages to match. I.e. If I chose not to send emails on password change failures, I would not link in the ITP and OTP rules that implement that.

The missing rule is the Default Password one, which would normally hardcode the password. This driver however controls it a bit nicer via a GCV for the Publisher channel (Pub-Command) but does not send the account to the connected eDirectory on the Subscriber channel if there is no password in the event, It actually vetoes in the Sub-Command, where it is actually a bit more clever and checks for any password, which could nspmDistributionPassword or the Private Key/ Public Key pairs as well since this driver supports both methods of password synchronization.

Output Transform Policy Set:

There are three policy objects in this policy set. One is specific to this driver, and the Password Sync and Account Tracking ones are common with other drivers.

  • NOVLEDIR2ENT-otp-EntitlementsImpl

  • NOVLPWDSYNC-otp-EmailOnFailedPwdPub

  • NOVATRKBASE-otp-Subscribe


There is a single rule in here, Intercept outbound queries for eDirAccount. which I have seen in other drivers, Google Apps, for example, where a query for eDirAccount as the class name, get translated to look like the default driver initialization event.

That is, the class name is removed, and changed to query-driver-ident, and then a AccountEntitlementQuery driver scoped variable is set.

I think this is to support User Application, querying into connected systems for information. But I am not entirely clear why this is. We will see later on in the Input Transform a companion rule that handles the results and sends back predefined information. So I am not sure what value the query has when it always comes back the same? My theory is that there may be systems (I would guess SAP for a variety of reasons) that might return useful information, but most other drivers do not, and therefore have to ensure a meaningful response, or maybe at least a non-error response.


This policy is the standard one from Password Sync Common package, so I will just refer you to my article on the subject elsewhere:


This policy is standard from the Account Tracking package, which is hugely verbose, and I think has some real issues. I will be writing a series on this package, and comparing the IDM 4.01 version of the packages with 4.02 so I think I will skip this one for now, but will minimally say that it tries to identify if this is a monitored class (like User) being enabled or created, so that the DirXML-Accounts attribute can be kept up to date. There is a companion Input Transform rule that reads the operation data this rule sets and updates the DirXML-Accounts appropriately.

That about concludes the Subscriber channel, which was interesting. Now onto the Input Transform, and then the actual Publisher channel. (Technically the Input and Output Transforms are not actually in either channel, they are before (or after) the channels.)

Next up in the Input Transform, followed by the Publisher channel.

Input Transform:

there are seven policy objects linked in here, from a bunch of different packages.

  • NOVLEDIR2ENT-itp-InitEntitlementsConfigurationResource

  • NOVLAUDTENTC-itp-SendEntitlementEvents

  • NOVLEDIR2MSI-itp-InitManagedSystemInfo

  • NOVLATRKBASE-itp-Publish

  • NOVLATRKBASE-itp-WriteAccounts

  • NOVLPWDSYNC-itp-EmailOnFailedPwdSync

  • NOVLEDIR2ENT-itp-EntitlementsImpl

There is stuff from Password sync (sends emails on failed password changes), from Audit (sends events on entitlements changes), from Managed System Gateway (used to set up the MSysInfo GCV object), and from the eDir to eDir drivers Entitlements package (To handle group entitlements after the user is created).

Some of these have been worked through before, since after all they are common across many drivers (which is kind of the point of using packages that are common, where possible).


This policy is one of those I am not sure I agree with the need. This basically regenerates the EntitlementsConfiguration object under the driver object ((A DirXML-Resource with a DirXML-ContentType of text/vnd.novell.idm.entitlementConfiguration xml) every single driver startup.

This is an XML document that lists the entitlements in this driver and some bits of information about them. What annoys me about this policy is that it basically is static, since if you add a new entitlement, while it will superficially pick up the new entitlement, it will not be enabled for RBPM, Role Mapping, and so on, until you add some GCV values to describe it, and then actually modify the code in this rule to support it, since it explicitly handles each type in a series of nested IF THEN actions.

Thus what is the point? Isn't it easier to just ship a template and tell people to edit it if they need to add a new entitlement? Even more so, the only reason it cannot be shipped as a ds-object in a package out of the box is that there DN of the driver needs to be represented in LDAP format inside the object. I.e. The references to the entitlements are full DN's in LDAP format, which I have yet to figure out how to make Packages deliver.

You can read much more about this approach with these two articles. The first is written to explain how you would add such support to your existing 3.61 driver for RBPM. The second is my attempt to dissect what the policy object does, and thus you will see why I am not a huge fan of this one. It is very clever, but seems wasteful.

However on the flip side this fires once per driver startup and never again so the waste of time is pretty minor, except that it really does clutter up a driver startup trace. There is another example of this in the Managed System Info rule coming up that does much the same though that one rebuilds a GCV object (MSysInfo) every driver startup, further adding to the clutter and noise.


How To-Best Practice
Comment List