Showing posts with label DSML. Show all posts
Showing posts with label DSML. Show all posts

Friday, January 13, 2012

Sun One Boolean Attributes

Recently while working with the Sun One MA, I came across a problem caused by how FIM interprets boolean data coming from the directory.  In this case, the Sun One directory stores its boolean data as “YES” or “NO”, however when imported by FIM, this data always gets converted to False in the connector space.  (http://social.technet.microsoft.com/Forums/en-US/identitylifecyclemanager/thread/8ffc112e-d945-4916-83b3-78fbba716705)

Now we can’t use an advance import flow to correctly convert the data as it comes into the Metaverse because we have already lost data integrity.  The data that’s in the connector space is basically useless.  This only leaves us with a couple of options, we can write an XMA to correctly handle the data, but this can be fairly complicated.  We can also update the directory schema and use a string instead of a boolean, however, this could cause other downstream issues with other systems that might be consuming this data.  There is one other option, but its completely unsupported.  You could update the FIM database to make the system think this attribute is a string. 

Begin by running the following SQL Statement using the SQL Server Management Studio against your FIM database:

SELECT CAST(ma_schema_xml AS XML)   
  FROM FIMSynchronizationService.dbo.mms_management_agent
 WHERE ma_name = '<Sun One MA Name Here>'

In the results window you will get a single record that can be clicked on to open an xml document containing the schema for your Sun MA. Each attribute in the directory will appear using this syntax:

<attribute-type id="system_assigned_id" single-value="true/false">
     <name>attribute_name</name>
     <syntax>LDAPv3_syntax_oid</syntax>
</attribute-type>

If you do a quick search (Ctrl+F) for your attribute, you can manually update the LDAP Syntax OID from a boolean (1.3.6.1.4.1.1466.115.121.1.7) to a string (1.3.6.1.4.1.1466.115.121.1.15).  In my case, the new XML looked like:

<attribute-type id="Ah" single-value="true">
     <name>isManager</name>
     <syntax>1.3.6.1.4.1.1466.115.121.1.15</syntax>
</attribute-type>

I then used an update statement to write this information back to the database.  After performing a full import on this MA the connector space now reflected this data as a string of “YES” or “NO” just as it appears in the directory.  Now that the connector space had data I could work with, I wrote a quick advanced import flow rule to transform this value to a boolean:

case "isManager":

   //perform conversion for isManager from yes/no to boolean value
   if (csentry["isManager"].IsPresent)
   {
      if (csentry["isManager"].Value.Equals("yes", StringComparison.InvariantCultureIgnoreCase))
      {
         mventry["isManager"].BooleanValue = true;
      }
      else
      {
         mventry["isManager"].BooleanValue = false;
      }
   }
   break;

This approach does have its risks.  It will need to be re-done after performing a schema refresh in FIM and there is no guarantee it will keep working after an upgrade/patch.   The following SQL query could be used to script out this update, just replace the attributeName and SunOneMA variables and you should be good to go:

DECLARE @attributeName AS Varchar(255) = '<Attribute Name Here>'
DECLARE @SunOneMA AS Varchar(255) = '<Sun One MA Name Here>'
DECLARE @newSchemaOID AS Varchar(255) = '1.3.6.1.4.1.1466.115.121.1.15' --Directory String

-- get schema data
DECLARE @schema AS XML

SELECT @schema = CAST(ma_schema_xml as xml)
  FROM FIMSynchronizationService.dbo.mms_management_agent
 WHERE ma_name = @SunOneMA

-- update schema type
SET @schema.modify('
   declare default element namespace http://www.dsml.org/DSML;
   replace value of
      (dsml/directory-schema/attribute-type[name=sql:variable("@attributeName")]/syntax/text())[1]
   with
      sql:variable("@newSchemaOID")
   ')

-- save back to table
UPDATE FIMSynchronizationService.dbo.mms_management_agent
   SET ma_schema_xml = CONVERT(nvarchar(MAX), @schema)
 WHERE ma_name = @SunOneMA

Friday, April 22, 2011

File Based Management Agents In MIIS/ILM/FIM

I had a recent need to really compare the capabilities of each of the file based Management Agents in FIM.  Can you name all five? Don't worry, I won't leave you hanging, they are:

  • Attribute-value pair text file
  • Delimited text file
  • Directory Services Markup Language (DSML) 2.0
  • Fixed-width text file
  • LDAP Data Interchange Format (LDIF)

Here are some of the things that they can and can't do (this is for you Joe) and just for kicks, I also added in the SQL MA. If you are using one of these file types in an Extensible Management Agent (XMA), the following still applies: 

 

Multi-valued Attributes

Attribute Level Updates 1

Multi-valued Level Attribute Updates 2

Attribute-value pair

YES

NO

NO

Delimited

YES 3

NO

NO

DSML

YES

NO 4

NO

Fixed-width

YES 3

NO

NO

LDIF

YES

YES

ON IMPORT ONLY 5

SQL MA

YES

YES

NO 6



Okay, now for the caveats (can’t get away without some of those):

  1. An Attribute Level Update implies that a delta import can contain only the attribute that has changed (along with the other required columns, like the type of change and the anchor)

    So, here’s what that might look like.  Suppose I have a user with the following attributes:
      ID: 12345
      Name: Sarah
      Status: Active
      Phone: 555-123-4567
                                         
    If Sarah’s phone number changes to 555-987-6543, I can simply tell FIM something like: 
      ID: 12345 
      Type Of Change: Update
      Phone: 555-987-6543

    This has the advantage of giving FIM less work to do to determine what has changed on the records being imported and greatly speeds up delta imports. 
     
  2. A Multi-valued Level Attribute Update supports adding and deleting specific values from a multi-valued attribute
     
    Let’s take another look at Sara’s record:
      ID: 12345 
      Name: Sarah 
      Status: Active 
      Phone: 555-123-4567
      Phone: 555-456-7890
                                          
    Now, Sarah has two Phone numbers, or a single attribute with multiple values. With multi-value level attribute update support, we can do things like add a new phone number to the list, delete a phone number from the list or update a phone number (in essence by doing an add of the new value and then a delete of the old one):
      ID: 12345 
      Type Of Change: Add
      Phone: 555-987-6543

    Without this support, the source system would be required to do a “replace” action and provide FIM with all of the current values at the time of import which FIM will use to override all the values that it has for that attribute.  So if we start with Sarah’s record as listed just above and add the phone number 555-987-6543 and remove the phone number 555-123-4567, we would have to pass:
      ID: 12345 
      Type Of Change: Replace
      Phone: 555-987-6543
      Phone: 555-4567-7890

    As with attribute level updates, multi-valued level attribute update can greatly reduce the amount of work that FIM needs to accomplish.  To illustrate, just imagine applying this scenario to attributes like member on an AD group that can have thousands of values.
     
  3. Using a multi-valued attribute in a delimited or fixed-width file requires the use of a header on the import file

    So for a comma delimited file this would look like: 
                                           ID, NAME, PHONE, PHONE, PHONE
                                           12345, Sarah, 555-123-4567, 555-987-6543, 555-456-7890

    This would import a record for Sarah with three attributes - ID, NAME and PHONE, the last of which will have three values. A fixed width file would work the same way.
     
  4. While the DSML specifications themselves can actually handle attribute level updates using the addRequest, delRequest and modifyRequest operations, FIM only implements the ability to import a SearchResultEntry element which must contain all of the attributes on the object

    Just a side note for those that might be curious, you can actually place the addRequest, delRequest and modifyRequest nodes in the DSML file.  FIM will be able to parse the file and it wont cause any errors, however these elements are completely ignored and aren’t processed by FIM.  I also tried sending a DSML delta to FIM with just the attribute that changed and a change type of “modify”, and I suppose not surprisingly, the object in the connector space was updated so that it only had the one attribute I specified,  all the other attributes originally on the object were removed. Had any of these attributes been defined as required, this update would have failed.
     
  5. While you can import an update to a specific value in a multi-valued attribute, if you were to export this same change to an LDIF file, it will come through as a replace operation containing all values now present on the attribute
     
  6. While the SQL MA does not support updates to a specific value on a multi-valued attribute out of the box, I hear rumor that some customizations can be done to make this happen