Walking through the Office 365 IDM driver – Part 4


In part one of this series I walked through some of the configuration, Packages, and GCVs used in the Office 365 IDM driver.

In part two of this series I walked through more of the GCVs and looked at some possible values for the License entitlements.

In part three of this series I looked at the Filter and Schema Map and some more entitlement issues.

In this article I will look at the configuration settings and then on to actual policies.

The driver configuration settings allow the developer to specify three classes of settings. A Driver options, Subscriber Options, and Publisher Options. If you look at the XML it is pretty obvious how they did it. the Driver options are any options set under the parent node, and two children, <subscriber> and <publisher> hold the channel configuration settings. Some drivers lump them all into the Driver options, but this one nicely breaks them up.

First up we have Office 365 user name and password, which is the account used to connect to Office 365 for doing the work. What is interesting is why not just use the Authentication Context as the user name, and the Application password instead of yet another username and password combo here? Interesting choice, wonder why.

Subscriber options has two settings. The Office 365 domain name, which is used to append to the CN to calculate the desired User Principal Name value in Office 365. In fact, this is of a very interesting type. Normally the <definition> nodes in a GCV or Driver Configuration have an XML attribute 'type' that defines how to display them. GCV's and Driver Configurations share a DTD, so if you ever want a UI to make a complicated Driver Configuration of your own, just do it in the GCV editors and paste the <definition> nodes and whatnot (you will see why this quibble in a second) into the XML View of the Driver Configuration. But this is actually a type of gcv-ref, which in fact does not start with a <definition> node. Rather it looks like this:

<gcv-ref display-name="Domain Name" driver-param-name="domain-name" name="drv.domain.name" type="string">
<description>Specify the Domain Name to which users are added in Office365. Ex "domainName.com".</description>
<value xml:space="preserve"/>

I talked about the various GCV types in these articles:

At that time, I was sort of unclear why ever you would use such a gcv-ref type GCV and in fact skipped over it, since I really did not understand it at the time. Now I do, and I see the cleverness inherent in the system (Which is better than the violence inherent in the system! Help! Help! I'm being repressed!).

It helps if you understand why there are two different settings mechanisms, that share a DTD. The GCV's are meant to be used by policies and whatnot in the engine. The Driver Configuration settings are supposed to be used by the shim itself, and usually you will see this XML rendered into a set of settings during driver startup. Thus they are two different sets of settings. But what if you have some info that needs to cross over into both worlds? Well you could define it twice. But now you are subject to the maintenance cost of remembering to switch it in both places should it change and the errors that ensue if you forget one of them.

Also, to read a Driver Configuration value, you need to use a local variable (say called CONFIG) to store the DirXML-ShimConfigInfo attribute from the driver, Base 64 decode it, XML Parse the text results, then select with XPATH something like $CONFIG//*[@name='MyConfigOption']/value/text() or the like. Using a <token-global-config-value> seems a lot quicker and simpler.

Thus was begat the gcv-ref. Define a GCV with a particular name. In this case, thusly:

<definition display-name="Office365 Domain Name" mandatory="true" name="drv.domain.name" type="string">
<description>Enter the Office 365 Site Context. For Ex <Domain-name>.onmicrosoft.com</description>

Then in the Driver Configuration, define a <gcv-ref> reference as above. You still have to repeat the setting information, but if you change one, you also change the other. Additionally, the format of replacing the <definition> node with a <gcv-ref> node makes it easy to create. Define the GCV, copy the XML, paste and modify the open and close nodes.

In some ways this is similar to the type='password-ref' case where instead of creating a Named Password and then making a GCV to hold its name, you do it all in one fell swoop. Technically a convenience thing but oh so convenient!

The second configuration option is Office 365 custom licenses. This is fun too, since it is a Structured GCV which are really a ton of fun. This allows you to say, I need a GCV that has multiple instances, and each instance contains a couple of other GCV style values.

Here we have two items inside each instance.

<definition display-name="Office365 Custom Licenses" instance-separator=" " name="custom-license" type="structured" value-separator=";">
<description>Create Custom Office365 licenses by disabling specific services. To assign the license created License Entitlements must be used.</description>
<template max-count="10" min-count="0">
<definition display-name="Custom License Name" name="custom-licensename" type="string">
<description>Specify the name with which license is to be created. This will appear as [name]:[domainname] in license entitlements.</description>
<definition display-name="Service name to be disabled" multiline="true" name="custom-disableservicename" type="string">
<description>Specify the service names to be disabled in custom plan. To disable more than one service, multiple service names can be mentioned separated by a comma. Ex "EXCHANGE_S_ENTERPRISE,SHAREPOINTENTERPRISE" to disable exchange and sharepoint in enterprise plan.</description>

The description says that these are used to make a custom license that disables specific services. The docs alas just repeat that string, so that does not help us understand this very well.

Looking at the description of the two component items inside we see that the Custom license name is added as a 'name' and that the entitlement value to use this will be: [name]:[domainname] This is a little unclear to me, as is this an attempt to show a JSON value, or is this meant to say, for a domain I called MyDomain.com and an exclusion license called CheapSkates, the value for the ID parameter in the entitlement granted will be:

Cheapskates:MyDomain.com, and thus in JSON {"ID":"Cheapskates:MyDomain.com"}

or literally in square braces like:
[Cheapskates]:[MyDomain.com], and thus in JSON {"ID":"[Cheapskates]":"[MyDomain.com]"}

Or since in JSON square brackets indicate an array of values, do they mean something like:
[Cheapskates]:[MyDomain.com], and thus in JSON {"ID":[{"Cheapskates":"MyDomain.com"}]"} and thus an array of one entry? 

The mind boggles, and it is very unclear what is intended.

However, it does seem that you can somehow use this to exclude services from a user, since otherwise the License entitlement would be used to include services only. I hope there is some policy that uses this, and not just buried in the Shim code, since I am really curious to see how this works. Alas we still do not have a list of values that are available to be excluded. In the second article in this series I reported a series of values I found, and it looks like the two examples in this description are not in that list. While I understand this sort of list might change on Microsofts side as they add, remove, and modify services from Office 365 but at least a list at the time of writing and a link to where to look at Microsoft for possible values would be nice to have. I will continue to hunt for the valid license codes and report back.

The Publisher side has a number of configuration options. There is an on/off switch for the Publisher channel which is nice. If you wish to use the Publisher channel, then it will cache into a database, in a path specified, the working directory. This is sounding a lot like the JDBC driver, where it polls on a schedule, and stores the previous values in a JDBM file.

The database file gets a password, since it will of course have interesting stuff in it, that ought not to be lying around in the clear.

The next item, "Confirm publisher delete" is an interesting idea, since it seems that an object present in the cache database, that is absent in the next poll would imply a delete, you could imagine cases of perhaps incomplete polling, or perhaps a permission change that hides them from your account. Thus the option to confirm a delete really happened, by checking back into Office 365 instead of just proceeding as assumed.

A nice setting that is added is the option to "Clear Current Cached Events" which would allow you to reset the cache database. I wonder if it resets itself back to false on each restart or if it stays as true until you change it. Sort of like how "Set timesync restart flag = on" in Netware used to work. Where the act of setting it to true, performed the action, then reset itself to false. Ah the good old days of Netware.

The only ECMA object linked into this driver is the standard Lib-AJC probably because of the function to parse the Entitlement parameter values as JSON.

We have the usual GCV objects linked in from the additional packages like MSysInfo, Account Tracking, Password Sync (though this driver does its slightly differently) and then Entitlements followed by the default configuration set.

Finally, on to policy. Lets start at the beginning of the Subscriber channel in the Sub-Event.

There are two policies objects here:

  • NOVLOFFIOPTL-sub-etp

  • NOVLOFFIDCFG-sub-etp


This has only a single rule, "extract CN from src-dn" and this is sort of odd. Why would you need to extract the CN from the Source DN? First off, you could use the Source Name() token to get the value, rather than using Parse DN on the Source DN (Which itself has a built in version of Parse DN!).

I suppose this could make sense if you had multi-valued CN's in your tree, which is quite possible, and by figuring out the CN like value used in naming, then removing CN from the event (Strip op attr CN) and adding it back, you force it to be single valued.

I suppose they could have just used UniqueID, it seems like a better choice, and more properly suited to this role. I know from looking ahead a bit that this CN value will be used to make the User Principal Name in Office 365, so it does seem like UniqueID would be a better choice. The driver is going to pretty much append an @ sign, then the domain name value provided in the driver configuration to build the User Principal Name. This is required to be globally unique, so it really does seem like UniqueID is a much better choice.

This comes from the NOVLOFFIOPTL package which is an optional package. I guess this meant as a clean up for multi-valued CN values. The up side, is that this means making your own version of this package should be simple. There is only one more policy in this package, and it is in the Subscriber Command Transform, where it tries to handle (poorly I would say) changing CN's oddly not as a rename event, and try to handle the Login Disabled attribute. It does look like the author of these policies is not aware of a couple of built in tokens in DirXML Script and is instead just doing it the hard way in XPATH. I will discuss this more, when I get to the Command Transform policy set.


There is only one rule in here, "veto move operations". I guess that makes sense since Office 365 tenants are basically flat in the remote directory. The structure seems like it would be between tenants at the Microsoft end. A move in a flat directory does not make much sense, so good to veto it. That does imply that renames work, which is a good sign.

I do wonder how they have it set up in their back end infrastructure. For example, one large Active Directory, with a domain per tenant, or just one flat large domain. They certainly have mucked about using their own custom schema for these pseudo objects, which is interesting, since that seems like they have cheated a bit. In Active Directory only Users, Groups, Computers, and Domains are security principals. Yet here it would seem like MSolUser objects appear to be security principals. It is good to be king and able to change the rules to fit what you need. I suppose the same is true of MSolGroup objects. I wonder if maybe they cheated as well and limited what you can do with these objects, by schema and are faking out needed rights some other way. I would love to know how they are hosting this under the covers over at Microsoft.

That about does it for this article, stayed tuned for more in the next article as I work my way through the Subscriber channel. Onwards to the Match policy!


How To-Best Practice
Comment List