Synchronizing Multiple OUs Effectively with GCV
Novell Cool Solutions: AppNote
By Michel Bluteau
Digg This -
Posted: 12 Jul 2006
This is the second AppNote I'm writing on this topic. The first one, published in January 2006, leveraged special object classes and attributes in order to achieve the same result. This time, the solution I describe leverages Global Configuration Variables, or GCV. It is probably more effective, although it requires that the person managing the list of OUs that are to be synchronized be able to modify the driver objects or the driver set object.
The main issue of this AppNote deals with real-life scenarios where more than one OU needs to be included in the scope of a driver for Active Directory or LDAP, or between two eDirectory trees. Sometimes the OU names match on both sides; sometimes they don't. Also, a dynamic situation is expected where OUs will be added, removed, or moved around. Instead of having to update several rules in several policies all over the drivers, the solution I propose here will centrally manage the list of OUs through GCV, defined at the driver level. It can also be defined higher up at the driverset level, if they need to be shared by multiple drivers. Even if the GCV are not shared, it may be a good idea to define them at the driverset level, again with the idea of centralizing the management of those lists in one place.
In this AppNote, I will configure a driver to manage the User object. I will not cover Group or other objects, but the same kind of idea can be applied to other objects.
Creating a New Project with Designer
Let's use Designer to put together a new project.
1. Start a new Identity Manager project.
Figure 1: New Identity Manager Project with Designer 1.2 Build id: 20060627
A new blank project window appears in IDM.
Figure 2: New blank project in Designer
2. Drag and drop an Identity Vault object onto the blank project.
Figure 3: Add Server to Identity Vault wizard
A new Identity Vault object is created.
Figure 4: New Identity Vault object
3. Drag and drop a new Active Directory driver in the project.
Figure 5: New Active Directory driver
4. Accept defaults and enter a domain name and domain DNS name.
Figure 6: Domain name and domain DNS name
5. Use the wizard to create a single Flat synchonization between the OUs on both sides.
Figure 7: Single Flat synchonization between the OUs
6. Set the Exchange policy to none. If you prefer, you can implement an Exchange policy, but you will get an additional page for the wizard.
Figure 8: Setting no Exchange policy
7. Accept the defaults for the other pages in the wizard. You should get a success status at the end of the wizard.
Figure 9: Resulting Identity Vault with the Active Directory driver
8. Set up a matching rule on the Publisher Channel.
Figure 10: Matching Rule on the Publisher Channel
The above Matching rule on the Publisher Channel(From AD to eDir) checks if the user object in AD is under OU=Users,OU=Quebec,DC=domain,DC=com. If so, it sets a value for Unmatched Source DN (CN=username if the user is under OU=Users).
9. Set up a rule to veto events for users outside of the scope.
Figure 11: Default rule for the Matching Policy - uses the NT logon name and looks for the user under deltaguitars\quebec\users
The rule above will veto event for users outside of the scope (no value for Unmatched Source DN), and the match rules will try to find the user in the right location. If you need to add support for a second OU mapping, you would basically copy the existing rule and modify the AD OU that it checks for.
All these rules are applied sequentially, and you can add as many as you want. But this quickly becomes out of hand when you have more than a few to manage. Also, other rules in other policies would also need to be updated that way, for example, the placement rules.
If you were to handle multiple OUs with this matching rule, you would probably need to add a condition like the ?if source DN? in the first rule to the Condition Group to test where the users is in AD. You would need to copy this resulting rule to handle a second OU, and so on. Again, this can quickly become a problem if you have many OUs to manage and if things are changing often.
10. Set up a Placement Rule for the Publisher Channel.
Figure 12: Placement rule for the Publisher Channel
The placement rule would need to be modified with the addition of an "if source DN" condition, and the rule would need to be copied in order to manage multiple OUs.
Modifying the Driver
Now, let's modify our default driver with scalability and a dynamic environment in mind. Let's say that we have 10 OU's on each side (AD and eDir) that we need to map, and that the names are sometimes different (remember that AD is case-sensitive).
We will create a GCV at the driverset level that will take care of the mapping. We would need a list of mappings (10). The list type GCV can be used, and we will use a special character that we don't expect to see in OU names as a delimiter between the AD OU and the eDir OU - such as the "#" character.
1. Create the Global Configuration values in the Driverset properties.
Figure 13: Driverset properties, Global Configuration Values
2. Create a new GCV for the OU mappings.
Figure 14: New GCV for OU Mappings
3. Add all 10 mappings as values, using the # character as a separator.
Figure 15: Adding all 10 mappings
The resulting list GCV will contain all 10 mappings.
Figure 16: GCV with all 10 mappings
4. Insert a new rule (before the top one) for the Matching Policy, Publisher Channel.
Figure 17: New rule for Matching Policy, Publisher Channel
The name of the rule can be changed to something more meaningful down the road. The first step is to simply create a rule that will retrieve the list of values from the GCV and copy it into a multi-value variable.
5. Accept the AND Conditions and the OR Groups and click Next.
Figure 18: Selecting the condition structure
6. Set the single condition to test if the object in the event is a User object.
Figure 19: Defining the condition
7. Select Continue to begin defining the action, then click Next.
Figure 20: Continuing ...
8. Define the action to set the values for the local variable OumapAD by retrieving the content of the GCV OumapAD. Use the Editor to set the node set argument.
Figure 21: Defining the action to set the values for the local variable OumapAD
The reason for moving the mappings into a local variable is so we can parse the values with a for-each, which would not be possible directly with a GCV.
Figure 22: Resulting rule for setting the local variable OUmapAD
9. Add a second action in the same rule that will set the local variable OUsource value to the Source OU where the user is located in AD.
Figure 23: Adding an action to set OUsource value to the AD Source OU
10. Add a third action to the same rule that creates a local variable called destDN through the use of a for-each action.
Figure 24: Adding an action to create local variable destDN
11. Use an XPATH expression to build the destDN value.
Figure 25: XPATH expression for destDN
Here, we are leveraging XPATH in order to build the value. We try to find the substring after the AD OU and the separator (e.g., OU=Users,OU=Quebec,DC=domain,DC=com#, which would give deltaguitars\quebec\users) by using the substring-after function and the concat function. For a negative instance of the substring-after function for a given node, the result would be an empty string. So, we can concatenate all the results and get only the resulting destination OU (e.g., deltaguitars\quebec\users).
12. On the Subscriber Channel, flip the logic around like this:
13. Disable the 2nd rule, then add another action to our first rule. This creates a local variable that corresponds to a value in the list of mapped OUs if the Source OU is mapped.
Figure 26: Disabled 2nd rule, new action for local variable (list of mapped OUs if the Source OU is mapped)
14. Modify the veto out-of-scope event rule.
Figure 27: Modifying the veto out-of-scope event rule
The XPATH expression $inScope=$OUmapAD will evaluate to True if the value of $inScope is in the list, and it will evaluate to Not True if it is not (veto).
15. Modify rule that attempts to find a matching user in the eDirectory OU.
Figure 28: Modified rule for finding a matching user
16. Modify the matching rule for the NT logon name.Figure 29: Modified matching rule for the NT logon name.
17. Use the local variable destDN to build the destination DN for the user.
Figure 30: Modified matching rule for the full name
You should disable the last rule and match everything else, unless you plan to match other objects, such as Group or OU. That would require other rules similar to the ones we created, in order to support multiple OUs.
18. Copy and paste our first rule into the Placement Policy (Publisher Channel), as the first rule.
Figure 31: First rule in the Placement Policy (Publisher Channel)
19. Remove the "set local variable inScope" action, because it is not used in the Placement Policy.
The placement rule needs to be modified, because it is static.
Figure 32: Placement rule to modify
20. Modify the rule so it takes advantage of the local variable destDN.
Figure 33: Modified placement rule (with destDN)
Subscriber Channel Rules
Next we will quickly cover the rules for the Subscriber Channel.
1. Copy and paste the rule from the Publisher Channel, and flip the logic around.
2. You also need to disable the remember relative position in hierarchy rule.
Figure 34: Subscriber Channel Matching Policy
3. Copy and paste the "veto out-of-scope events" rule from the Publisher Channel Matching Policy to replace the one in the Subscriber Matching Policy.
Figure 35: Subscriber Matching Policy with veto rule
4. For the "match users based on NT logon name" rule, replace the static DN with the local variable destDN.
Figure 36: Local variable destDN in match NT logon rule
5. Modify the "match users based on full name" rule, replacing the static DN with the local variable destDN. I selected to disable the match everything else rule for the same reason invoked for the Publisher Channel above.
Figure 37: Local variable destDN in match full name rule
6. Copy the new rule from the Subscriber Channel Matching Policy into the Placement Policy in order to generate the destDN local variable.
Figure 38: Placement Policy with rule to generate destDN
7. Modify the "placement for all objects" rule and replace the static OU with the local variable destDN.
Figure 39: Local variable destDN in the placement rule
The Active Directory driver filter is shown below.
Figure 40: The Active Directory driver filter
If we look at the filter, we realize that the object Organizational Unit and Organization are not synchronized. This is because we selected Flat versus Mirror. Also, we have the Group object allowed by the filter, because we selected to synchronize Group through the import wizard. For a given environment, Group may follow the same kind of mapping that User follows, or it may be different. We could use static rules if we have one or a few OUs that are not changing over time, but if we have more than a few, then we should probably add logic similar to the logic we used for User.
If you do not need to synchronize Group, you could modify the filter to not allow events on the Group object to be processed.
The driver we have at this point is not finished, but the main ideas are there - to use GCV and XPATH to effectively and centrally manage multiple OU mappings. You can download the driver export file using the link below and examine it in Designer. Then you can copy and paste bits and pieces into your own project and drivers.
Link for the XML Export File
I hope this AppNote will prove useful to you, and that you will be able to leverage some of these tricks in your own projects. Do no hesitate to send me your feedback, comments, or questions. Thank you for taking the time to read this article.
Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com