Managing multiple Active Directory domains in one IDM system - Part 1

With Novell Identity Manager there are a number of available drivers that come out of the box. These come with a default configuration, usually included with iManager (via the Identity Manager plugins) or with Designer. With the release of Identity Manager 4 Advanced Edition, Designer 4 has some new features (and the engine has the code to support them) called Packages. You can read more about Packages in this series I am writing on it! There is a TON of interesting things involved, and very little actual documentation from Novell at the moment:

Packages are a great way to replaced configurations and a big step forward, even though it will be relatively difficult to migrate to Packages, and there is not a lot of information yet out there on packages. However, I think long term it will be worth it.

The main issue with the configurations that came with IDM prior to Packages is that they are really like the Pirate Code, less like rules, and more like recommendations. (My wife loves Pirates of the Caribbean, had to make the joke). Thus Novell officially does not support them via NTS (Novell Technical Services) since it is basically impossible to support them. There is no way to be certain a client is running the 'shipping' code, nor is there any real method available to upgrade to different versions of the configurations.

Worse than that it is impossible to upgrade a driver configuration, since it would throw away any changes you made, and there is no way to manage the problem. Packages make this all possible (as long as you started with a Package) by breaking the configuration down to the smallest possible components and locking each one down. There is a factory mode option for NTS, so if you complain to support that there is a bug, they can ask you to turn on Factory Mode, and any possible changes you might have made get disabled, and if you cannot reproduce the bug in Factory Mode, they know whose code is broken. Annoying though that may be, it does help isolate the problem quite quickly! Each of those small units, can be upgraded independently, and since you are not supposed to modify them (You can, but Designer just whinges and complains, and nags, and flags the policy as different until you just give up on it) an upgrade should not break your code.

This also means that bug fixes to Packages can come faster, and in the two and half months since IDM 4 was released, there have been about a dozen updated packages already! (You can tell, since Designer 4 has a check for upgraded Packages option and Novell has some online repositories for Packages!) In fact, if you install Designer 4 fresh now, you will see all the updated packages, when it first starts up.

As it happens, I have actually spent the time reading the policies in some of the different versions of the drivers (at least for the Active Directory one, since it has changed the most, and is most commonly deployed) and come up with some major items of difference between them, however, that is not really a scalable solution since there are MANY driver configurations (at least per major driver of course) and many revisions over the years since NSure Identity Manager 2.0, 3.0, 3.5, 3.6, and now IDM 4 with Packages.

You can read some written descriptions of some of the drivers in this kind of detail on the Wiki page I maintain:

Please feel free to write up any driver, or even small segment of some driver that you understand and submit it to Cool Solutions. Let me know, and I will link it in. The more the merrier, and even I do not have time to write all the articles I want too! It would be helpful if there was some rule in a driver that does something that is not obvious, and you wrote up even that much!

One example that I find maddening personally is that the schema mapping for DirXML-ADAliasName changed between v4 and v5 of the Active Directory driver configuration. It used to map to sAMAccountName in Active Directory, and now maps to userPrincipalName.

Big deal? After all, User Principal Name (UPN for short) is just the sAMAccountName with an @ symbol, then the shortname for the domain. So geoffc@acme.local perhaps and you can derive the sAMAccountName from it trivially (XPATH of substring-before($Var, "@") for example). Well it turns out to have lots of consequences inside the way the driver uses these attributes. For example, DirXML-ADAliasName and DirXML-ADContext exist primarily to allow the driver to decide if a rename or move event coming from Active Directory is really a rename or really a move. This is because in both cases, the DN of the object is changed. That is CN=Geoffrey Carman, ou=silly writes, ou=writes too much,dc=way, dc=toomuch changing could be a rename event, if the cn=Geoffrey Carman part is changing, or a move event, if any of the rest of the DN is changing. I.e. The parent containers are now different, thus a move event.

Therefore you will see in the Publisher Event Transform, some rules to figure out what just happened. This is actually one of the trickier parts of the AD driver to understand why it is being done. The trick is to know that the AD driver shim sends two events in one document when it thinks a rename/move has happened. It sends a rename event then a move event. (Actually I have no idea what the actual order is, nor if it is always the same, it does not matter, but now that I think about it, I have no idea if it matters).

Then the rules use the DirXML-ADAliasName to get the old CN= value, and the DirXML-ADContext value to get the old DN value (using ParseDN start at 0, length of -2, which means chop of the CN= part).

Then it compares the old values from the attributes, and the new values in the move or rename document. If the CN='s are the same it is not a rename event, therefore Veto the rename. If the DN has not changed it is not a move event, so veto the move event. Therefore only one of the two events will make it through.

But there is a bigger issue here. This all works fine when you have a single Active Directory driver. What happens when you have users in two or more Active Directory domains. With Identity Manager this is otherwise a piece of cake. This is also a fairly common example as well for our clients. Often they want to migrate from one AD forest to another, using the IDM system with an Identity Vault in the middle to help the process along. (In fact we even did a SidHistory scripting driver to automate what the Microsoft Migration tool does, in copying the old users SID to the new user object. Kind of a huge security hole in some ways, since if you can modify this value, go give yourself the SID of 500 (or is it 512? I forget now) for Administrator in the old system).

Well what happens when I need two AD accounts with the DN's of:
cn=Geoffrey Carman, cn=Users,dc=sillyDefault, dc=com
CN=Geoffrey Carman, ou=silly writes, ou=writes too much,dc=way, dc=toomuch

Well which DirXML-ADAliasName is used? And which DirXML-ADContext?

Usually what most people do is create a pair of extra attributes, per domain involved, and modify the rules to use those attributes instead of the real DirXML-ADAliasName and DirXML-ADContext attributes. This is pretty easy to do, as you could almost simple export the configuration and search and replace the values. I would personally double check to be sure, but that usually is sufficient.

But how well does that really scale? Especially when you are like one of our clients who for whatever reason has about a dozen standalone Active Directory forests?

I have a proposed solution that my boss came up with, and I am just taking credit for. :Hehe. He is too lazy to write it up is my excuse.

Lets make two new attributes, to make the plural versions of DirXML-ADAliasName and DirXML-ADContext. That is, lets add two new attributes, that are multivalued and using Path syntax, and call them DirXML-ADAliasNames and DirXML-ADContexts.

Path syntax was meant to hold file system references in eDirectory. The most obvious example is the Home Directory attribute. Well to describe a NSS (Novell Storage Services) volume reference, you need a couple of things. You need to know what namespace you are referencing it in, the DN of the volume object, and then the path within that filesystem to the file or directory. Thus path syntax has three components, nameSpace (note the capital S) a 32 bit integer, volume a DN reference, and path a string.

Well this turns out to be used all over the place, for example, DirXML-Associations uses it exactly in this fashion. The nameSpace component stores the state value. Usually 0 for ignore, 1 for associated, and I forget what the rest mean, but they are unimportant. The volume holds the DN of the driver for which this association applies, and the path component holds the actual association value. You can see what those might look like in this article:
Open Call - IDM Association Values for eDirectory Objects

Well why not do the same thing with DirXML-ADAliasNames and DirXML-ADContexts (note the plural)?

Lets extend the schema, and add the two new attributes. Make them multi valued, which actually means, do NOT select the single valued flag when creating them. Make them Path syntax. I usually add them to the DirXML-ApplicationAttrs auxiliary class, since that is where DirXML-ADAliasName and DirXML-ADContext come from anyway. This way there is no need for a new aux class, though it is updating the Novell distributed schema... I concede there is a risk involved there and of course, you could use your own aux class to hold them as well. Actually now that I think about it, it might actually be a pretty bad idea to use the Novell aux class, since an updated attribute to it might overwrite the attributes. Hmm, will have to think about that one.

We have three components. The first two are pretty obvious how we will use them. The volume component will of course be the DN of the driver. This like DirXML-Associations means that you can have at least one instance per driver. (Actually, nothing is stopping you from having more than one, and in fact you need to make an effort to ensure only one is used!) This makes it very easy to detect, since every driver has a Global Configuration Value (GCV) called which returns the current drivers DN in backslash syntax, which is how the engine will show the volume component value, making a driver independent comparison trivial.

The Path component is obvious as well. In the case of DirXML-ADContexts it is what the local driver instance's DirXML-Context value ought to be. In the case of DirXML-ADAliasNames it would be what the local driver instance's DirXML-ADAliasName ought to be.

This has a side benefit, since if you had an existing IDM solution with an older Active Directory driver in it, you would have DirXML-ADAliasName holding the sAMAccountName, which usually is the same even in different AD forests (but does not have to be), and might be survivable coexisting, except for the fact that adding a new Active Directory driver would almost certainly mean using DirXML-ADAliasName to hold the User Principle Name, which means you have an immediate conflict. However with the plural attribute approach, it is now independent of drivers, so one driver could continue using the sAMAccountName value and the other the User Principle Name value in the Path component.

But what to do with the nameSpace component? Every time I see a 32 bit integer I think of one thing, CTIME! That is the internal time format for time attributes in eDirectory. You can easily use the Time or Convert Time token to get any time you wanted into the count of seconds since Jan 1, 1970 at midnight, which is easily stored in a 32 bit integer. Alas, it runs out of seconds, when treated as a signed integer (i.e. you can only go to 2 billion some odd seconds as the other two billion refer to the years before Jan 1, 1970) around the year 2037. I dunno what we are going to do when the Y2K37 bug approaches, but I assume someone else will fix it, since that worked so well before!

Now that is the concept, how do we actually do it? As they say, the devil is in the details. Stay tuned for the next couple of articles as I have tracked down all the places the changes are needed, and know what to change to make it all work!


How To-Best Practice
Comment List
    Hi geoffc,

    Im newbie on IDM, seems i can get some help from you :D

    We hv 1 driver set (lets call dset1) running AD, Entitlement, etc) in Development - idm 3.6.1. All works fine. Recently manager asked me to create 1 more dset one brand new server. So i managed to install new server, join idv tree, install IDM 4.02 and created dset4. Then i install AD driver on dset4.

    Now what is the next step to sync user from eDir to AD? Im not the one who create the AD in dset1 long time back and i cant find anything in Novell doc about sync user object from idv to AD.

    *i read your article but still not clear what to do for me to be able to sync the user to our new AD. This new AD is a new domain. So i can say we have 1 AD manage Citrix user in AD and 1 new AD to manage another domain.
    I've started to encounter some unwanted issues related to storing CTIME in the nameSpace component.

    Definitely, there are advantages to your approach (it's possible to track the history of the attribute)

    My issue is that it is causing unwanted events to trigger on other drivers that subscribe to these same attributes when a publisher channel merge occurs on the AD Driver.

    I'm wondering is this is again an example of why Novell stuck with 1 and 0 for their usage of the path syntax attribute. (getting more fancy breaks things in a very subtle way)
    The idea was my bosses, but he dumped it on me to implement (Those who can do, those who are really good delegate!). The first time we used it, we did NOT use it this way exactly, and this exercise allowed me to revisit and redo it in a more generic sense.

    I want t o try and make a Package for it, but this is harder as it interacts/overwrites policies in Novell provided Packages and I am not clear how to overcome that issue.
    Geoff, you've done it again. Or at least your boss did? Whatever. Last time I ran into this problem I put in separate attributes for each AD driver. This is so much cleaner.

    Most places I have been have their own set of Aux classes. It is probably best put in one of those rather than one that Novell provides. You never know what Novell might do to their schema definitions.