Walking through the IDM 4 Google Apps Driver - Part 4


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 this article let's work through the Placement policy set and start in on the Command Transform policies.

The Placement Policy set has two policy objects:


This placement rule starts off with scoping it to Organization Units and Users, and makes sure there is a placement scheme selected in the GCV gcv.NOVLGGLEORGU.googlePlacementOption. I was going to say that this seems a bit problematic since we need to place users even if we are not syncing Org Units, but of course, the placement of a User differs if we have one over arching Org Unit in Google (not syncing eDirectory Org Units) from when we sync a whole bunch of Org Units into Google, and thus we want to place users in their proper Org Units.

Mirrored Placement Rules

If the GCV gcv.NOVLGGLEORGU.googlePlacementOption is set to mirror then the driver will use the Org Unit the user exists in to place in Google. So there is a condition that tests for this GCV, and makes sure we are only working with Users and Org Units. Finally there is a test that the user's Source DN is in the correct subtree (using GCV's for idv.dit.data.users)

If so, then the destination DN is set to the Unmatched Source DN which is that cool feature of the if Source DN token, that makes it available for use in a case like this. In other words, the Org structure under the User container in the IDV is mirrored to Google, but without the base DN's in the IDV. Which makes sense, as no doubt Google could care less what your tree name and first Organization or DC object is named.

Entitlement Placement for Users

Now if the gcv.NOVLGGLEORGU.googlePlacementOption GCV is set to entitlement, then the data for where to place it, is the payload of the Entitlement that was granted. This rule is only for Users, and looks for an entitlement object NOVLGGLEORGU.UserPlacementEntitlement. Then it loops through that entitlement on the user, and uses the ECMA function call es:getEntParamField($current-node,'ID') to get the data out of the entitlement payload as discussed earlier in this series. That value a backslash (\) then the Source Name of the user is set to the destination DN in Google.

Entitlement Placement for Organizational Units (Mirrored when Synchronized) (Typos in the original)

With the same basic conditions as above, except that the class is Organizational Unit instead of User, and there is no checking for an entitlement (but the GCV for placement is set to Entitlement) then if the GCV gcv.NOVLGGLEORGU.AllowOrgUnitsSyncToGoogle is set to true, just the Unmatched Source DN is used as the name to send to Google as the Destination DN.


This policy object, has a single rule, to handle the case where Organizational Units are not being synchronized, and there we are doing flat placement in Google. Thus it has a simple rule. If any object has gotten this far, and destination DN is not available, then set it to just the Source Name of the object.

In a Matching rule you can chain the Find Matching objects, since the first one to find an object will cause all the others to skip and not process. So you order them from most likely to least likely. In the case of Placement what you usually do is try to place, and then finally as a fall back, if all else fails, you can check by testing for the availability of Destination DN. This token is basically doing the same as you could do with an XPATH test of @dest-dn which looks for the XML attribute dest-dn, and if present is true, (even without a value! Since you could have a dest-dn="" which won't work, but would return true for @dest-dn. But your code would have to have failed and actually set the Operation Destination DN to a blank value) and false if absent.

That closes out the Placement policies, as this covers Users (if not using Org Units) and Groups since there is no class scoping in this rule and any object not yet placed (no destination DN available) will get the default placement.

Command Transformation Policy Set:

There are seven policy objects in this policy set. The first three are specific to this driver. The last four are the basic password handling packages, and in fact are the default NetIQ provided ones. They are not even customized by the Google driver at all.

There is not much to say about the last four policies so I will just reference the two articles I wrote on the topic of how a password change is handled by Identity Manager Drivers, in most drivers:

In short, the <modify> event with a <modify-attr attr-name="nspmDistributionPassword"> node, is transformed into a modify-password event that is sent to the Google Apps driver shim, which knows how to handle that special modify case. There are a series of GCVs involved that control how passwords are handled, and you should read the full articles to better understand all of what is going on. But since there is nothing special here related to the Google Apps driver I will leave it at that.

  • NOVLGGLEUSER-sub-ctp-HandleEntitlementsOnUsers

  • NOVLPWDSYNC-sub-ctp-TransformDistPwd

  • NOVLPWDSYNC-sub-ctp-DefaultPwd

  • NOVLPWDSYNC-sub-ctp-CheckPwdGCV

  • NOVLPWDSYNC-sub-ctp-AddPwdPayload


First the event is scoped with three tests. Limit it to groups, make sure the GCV for Groups and entitlements is not true, and then make sure a DirXML-EntitlementRef is changing. If any of those three things is not true, then do not process this event.

Now in light of the fact that the Group specific GCV object says that Group Entitlements are not supported at this time, this rule may be a future feature that is not yet ready for prime time. However it is worth seeing what the intent is.

Next rule, after scoping is conditioned on the Entitlement NOVLGGLEGRPS-GroupProvisioning changing.

If so, loop through the changing entitlements NOVLGGLEGRPS-GroupProvisioning, which using the Entitlement() token means the values being added. If it is a event, then set the destination attribute Permission to the value of the GCV gcv.NOVLGGLEGRPS.DefaultVisibility. As discussed earlier in the Create rule context, this is a hidden GCV at the moment and can have the values of Owner, Member, Domain, Anyone. It defaults to Domain, unless you edit the XML to make it visible or change it in the XML view.

Then it loops through all removed Entitlement values using the Removed Entitlement token.

There is a GCV gcv.NOVLGGLEGRPS.GroupCreateEntitlementLossHandler that has a couple of values, owner and DELETE. If it is set to owner, the Permission attribute is set to Owner (note the capital O vs the lower case o in the GCV) and the association is removed. That is the group is not longer synced via IDM, and the Google Apps permission is limiting it to the Owner of the group.

If the Loss Handler GCV is set to DELETE, then the destination object is deleted, and the association removed from the current object. In this case, we do not need to process the modify event any longer so it is vetoed.


This rule is scoped with three major conditions. First that the placement for Organizational Units GCV is set to none, the class is not User nor Org Unit and it is not a move or modify event. If any of those are true this policy is skipped. So basically if we are using Org Units, and a User or Org Unit has an event that is not a modify nor move, skip. So move and modify events get through.

Mirrored Placement Rules

There are three major condition blocks, that are OR'ed together so that any one block is sufficient to process the rule.

  1. User, and the placement GCV for Org Units is mirror, and the user is in the correct subtree.

  • For Org Units, with the placement GCV set to mirror, is not from a Merge event, and is in the correct subtree.

  • For Org Units, with the placement GCV set to entitlement and the Allow Org Units to Sync to Google GCV set to true, not from a merge, and in the right subtree.

The from merge event is an interesting one if you are not aware. In the case that an object in the IDV is created, and it matches an existing object in Google Apps, then a merge will occur, following the rules in the filter for Merge Authority. By the Command Transform, you can test for XML Attribute from-merge equals true or with XPATH of @from-merge="true". It is important to remember to handle this case, since it is not just the user created that matches an existing user. It is also used if the association values are lost and you need to do a resync to reconnect the objects, so it is likely more common that you would think.

You can read more about merge authority in the seventh article in a nine part series (so far, if you have more ideas to suggest let me know and I will write more) about common things newcomers to Identity Manager might not know. Usually this stuff really is in the docs, but it is so hard to divine the practical use cases that I thought it worth while to try and call them all out.

Part 7, about Merge Authority is available in this article: Common Mistakes Newcomers to IDM Make - Part 7

The rest of the series is available in these articles:

So these rules are basically for modify or moves of existing objects, and the first thing done in the actions is to get the object class into a variable lv_class.

Then the lv_DestinationParentDN is picked up using the ParseDN token, with a length of -2, (default start is 1, the beginning) which means go one node up to get from the last node, to the parent node. You can read more about Parse DN, a truly powerful token in these articles:

The ParseDN token is used upon the Unmatched Source DN token, as discussed earlier is this series, which holds the DN of the user from the If Source DN is in subtree path and down further.

If there is no value in the parent DN variable, in other words there is no parent container, then the value is set to a back slash (\) so that it can be used to build a DN in a moment. Otherwise it is left alone. Now they use an if local variable equals "" test, that is no equal to an empty value.

Then the object is moved using variable replacement ($lv_class$ the two dollar signs are how we specify the value of a variable) for the object class value, to the parent DN value specified. If it is backslash by itself that is not really a move event.

That is for modify events. If the object is moving in the IDV, then that is vetoed and the generated move event will proceed.

I do not understand the reasoning here, for stopping actual move events, rather if there is modify of an existing object, trying to move it. I suppose for an Organizational Unit, a move would include a change of the OU attribute since it is a naming attribute, but it seems like this would fire too often, and then generate probably a null event in the driver. There must be a major case where an object changes in some way that indicates this is a move event?

That wraps up this article. Stay tuned for more, we still have to finish the Command Transform, and then the Output and Input transformation policy sets which are actually much more interesting than I was expecting them to be. Hope you are enjoying this series, please let me know if you have any questions on this article.


How To-Best Practice
Comment List