ADAMSync can also transform users in to proxy users

Now that we have ADAMSync synchronizing our data over, we should probably investigate the most commonly asked for transformation: proxy user transformation.

When we introduced proxy bind in ADAM RTM, customers seemed to really connect with the semantic. If anything, I’d argue we have customers overusing proxy bind! But that’s a conversation for another day.

However, the introduction of proxy bind opened a bit of a management scenario that had not yet been seen. When you use proxy bind, you must first have created the objects to which you will proxy bind. That means one need create and maintain these new objects in the ADAM environment which correspond with the AD users. This seems like a natural scenario for ADAMSync.

In RC0 we enabled what we typically call “user to userProxy transformation.” This transformation is simple….one can take users being synchronized and create proxy users out of them. These proxy users may be of the Microsoft defined proxy user class (called userProxy) which has shipped with ADAM since RTM, they could be of the new class we added to R2 to help with this (userProxyFull), or they could be some custom class you have implemented (any class defined with an aux class of msds-proxybind will have the proxy behavior). We allow you to tweak this in your configuration file.

So let’s give it a try.
Before doing anything, we need to get a class defined that leverages the proxy bind functionality. For the sake of simplicity I’ll use the one that ships with ADAM:

C:\WINDOWS\ADAM>ldifde -i -f MS-UserProxy.LDF -s localhost -t 50000 -c "cn=configuration,dc=x" #configurationNamingContext
Connecting to "localhost"
Logging in as current user using SSPI
Importing directory from file "MS-UserProxy.LDF"
Loading entries....
3 entries modified successfully.

The command has completed successfully

Time for ADAMSync itself….
I’m going to go ahead and change the heart of the sync file as follows (things modified in red):

<?xml version="1.0"?>
<doc> 
 <configuration>  
  <description>sample Adamsync configuration file</description>  
  <security-mode>object</security-mode>        
  <source-ad-name>erictest.local</source-ad-name>  
  <source-ad-partition>dc=erictest,dc=local</source-ad-partition>
  <source-ad-account></source-ad-account>               
  <account-domain></account-domain>
  <target-dn>ou=SyncTargetOU</target-dn>  
  <query>   
   <base-dn>dc=erictest,dc=local</base-dn>
   <object-filter>(objectCategory=person)</object-filter>   
   <attributes>    
    <include>objectSID</include>    
    <include>sourceObjectGuid</include>
    <include>lastAgedChange</include>
    <exclude></exclude>
   </attributes>  
  </query>
  <user-proxy>
<source-object-class>user</source-object-class>
<target-object-class>userProxy</target-object-class>
</user-proxy> 
  <schedule>   
   <aging>    
    <frequency>0</frequency>    
    <num-objects>0</num-objects>   
   </aging>   
   <schtasks-cmd></schtasks-cmd>  
  </schedule> 
 </configuration> 
 <synchronizer-state>  
  <dirsync-cookie></dirsync-cookie>  
  <status></status>  
  <authoritative-adam-instance></authoritative-adam-instance>  
  <configuration-file-guid></configuration-file-guid>  
  <last-sync-attempt-time></last-sync-attempt-time>  
  <last-sync-success-time></last-sync-success-time>  
  <last-sync-error-time></last-sync-error-time>  
  <last-sync-error-string></last-sync-error-string>  
  <consecutive-sync-failures></consecutive-sync-failures>  
  <user-credentials></user-credentials>  
  <runs-since-last-object-update></runs-since-last-object-update>  
  <runs-since-last-full-sync></runs-since-last-full-sync> 
 </synchronizer-state>
</doc>

The new user-proxy section is what defines the transformation.
One can transform….well, anything to anything! :) So long as you are going from some sort of security principal in the source to a proxy user in the target, it’ll fly right along. I’m using userProxy just to keep it simple. Note that I also included objectSid as proxy users require the SID to be specified. Finally, I changed my search filter to look for object with an objectCategory=person just to isolate exactly what I wish to import.

C:\WINDOWS\ADAM>adamsync /install localhost:50000 ADAMSyncDemo.XML
Done.

C:\WINDOWS\ADAM>adamsync /sync localhost:50000 "ou=synctargetou" /log –

<chopped for brevity>

Finished (successful) synchronization run.
Number of entries processed via dirSync: 6
Number of entries processed via ldap: 1
Processing took 0 seconds (0, 1080131584).
Number of object additions: 7
Number of object modifications: 0
Number of object deletions: 0
Number of object renames: 0
Number of references processed / dropped: 0, 0
Maximum number of attributes seen on a single object: 5
Maximum number of values retrieved via range syntax: 0

And sure enough, when I go to look for some of the users I know should be there…..

>> Dn: CN=Administrator,CN=Users,OU=SyncTargetOU
 3> objectClass: top; syncEngineAuxObject; userProxy;
 1> cn: Administrator;
 1> distinguishedName: CN=Administrator,CN=Users,OU=SyncTargetOU;
 1> instanceType: 0x4 = ( IT_WRITE );
 1> whenCreated: 09/23/2005 10:59:13 Pacific Standard Time Pacific Daylight Time;
 1> whenChanged: 09/23/2005 10:59:13 Pacific Standard Time Pacific Daylight Time;
 1> uSNCreated: 23644;
 1> uSNChanged: 23644;
 1> showInAdvancedViewOnly: TRUE;
 1> name: Administrator;
 1> objectGUID: 613813f4-f8cf-44ba-887b-aae4cb128580;
 1> objectSid: S-1-5-21-980059532-776183279-2334900600-500;
 1> objectCategory: CN=User-Proxy,CN=Schema,CN=Configuration,CN={B57A6E49-957D-434C-8584-9AA3D3946EF0};
 1> sourceObjectGuid: P upy?B$6 ;
 1> lastAgedChange: 20050923175913.0Z;

One of the most commonly made mistakes is forgetting to include objectSID so please do include it! If you don't, you'll get the missing attribute error we have seen before.