Walking through the Multi-Domain Active Directory Driver – Part 3

The new Multi Domain Active Directory driver is a clever new approach to drivers in general yet reusing the hard work and maturity developed in the classic Active Directory driver.

In part 1 of this series I discussed the driver creation method, since this time it matters how you do it. (Drag it from the palette not from Right click, Add New Driver).

In part 2 of this series I discussed the Connection configuration objects and got through most of the configuration settings.

To finish up the configuration settings, we have one last GCV to work with. The Configuration GCV object (NETQMADDCFG-GCVs) has two sections, Synchronization Settings is first. If you read the description via the little blue i button, you will see they stole this from the REST driver and forgot to edit the description. But what it means is to provide more information about each domain.

Now this seems a little silly. On the one hand, we have connection objects created by a tool that only works if you properly import the driver (Via the Palette, not by "New Driver" from the driverset object). On the other hand you need to specify the Connection DN and a password in the driver configuration (Subscriber settings), yet on the gripping hand you have to set more information in the GCVs. It seems a bit odd to not consolidate this information into a single location.

Probably the tricky bit was the password since that should be managed securely so why reinvent the wheel when Named Passwords already do this. But that just limits it to the Driver configuration or a GCV. Not sure what the value of the connection objects are, when they still require all this extra configuration, especially in two different places.

In this GCV we see you need to provide the Domain DNS name, (say acme.com), the Domain Container in eDirectory, (something like ou=Domain,ou=Users,o=com), then the Active Directory User Container (perhaps cn=Users,dc=Acme,dc=com). Then two more settings for each domain, Subscriber and Publisher Placement Types. These can be mirrored or flat. The Domain Container is used to identify where IDV users are that map to this domain for matching and placement.

The Name Mapping Policy is the last set here, and is the same as in any Active Directory driver, where you can control how the users created get named with cn=, and how they get named by the CN in eDirectory (the username mapping) or via Full Name mapping (as CN=Geoffrey Carman). Similar settings for User Principal Name which might follow the user name, the AD email, the eDirectory email, or nothing at all.

There is a bug that in my Designer such that these options do not properly display but I just edited the XML to read the choices. I was sure this was resolved in a later package build but I do not see it yet.

That is about it for the GCVs, now on to the next interesting, but still not policy item.

Schema Extensions:

This driver includes two new schema attributes, that parallel the old Active Directory driver schema attributes.

  • DirXML-MDADContext

  • DirXML-MDADAliasName

These differ a bit from the standard attributes. In the first place, both are flagged as Sync Immediate. Usually eDirectory synchronization is pretty quick and sync immediate is not needed, so I wonder why they added that flag here. The problem with sync immediate, is that it is tempting to flag everything that way and when everyone is immediate, no one is immediate.

The second interesting tidbit is that while in the old AD model, these attributes were both strings, they are now both Path syntax attributes. That means they have three components, a DN which will reference the driver this instance of the value is related to, a string, with the value, and an integer, which I am not sure how they will use. I am told this is a direct homage to my series of articles on how you might make the Active Directory driver work with multiple instances. You can read all about that in this series: Managing multiple Active Directory domains in one IDM system

The basic problem in the past was, the Active Directory driver configs assumed you had only a single AD instance, therefore you only needed on DirXML-ADContext. But what if your enterprise, like so many had more than one AD? There were several options (Custom schema attributes for example) and I suggested instead use a PATH syntax plural version of the attributes and use the DN component to point at the specific AD driver instance.

Out of the box, the MDAD driver configurations support multiple domains within a single driver, and multiple forests using multiple drivers.

I look forward to seeing how they implemented this aspect of the code now that it is finally time to start looking at actual policies.

As usual, I will start with the Subscriber side, and work my way from the bottom of the fishbone upwards.

Subscriber Channel:

The Event Transformation policy set is actually empty in this driver, so that was easy.


Here we have two policy objects:

  • NETQMADDCFG-sub-mp-Scoping

  • NETQMADDCFG-sub-mp


I will note they still left this as a linkage weight of 500, but the second policy is 510. Getting closer to remembering to never leave anything at 500, but still not there. I noticed a number of package updates had come out that had mostly fixes for this a few months ago and I think that was a good sign. Since it is so easy to update packages, it is worth just fixing that kind of stuff out of band of major releases.

This policy has the standard "remember relative position in hierarchy" rule that many drivers use. This model was introduced with packages in IDM 4.0 since it allows you to chain matching rules and use an operation property to pass the message about trying to match or not.

However because of support for in the MDAD driver for many domain instances, we need to track the info for WHICH domain this user should belong.

So as is normal, the unmatched-src-dn operation property gets set, using the Unmatched Source DN token. This is the part that confuses people. The token works when used after an If Source DN in subtree test. But it does not magically set the op property, there is a step in the policy that does that. This is to persist the information to the next policy object. But it looks like they would be related, but not really.

Thus the conditions here were if the source DN is in the GCV for the IDV user objects and attempt-to-match operation property is not yet set to false (perhaps you chained a rule in earlier to do some matching? Then no changes needed, you can disable this and the following rules by simply setting an operation property in your policy. This is a good design to allow Packages to plugin as needed to other Packaged content).

A new variable, resDomain is used so we can know when we find the proper domain to work with, and since we are looping over a bunch of possible domains, best to have a way to know when we have found our proper domain.

There is a for each over the Structured GCV, which treats it like a node set and therefore loops over the <instance> nodes inside the drv.domains GCV.

Thus the domain_container variable can be set to the XPATH $current-node/definition[@name="drv.domain.container.name"]/value/text() because the <instance> node has a series of <definition> nodes, one for each component of the structured GCV. This says, for the $current-node (the <instance> node we are currently in) find the definition node, whose XML attribute name, is drv.domain.container.name which is then used in the next condition.

If the source DN of the current object is in the subtree for the domain container name, then this user belongs to the specified set of Domain configuration information. There is an additional test to see if resDomain is false to avoid doing the work again once a domain is identified.

A bunch of operation properties are set with the information from the configuration GCV so that the data can persist across the following policies. It gets the drv.domain.container, drv.domain.dns.name, drv.user.container, drv,subPlacementType, and drv,pubPlacementType.

Then it sets the resDomain to true so it won't loop anymore. If it does not find a domain that claims the container of this user, it sets attmept-to-match to false, since this is now out scope.


This policy has 7 rules:

  1. veto out-of-scope events

  • remember relative position in hierarchy

  • generate full name if not in Identity Vault

  • match users based on NT Logon name

  • match users based on full name

  • match everything else

1. veto out-of-scope events
This rule checks to see if the attempt-to-match operation property is true. If not it vetos the event. This is how the previous scoping rule, or a custom scoping rule you wanted to add via your own package would interact.

2. remember relative position in hierarchy

This starts with a test that is now redundant, if operation property attempt-to-match is true, since the previous rule vetoed all cases where it is not. Well I suppose they previously only vetoed cases where it is absent or set to false. I suppose if someone set it to a strange string then this would be necessary.

Then this does something that at first glance seems a bit odd. In the previous policy we set the unmatched-src-dn operation property. Now it is doing it again. Why redo it? Took me a minute to see the reason.

It requires you to remember a point I made above that the Unmatched Source DN token is dependant on the preceding If test for Source DN in subtree. In the previous rule, the If Source DN test was for the GCV defining the Users container in IDV. That could be \TREE\O\OU\OU\Users. But here the drv.domain.container.name operation property is copied into a variable (named JUST slightly different as drv.domain.container) and then a second if Source DN test is executed, this time with the drv.domain.container value as the test. This perhaps would be a path like: \TREE\O\OU\OU\Users\Domains\DomainA

In which case the Unmatched Source DN would be different and more relevant and relative in this second case. I.e The Unmatched Source DN with the Domain structure as opposed to within the User container structure.

If you do not look carefully this one could slip by.

3. generate full name if not in Identity Vault

This is the generic make sure we have a Full Name attribute for Active Directory. Especially if using Full Name mapping, and it builds it from Given Name a space and the Surname. This is basically the same as the standard Active Directory driver policy. The cute thing it does is use XPATH to normalize-space() the result since that cleans up extra spaces, leading and trailing spaces, which is a good thing.

4. match users based on NT Logon name

Now we get into the matching policies. If LogonNameMap GCV is true, we are looking for the users CN in AD, to match the CN in eDirectory. Now to be fair, they used the Source Name() token to get it out of the IDV which implies the naming attribute. This is important since CN is multivalued, but only one instance is 'naming'. That is, if I had a CN value of geoffc and gcarman, I could use an LDAP filter of (cn=geoff) or (cn=gcarman) but I could not do an Entry level search for both cn= values, since only one is naming. Usually the first. I am not entirely sure of how you could change the naming attribute directly, short of a rename operation.

This then does a Regular Expression cleanup to replace everything that is NOT this set:

with null. That is meant to remove illegal characters from the eDirectory naming attribute that Active Directory does not support. I know Alex McHugh who has posted at Cool Solutions before has gone through this in detail and I need to check and see if they took his fixed version here or not. He got back to me that this is the correct fixed version, which is always nice to see.

That is about all the time I have in this article, stay tuned for the exciting next article in this likely to be interminable series. (You would think I like to hear myself type or something).


How To-Best Practice
Comment List