Walking through the Bidirectional eDirectory Driver – Part 6
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 the fourth article I finished the Subscriber Command Transform, and Output Trasnsform and just started into the Input Transform.
In the fifth article I finished the Input Transform and Publisher Event Transform.
Let's try and wrap it all up in this article by getting through the Match, Create, Placement, and Command Transform policy sets.
First up is matching.
Publisher Matching Policy Set:
There are three rules in here, following the now common (to me at least, after a number of these walkthroughs on Packaged drivers) model for Matching.
This is the place where the container for objects is defined. (No class is specified here). The condition is if Source DN is in subtree ~drv.edir.base.container~ which is pretty standard.
Then the Unmatched Source DN token is used, which is a strange one, since it only has a value, if it follows an If condition test where the in subtree modifier is used. Because the value does not persist beyond this immediate event they store it in an operation property which will carry forward with the event called unmatched-src-dn which I could see leading people to believe that maybe the Unmatched Source DN noun token somehow generates this operation property, but alas it is does not.
A second operation property is set, attempt-to-match as true. This way, any object coming through out of scope will not get this operation property and we will see in a moment or two that the main matching rule will check for this property before proceeding.
The reason for not doing this all in one step is basically to allow the insertion of the next policy object to handle Entitlements, but will work equally well to add additional requirements of your own.
This rule checks to see if the GCV enabling entitlement support is on. If so, and the Account Entitlement is not there, then it sets the operation property attempt-to-match to false.
Now as I read this, I think this is wrong, since the Entitlement is on an eDirectory object in the Identity Vault, and thus the test If Entitlement is available ought to fail always, because to know if the target object has the entitlement or not, implies that you have already found and matched the user. In fact, comparing with an Active Directory driver, this rule just has the first two conditions and does not test for the presence of the entitlement, probably for the reasons I just outlined. Now it is possible I suppose that the connected system, being eDirectory might have an entitlement, but since containment requires it to be under a Driver object and there is no other half of the driver in this bidirectional, one piece, eDirectory driver that makes no sense either.
However it is mostly immaterial since it will always return false and so there is no real harm to this extra test other than processing time, which is reasonably minimal. I suspect this may get cleared up in a later package, before it is properly released.
This policy has three rules.
veto out-of-scope events
This is the rule that takes advantage of the operation property attempt-to-match. If it is not available or equal to null. Which I suppose could have been more simply tested for with in not equal to true. This is the sort of issue the odd way eDirectory handles booleans can lead too. That is, the absence of a boolean implies false. But it can also be explicitly false. (I did not know that for the longest time, and would always remove the boolean to imply false, till someone at a client (Hi Ray! Not sure if you are still reading these) pointed out that false is a valid state as well. Which in hindsight I should have seen since Login Disabled is often false in eDirectory.
Regardless of how they get there, if the attempt-to-match is not present or is equal to false, then the event is vetoed. This is the second step that allows inserting other rules and processing in between the first and last policy object. This change was made for Packaging so that rather than needing to modify the packaged content you can add your own rule, in your own Package for inclusion. This is important since in packages you want to run in the shipping state as much as possible.
One of the benefits of Packages is that Support can actually demonstrate if the issue is a driver bug or configuration bug by just asking you to switch the driver to run in Factory mode, which temporarily disables any customizations made to shipping packages. As you can imagine the fewer you make to the shipping ones the better. Thus the 'art' of Package building involves understanding how to insert your code as new independent items as opposed to modifying existing content. This gets tricky in some places and is not easy to do. The alternative, if you have to make heavy changes to the default configuration is to in fact basically copy the Novell provided Default Configuration policy as your own, and make your modifications there, instead of in the Novell owned policy. This way when you are ready and build your package, you use your Custom Configuration package instead of Novell's Default configuration package.
Like the Pirate Code, Default Configuration packages are more suggestions than rules. That is, Novell offers you an example of how you could do it, in a useful, out of the box way (usually supporting flat and mirrored placements) but since the real world is never quite that simple, you may need your own version. The downside is that if NOvell releases a package upgrade to the Default Configuration, we all know the docs will not detail exactly what changed between packages (I can dream, can't I?) and thus you will be responsible to go figure out what changed, and decide if it needs to be included in your Custom Configuration package as well, or not. With IDM 4.02 there are at least 126 new and updated Packages since the IDM 4.01 release, so you can see how you need to balance changes with extra work to support them, vs living with default configurations.
The second piece to the art of Package building, is figuring out ways to pull off tricks like this that make it possible for other Packages to insert content in a useful way.
Do match for flat placement
Flat is somewhat interesting as they match on first and last name in the placement container, which seems kind of odd. But for groups they look for a Group in the Group container with this specific name. (Entry vs subordinates search). This leads me to think this policy is not yet complete.
Do match for mirrored placement
This is much simpler, a Find Matching object, for an entry built by starting with the GCV defined base container, and then appending a backslash (\) and then the unmatched-src-dn operation attribute which will contain the structure in the connected system.
The next two rules match for flat or mirrored placement, based on the controlling GCV.
Create Policy Set:
The Create Policy set is empty, and you can add any such requirements you might need here in your own policy objects or Packaged content.
Placement Policy Set:
There is one policy object.
There are four rules in this policy object.
Perform Flat User placement
If the GCV for placement is flat, then the Destination DN is easy, its the base DN from the GCV a backslash and the object name.
Perform Flat Group placement
For groups the difference is that there are separate user and group base DN GCV's so use a different GCV.
Amusingly, they could have used variable interpolation in a GCV name field to have figured this one out in one condition. (Since the GCV ends in Users and Groups, if the class name is set into a variable, Class then idv.dit.data.$class$s would work (The final s is to make the User/Group of the class name plural). However that is just a fun example of the silly things you could do with the power of DirXML Script.
Perform mirrored placement in user subtree
If it is running in Mirrored mode, then it is much the same just the DN is built using the unmatched-src-dn operation property instead of simply the object name,
Veto objects other than User/Group for flat placement
In flat placement mode, other objects are vetoed, if they are not User or Group objects. This is sort of weird since you would want to allow for Org units or other objects to be synchronized.
In fact, the Subscriber channel does not do this, allowing Organizational Units through. Which makes sense since in Mirrored mode, you want to mirror new Org Units into the connected system. But in flat mode, you want to block them.
Like most Command Transform policy sets, this one contains the basic Password sync rules from the Common packages. Additionally this package has one more policy object handling the special cases of this driver, and finally there is an Account Tracking policy linked in here.
Beyond the usual four password policy rules from the Common package there are two additional packages of interest.
The Common Password sync package provides the policy objects but the driver specific Password sync package is used to link the policies into the correct location. This also delivers the first policy in this set, which is unique to this driver.
This policy is needed because this driver supports Password SYnc 1.-0 and 2.0. 1.0 is based on RSA keys being replicated. We sync the Public and Private key values tree to tree. V2.0 was the move to Universal Password and DDistribution Password.
Thus it is possible to have a password change event with (or maybe even an add event) with both sets of values. I was not originally sure why they need to clean up like this, but I wonder if it has to do with the fact that the four Common rules do not expect to deal with the actual attributes syncing Raw, rather they expect a <modify-password> event which means a change of the NDS password. THus we need to clean up to get a state where this makes sense.
There is a single rule in the policy object/.
On User add check if keys are being synched
For Users, being added, it checks if the Private Key, and Public Key attributes are present, or the Password Sync version GCV is set to 1.0. In which case the <password> node and any operation attributes nspmDistributionPassword, since the keys themselves are being synced, so no need for an actual password set event, the keys ARE the password.
Otherwise, thus where we are doing Password Sync 2.0 using UP/DP, then if there is no <password> node (Usually something handled in the create rule_) a default password from a GCV is added to the event.
Then finally if the nspmDistributionPassword is in the document, a Set destination password which adds a <password?> node is called.
This last one is a bit odd to me and seems out of place.
This rule comes from the Common Account tracking packages, and basically it finally writes out values for DirXML-Accounts if the operation properties set in the Input Transform so indicate. The DirXML-Accounts values is a pound (#) separated field consisting of:
current-node (CN in this driver)
op prop Account-Tracking-$current-node$ value
AccountTracking-idvAccountStatus op prop
AccountTracking-AppAccountStatus op prop
This is used to send to Sentinel for Identity Tracking.
That about wraps up the new eDirectory driver that is just one driver, instead of the old two driver model.
There is lots more good stuff in IDM 4.02 and I hope to be able to get through more of those changes in future articles.
You can read more of my driver walk through articles, and hopefully contribute your own, at the Wiki page I maintain to track them:
Please consider trying this for a policy or package or driver or anything you feel you know as it is helpful to others, and there is still so much more to write, I cannot do it all myself.