Jorge's Quest For Knowledge!

All You Need To Know About Identity And Security On-Premises And In The Cloud. It's Just Like An Addiction, The More You Have, The More You Want To Have!

(2010-07-29) Managing The userAccountControl Attribute In AD By FIM

Posted by Jorge on 2010-07-29


If you are using some system manage Identities in AD and you are either using ILM 2007 FP1 or FIM 2010 you may need to configure the ILM/FIM Sync Engine to act on the AccountStatus value and translate that to the userAccountControl value in AD.

So…

If employeeStatus = ‘Enabled’ then the AD user account must be enabled, or in technical terms userAccountControl bit 1 (2nd bit) (2^1=2) must be disabled.

If employeeStatus = ‘Disabled’ then the AD user account must be disabled, or in technical terms userAccountControl bit 1 (2nd bit) (2^1=2) must be enabled.

If you want to do this using classic flow rules, then you need to the following:

The attribute "employeeStatus" must be available as a string attribute in the Metaverse. The attribute "userAccountControl" must be selected to be imported from AD.

In the AD MA you also need an advanced export attribute flow (MV:employeStatus –> CD:userAccountControl). For the flowrulename you can use anything you like. I prefer to make it as clear as possible to what happens, so I call it "generate-userAccountControl(CS)".

In the Rules Extension Project for the MA you need to add the following:

Imports ActiveDs '<-- requires a reference added to the project! Public Sub MapAttributesForExport(ByVal FlowRuleName As String, ByVal mventry As MVEntry, ByVal csentry As CSEntry) Implements IMASynchronization.MapAttributesForExport Select Case FlowRuleName Case "generate-userAccountControl(CS)" If mventry("employeeStatus").IsPresent Then Dim currentUACValue As Long Dim newUACValue As Long If csentry("userAccountControl").IsPresent Then currentUACValue = csentry("userAccountControl").IntegerValue And (Not ADS_USER_FLAG.ADS_UF_PASSWD_NOTREQD) Else currentUACValue = ADS_USER_FLAG.ADS_UF_NORMAL_ACCOUNT And (Not ADS_USER_FLAG.ADS_UF_PASSWD_NOTREQD) End If Select Case mventry("employeeStatus").Value.ToLower Case "enabled" newUACValue = (currentUACValue Or ADS_USER_FLAG.ADS_UF_NORMAL_ACCOUNT) And (Not ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE) Case "disabled" newUACValue = currentUACValue Or ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE End Select csentry("userAccountControl").IntegerValue = newUACValue End If

If you want to do this using declarative flow rules (Sync Rules), then you need to the following:

The attribute "employeeStatus" must be available as a string attribute in the Metaverse. The attribute "userAccountControl" must be selected to be imported from AD. The attribute "userAccountControl" must be available as a number attribute in the Metaverse.

In the Portal Portal you need an Inbound Sync Rule for the AD MA.

SOURCE = userAccountControl

TARGET = userAccountControl

In the Portal Portal you need an Outbound Sync Rule for the AD MA.

For the INITIAL FLOW in the outbound sync rule you can use the following:

SOURCE = IIF(Eq(employeeStatus,"Enabled"),512,514)

To make more readable…

IIF(

        Eq(employeeStatus,"Enabled"),

        512,

        514

    )

TARGET = userAccountControl

For the PERSISTENT FLOW in the outbound sync rule you can use the following:

SOURCE = IIF(Eq(employeeStatus,"Enabled"),IIF(IsPresent(userAccountControl),BitAnd(33554397,userAccountControl),512),IIF(IsPresent(userAccountControl),BitOr(2,userAccountControl),514))

To make more readable…

IIF(

            Eq(employeeStatus,"Enabled"),

            IIF(

                IsPresent(userAccountControl),

                BitAnd(33554397,userAccountControl),

                512

),

            IIF(

                IsPresent(userAccountControl),

                BitOr(2,userAccountControl),

                514

            )

    )

TARGET = userAccountControl

Cheers,

Jorge

———————————————————————————————

* This posting is provided "AS IS" with no warranties and confers no rights!

* Always evaluate/test yourself before using/implementing this!

* DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/

———————————————————————————————

############### Jorge’s Quest For Knowledge #############

######### http://JorgeQuestForKnowledge.wordpress.com/ ########

———————————————————————————————

4 Responses to “(2010-07-29) Managing The userAccountControl Attribute In AD By FIM”

  1. Reshma said

    Hi Jorge,

    I have implemented the above functionality using flow rules…however the function MapAttributesForExport is not getting invoked. On debugging it through Visual Studio I realized that the initialize function is also not called.
    I am not sure what setting I have missed since I am new to FIM, Can you please help…

    Thanks and Regards,
    Reshma

  2. Guy Horn said

    Hallo. This is very helpful. I actually use a variation of your code combined with a sample from Kent Nordstrom’s book. I have some remarks and questions.

    The difference is that Kent is using a Boolean attribute. His custom expression is shorter. E.g. ‘IIF(,true,false)’. I named the control attribute _active. You used employeeStatus.

    Q1. Is there any special reason for you to use a string type attribute?

    Further you use the mask 33554397 that enables you to flip the 2e and 6e bit. In my case I need to set ‘password never expires’ and I used Kent’s mask. This mask only enables to flip the second bit. I choose that mask because it only manage the bit I intend to. Actually I looked it up and found that by flipping the 6e bit you force ‘password is not required = false’ (PASSWD_NOTREQD). See reference from https://support.microsoft.com/kb/305144. This feature is not documented in your post.

    Q2. Why did you choose this mask?

    If you want to mask 25 bits and flip only the 2e you should use 33554429 as mask.

    My custom expression is:
    IIF(_active,IIF(IsPresent(userAccountControl),BitAnd(9223372036854775805,userAccountControl),66048),IIF(IsPresent(userAccountControl),BitOr(2,userAccountControl),66050))

    Greetings, Guy

    • Jorge said

      A1: I use employeeStatus because I look at it from a person perspective, not an account perspective.
      EmployeeStatus could be Active, InActive, Terminated, OnLeave, etc
      Any value can then be translated into enabled or disabled

      A2: I want to forcibly configure an account where the bit PASSWD_NOTREQD is not enabled. If it is enabled an account does not require a pwd

  3. […] initially looking at exporting userAccountControl values to AD, I used Jorge’s code snippet: https://jorgequestforknowledge.wordpress.com/2010/07/29/managing-the-useraccountcontrol-attribute-in… as the basis for my code. Initially, I had some difficulty understanding the differences between […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: