Walking through the IDM 4 Google Apps Driver - Part 7


With the release of NetIQ Identity Manager 4.0 Support Pack 1 (aka IDM 4.01) some bug fixes, and a few new features were added.

Specifically three partner provided drivers were included, an RSA Driver, a Blackboard driver, and a Google Apps driver.

I discussed some of the new features and bugs fixed in IDM 4.01 in this series of articles:

I have been working on a series of articles walking through driver configurations, policy by policy to try and understand what the driver is doing, under the covers.

You can see more of these walk throughs on a Wiki page I maintain to keep them all together: Detailed driver walk through collection.

For this series of articles I would like to start looking at the Google Apps driver in IDM 4.01, that is provided by Consensus Consulting.

In the first article in the series I worked my way through the Subscriber Event transform and half way through the Matching Policy set.

In the second article in the series I worked my way through the rest of the Matching Policy set.

In the third article in the series I worked my way through the Creation policy set.

In the fourth article in the series I started working through the Placement policy set.

In the fourth article I did not quite finish the Subscriber Command Transform, so in the fifth article I continued to the end of the Command Transform and part way through the Schema Mapping policies.

In the sixth article in this series I would like to finish the Schema mapping policy set and begin to work through the Output Transform policy set.

In this article I would like to keep going through the Output Transform. It turns out there is a fair bit more in the Output transform than I expected.


AccountTracking - disregard if disabled or wrong object class

First off, if the GCV for enabling account tracking is not on, then break since there is no further work to do here.

There is a GCV that lists the object classes (drv.accTrk.objectClass) that Account Tracking will apply to, so for each of those values, if the current events object class (using the if class name condition token) matches the current value, then set a variable, pass to true. If the variable pass is not true (i.e. no Object Classes in the list matched the class of this event) then break, since again, no more work to do here.

AccountTracking - add operation-data for regular operations

The condition block uses a trick not everyone is aware of, using a Regular Expression in the equality test of a condition. That is, the default equality test is case insensitive. But if you look you will see there are many other types of equality tests. Case Sensitive, Regular expression, numeric, binary, Source DN, and Destination DN.

The Regular Expression option is very powerful, and since in RegEx a pipe symbol (|) means OR, then the you can do a single if operation equals, using Regular Expressions as the equality test with the value of "add|modify|delete|rename|move" which handles 5 different operations in one test.

First up is start building the operation properties that will be sent to the shim, and returned with the <status> document for the rules in the Input Transform to handle. AccountTracking-Operation is set to the current operation.

Next up a GCV drv.accTrack.mode, if set to fanout and we have an association value, then the AccountTracking-association is set to the association value and addObjectDN is set to true for later use.

Next we have a very strange If-then block that makes very little sense to me. First of all, there are no conditions, so everything is in the THEN block since it is always true, but not sure why bother?

Inside is a series of if-then blocks, testing if local variable current-node is equal to some string. and they are literal strings, then add an operation property. The problem is they are using the current-node variable which I did not think meant anything outside of a loop. In a for-each or while loop the current node represents the current node the loop is iterating over. This actually is a nodeset, but you can cast it as a string most of the time, if that makes sense. But without a loop, I am pretty sure this is empty. Regardless none of the values it tries to compare with make sense in terms of an event document. LDAPDN, DESTINATION, association are not usually strings that would be literal strings in an event document. It's like they forgot the loop.

The last test inside the block does make sense, if XPATH is true @from-merge='true' would catch merge events where the user is matched. In which case the op prop AccountTracking-association is set to the current association value and the variable addObjectDN is set to true.

A pair of variables are set to have a dash as the value, var-idvAccountStatus and var-appAccountStatus.

Next a test of if op attr is available, using a GCV, drv.accTrk.statusAttr which is isSuspended in the case of Google, which allows one Package to handle many possible driver combinations, since each system probably has a different attribute used to signify status.

If you think about that, it actually requires two packages. One the generic Novell provided one that adds the Policy objects to implement all the rules, and then a driver specific one, the Google Apps Account Tracking package that handles the GCV's for the package that are specific to this driver.

So if we have this attribute available, we set the variable var-accountStatusChanged to true, and then since the Status attribute might be like Login Disabled where true means it IS disabled whereas you could have a status attribute that worked the other way around, we have a GCV that defines the active state so we know how this attribute works.

There can be three values, I, A, U, and dash (- which is the value we set earlier on in this rule as a starting point). Inactive, Active, and Unknown. A cute if-then test is used to figure this out based on the GCVs for the status attribute, and the active and inactive state.

If the Status attribute is not available and its an add event then we set the variable to the default Status value from a GCV.

Then if the Source DN is available, and either of the variables addObjectDN or var-accountStatusChanged are true, we set an operational property, AccountTracking-ObjectDN.

If just var-accountStatusChanged is true, then set an op property, AccountTracking-AccountStatusChanged.

Finally in all cases, set two more op properties.


to the variables we defined and calculated earlier. This starts as a dash (-) and then gets changed based on the event in progress.

You can start to see what is happening here, the op data is being built up with the state of the user, the Users DN for cases where it matters. That is, cases where Sentinel, which is the consumer of the Identity Tracking data, cares to know that something has happened to the user. This is different than using Sentinel to track every change in the directory, which is possible. Rather this is a higher level, that only cares if the user has an account in this connected system, and is it active. We will see that in the Input Transform, the sister rule to this one will convert the data we send via op data, on a successful event and turn it into a write to the DirXML-Accounts attribute, which the Sentinel driver will send for Identity Tracking in Sentinel to use.

AccountTracking - add operation-data for mapped operations

This rule starts with a test of the GCV drv.acctTrk.mode and if it is set to fanout. If not move on. The other option is called One to One (Standard). I am beginning to strongly suspect that the Identity Tracking packages were initially designed on the SAP drivers, and then extended to be used on all other drivers. Thus there is a lot of SAP driver specific stuff in this configuration that is not relevant. The fanout configuration is based on a model used in the SAP UM driver. I think UM stands for User Management, but I am not certain. Anyway, in SAP each sub module has its own set of users and passwords. For the longest time, there was no directory for all SAP applications to consume. Now to make this tolerable for their customers, SAP added a UM module called the Central User Authority (CUA). This can manage users in all the other modules. Except that it cannot push passwords.

In the past with the SAP driver you would have to set up a UM driver to connect to every UM module you wanted to support. Or you could connect to the CUA, and use that to push the users to other UM modules, and then add a password only configuration driver to send just password changes.

This clearly became unworkable in larger environments, and if you have SAP, you are probably a larger environment. I also suspect the impetus was when Novell switched internally to using SAP their IT guys who run the internal IDM infrastructure at Novell probably decided this was no way to run a railroad. Thus with IDM 3.6.1 we got the fanout version of the SAP UM driver. This has a couple of modes, the old one to one mode, and a fanout mode. You can connect to the CUA with this driver, and then just specify all the connected UM's that you wish to push passwords too, and via the single driver it will handle just the password change issues to all those UM's. A hugely simpler to maintain model for large SAP clients. Thus we have the fanout and one to one mode in Account Tracking, since in a fanout world, this would still be a single driver for your user while it might represent dozens of actual accounts.

I think I will skip the rest of this rule in the context of the Google Apps driver and re-address it in a series just picking apart the Account Tracking package as it does not actually apply.

AccountTracking - strip AccountTrackingAccountStatus attribute

The last rule looks for the operational attribute AccountTrackingAccountStatus and removes it if present since it was set to carry data through this far and no further. Though I am not entirely certain where it might have been set.


This policy comes from the Groups package, and is used to handle Entitlements queries, which might be from a valued entitlement trying to get values, or possibly from the Reporting module, or maybe even the Role Mapping Administrator. If you look at the Managed System Gateway driver this is used to inject queries into other drivers at the request of the Reporting module, and that sort of query is what this rule is meant to handle.

If its a GoogleGroup object (since we are passed the schema map, we are in the Google application name space) and if it is a query event. However, looking at the schema map, Group is mapped to Group. Looking at it I see that this is actually the name of the Entitlement object used for Groups. You can tell, since the next rule for User entitlements tests for the class-name of GoogleAccount.

The first action is a Strip by XPATH of the following:


That means, parent of the current node (..), look for the query node, that is the last in the current XDS document, then remove the XML attribute class-name.

Then the event-id XML attribute is added with a value of query-driver-ident, a scope XML attribute is added with entry, and the search-class node is removed by a Strip by XPATH.

Then a search-class node is added back but with a class value of "__driver_identification_class__" which is a special event that returns the driver version, the license code version needed, whether the driver supports query-ex and so on. It is part of a driver startup.

Then the read-attr node is removed and added back empty. I suppose that is a read all values type thing.

It sort of looks like querying for groups won't work, so rather than hang the driver they send a query they know will work, but will return nothing dangerous or useful.

Finally a driver scoped variable GroupEntitlementQuery is set to true. This is a very bizarre rule. Now to be fair, we know from earlier that the support for Group entitlements is not complete, and I was informed that at ship time it was not ready for prime time, so they disabled it in the versions shipped, hoping to add support back when it was finished, working, and tested. I guess this is a placeholder as well to make sure it works without hanging the driver, even if it does not generate what you want for group entitlements to work.

This will be used in the Input transform, when the response comes back, to tag the query as being an entitlement query.

That's it for this article, stay tuned for more, still a couple more to go. Lots more to say, lots more interesting things to see, just you wait and see! Let me know if this has helped you out, or if you have any questions. If you have a particular driver you would like to see reviewed in this fashion let me know, there are so many possible drivers to do next, it is hard to decide.


How To-Best Practice
Comment List