IBM Support

Maximo LDAP - VMMSYNC Filtering and Configuration

Technical Blog Post


Abstract

Maximo LDAP - VMMSYNC Filtering and Configuration

Body

There are many confusions and misunderstanding when it comes to LDAP, and about what is and what isn't possible.
I want to take some time to discuss the possibilities for Maximo with LDAP, as well as go over the considerations and configuration of setting up VMMSYNC.
There is a second document with a similar take for LDAPSYNC. Here I want to focus on VMMSYNC. The goal for this document is to be a comprehensive guide for VMMSYNC. I am starting with the basics then going into more details going along.


Topics to be discussed:

  • Overview of VMMSYNC parameters
  • The user synchronization xml.
    • From where do I want the information?
    • Defining the BASEDN
    • Optimally filtering information
  • What information do I want?
    • How to choose attributes
    • Rules for using attributes
    • Using custom attributes
  • Where do I want the information to go?
    • Rules for synced data
    • Keeping synced fields consistent
  • Filtering with VMMSYNC
    • Common attributes to use for filtering
    • Examples of filters and syntax
  • Debugging VMMSYNC
    • Creating its own appender and logger

Overview:
VMMSYNC is a great tool for syncing users to Maximo. It uses WebSphere VMM API to extract user and group information from a specified directory. Since it is pulling the information from WebSphere and not directly from the directory, it comes with benefits (works with almost any directory structure) and disadvantages (limited to WebSphere information). VMMSYNC is the default method for syncing users. It is simpler to use and get working, and with its flexibility, it can be configured to do whatever task is needed.

The crontask has 10 different crontask Parameters.
ChangePolling - Default value is 0 - This property is used to configure the sync to run updates instead of doing a full sync every time.
                 -Documentation on setting this up: https://www.ibm.com/developerworks/community/blogs/a9ba1efe-b731-4317-9724-a181d6155e3a/entry/change_polling_in_maximo_with_vmmsync?lang=en
Credential - The password of the principal user.
GroupMapping - The xml used to choose what groups and group members to sync.
GroupSearchAttribute - This property is the attribute that WebSphere uses to grab groups from the directory. Default value is cn. Recommended keeping as cn unless your directory has change definitions.

  • Example of how it is used by WebSphere to find groups:  
    <wim:controls xsi:type="wim:SearchControl" expression="@xsi:type='Group' and cn='*'">
    . Note the and cn='*' appended to the group filter.

Principal - This property is the user that connects to WebSphere VMM API to get the information. This user does not need directory permissions.
Realm - This property is the name of the Realm of the Federated Repository in WebSphere. This property is best completed correctly. The Realm name can be retrieved from the WebSphere admin console under Global Security -> Configure. It is the Realm name field. If Maximo configured your security, it defaults to ISMRealm. If its the WebSphere default, then it is defaultWIMFileBasedRealm.
SynchAdapter - Class to get user data.
SynchClass - Class to sync user data.
UserMapping - The XML used to choose what users and attributes to sync to maximo.
UserSearchAttribute - This property is the attribute used by WebSphere to define a user. Used to search the directory for this type of user.

  • Example of how it is used by WebSphere to find users:
    <wim:controls xsi:type="wim:SearchControl" expression="@xsi:type='PersonAccount' and uid='*'">.
    Note the appended and uid='*' at the end.

User sync XML:

Let's look at an out of the box VMMSYNC user xml and explain what all of this means.

<?Xml version="1.0" encoding="UTF-8" ?><!DOCTYPE ldapsync SYSTEM "ldapuser.dtd">
<ldapsync><user>
<basedn>DC=test,DC=ibm,DC=com</basedn>
<filter>PersonAccount </filter>
<scope>subtree</scope>
<attributes> 
  <attribute>uid</attribute> 
  <attribute>givenName</attribute>
  <attribute>sn</attribute> 
  <attribute>displayName</attribute> 
  <attribute>street</attribute>
  <attribute>telephoneNumber</attribute>
  <attribute>mail</attribute> 
  <attribute>st</attribute> 
  <attribute>postalCode</attribute>
  <attribute>c</attribute>
  <attribute>l</attribute>
</attributes>
<datamap>
<table name="MAXUSER">
  <keycolumn name="USERID" type="UPPER">uid</keycolumn>
  <column name="LOGINID" type="ALN">uid</column>  
  <column name="PERSONID" type="UPPER">uid</column>                 
</table>
<table name="PERSON">  
  <keycolumn name="PERSONID" type="UPPER">uid</keycolumn>
  <column name="FIRSTNAME" type="ALN">givenName</column>  
  <column name="LASTNAME" type="ALN">sn</column>
  <column name="DISPLAYNAME" type="ALN">displayName</column>
  <column name="ADDRESSLINE1" type="ALN">street</column>  
  <column name="STATEPROVINCE" type="ALN">st</column>
  <column name="CITY" type="ALN">l</column>  
  <column name="POSTALCODE" type="ALN">postalCode</column>
  <column name="COUNTRY" type="ALN">c</column>     
  <column name="STATUSDATE" type="ALN">{:sysdate}</column>            
</table>
<table allowdelete="true" name="PHONE">  
  <keycolumn name="PERSONID" type="UPPER">uid</keycolumn>
  <keycolumn name="TYPE" type="UPPER">{WORK}</keycolumn>  
  <keycolumn name="ISPRIMARY" type="YORN">{1}</keycolumn> 
  <column name="PHONENUM" required="true" type="ALN">telephoneNumber</column> 
</table>

<table allowdelete="true" name="PHONE">  
  <keycolumn name="PERSONID" type="UPPER">uid</keycolumn>
  <keycolumn name="TYPE" type="UPPER">{HOME}</keycolumn>  
  <keycolumn name="ISPRIMARY" type="YORN">{0}</keycolumn>   
<column name="PHONENUM" required="true" type="ALN">telephoneNumber</column> </table> 
<table allowdelete="true" name="EMAIL">  
  <keycolumn name="PERSONID" type="UPPER">uid</keycolumn>
  <keycolumn name="TYPE" type="UPPER">{WORK}</keycolumn>  
  <keycolumn name="ISPRIMARY" type="YORN">{1}</keycolumn> 
  <column name="EMAILADDRESS" required="true" type="ALN">mail</column>
</table>
</datamap></user></ldapsync>




This user mapping can be broken down into three different sections for simplification.
The first is the BASEDN and the filter ->. From where do I want the information?
The second is the attributes ->. What information do I want?
The third is the table mappings ->. Where do I want the information to go?

The out of the box sync has much extra information that isn't necessarily required by Maximo. If you're wondering what can be removed, here is the simplest user sync that can be used:

<?Xml version="1.0" encoding="UTF-8" ?><!DOCTYPE ldapsync SYSTEM "ldapuser.dtd">
<ldapsync><user>
<basedn>DC=test,DC=com</basedn>
<filter>PersonAccount </filter>
<scope>subtree</scope>
<attributes>
<attribute>uid</attribute>
</attributes>
<datamap>
<table name="MAXUSER">
  <keycolumn name="USERID" type="UPPER">uid</keycolumn>
  <column name="LOGINID" type="ALN">uid</column>  
  <column name="PERSONID" type="UPPER">uid</column>                 
</table>
<table name="PERSON">  
  <keycolumn name="PERSONID" type="UPPER">uid</keycolumn>        
</table>
</datamap></user></ldapsync>

From where do I want the information?
The BASEDN is the base domain name of your directory. Since this xml is VMMSYNC, it is important to note that this information does not come directly from the directory, and comes from the Federated Repository in WebSphere.
You can find the BASEDN of your directory by looking under Global Security -> Configure while in the WebSphere Application Server administration console. It is the base entry of the repository. However, the BASEDN can be more specific than the base entry, it cannot be less specific than the base entry. This BASEDN must be a fully qualified domain name and cannot be abbreviated.

Combined with the BASEDN, the filter is the other piece that specifies where you want the information from. While the VMMSYNC offers its own filter to reduce or limit the users pulled in to Maximo, it is also possible to filter the users coming in to WebSphere. In some ways, filtering on the WebSphere side can be easier as it uses a direct LDAP filter and reduces overhead in VMM. The problem with filtering in WebSphere is that in order to change the filter, Maximo, and the WebSphere server must be restarted for the changes to take effect. It is usually recommended to start by putting the largest filter on the WebSphere side, and then select subsets within that larger data set to pull in to Maximo with VMMSYNC. This can help with users that can be scattered across multiple OUs and trees. For example, in WebSphere you can want to filter for the dept engineering, but in Maximo you only want the engineers who are part of the maximousers group. There is no right or wrong way to do the filter, but some ways can be more efficient.

image-20220629121605-1
 

What information do I want?
The attributes define what information you want to pull from the directory. While every directory is different, most directories follow a similar schema and the out of box sync uses some commonly defined attributes to pull in typical user data. So what attributes are there to consider? The main attributes used are the login ID, userid, and person ID. These three attributes do not need to be the same value as the others, but each attribute must be consistent across all tables that are being synced. If you look at the MAXUSER table and the PERSON table in the example, you see that the column person ID is set as uid in both tables. Similarly, this rule is true for all and same-as defined attributes. If I want to sync to a table that has userid, then the userid must be defined the same across all tables. You can have as look as only one attribute or as many attributes as you want to sync to Maximo.

Not all attributes in VMMSYNC are not 1 - 1 with the directory. uid does not exist (usually) in the directory that you are syncing users from. uid in this case is the attribute as it is defined in WebSphere VMM. By default, uid is mapped to sAMAccountName in the directory (again this varies based on directory type). And it is a common mistake when using filters in VMMSYNC to use the wrong attribute since you are pulling from WebSphere and not the directory directly. You can find what PersonAccount is defined as in under Global Security -> Configure -> Repository -> Federated repositories entity types to LDAP object classes mapping (Fig. PersonDef), and the wimconfig.xml in WebSphere. So keep in mind when doing filters for VMMSYNC that uid=sAMAccountName.

If you want to add more attributes, they must be added in WebSphere before they can be synced to Maximo. There are some supported attributes that are part of different entities(I.E. person account, group, org container) in WebSphere that don't always need to be added, however assume that all additional attributes need to be added manually. You can find these under the Admin console -> Global Security -> Configure -> Repository -> Federated repositories property names to LDAP attributes mapping. Note that when adding more attributes, they must be defined in WebSphere as a string in order to be synced to Maximo.

image

(Fig. PersonDef)

Where do I want the information to go?
Now that we have the information we need to get, we can put it where we want it. There are few limitations to putting data into Maximo. All tables must meet table requirements, meaning required fields. The information cannot break business rules, and the information must be a one-step process (for example, you can't put a work order in approved status). As stated previously, the fields must match across all same-as relationships, for example, person ID must be the same for every table. Hardcoding values that you are going to change via another process is also not recommended. Let's say you want to set a user's supervisor to be a specific person, then later you want to do a lookup to see who their supervisor should be, every time the sync runs, it updates this field to be the hardcoded value, and the changes made via the lookup will be overwritten.

When syncing data to fields, have the column type match as close as possible. You can find the column definitions in the application that uses alt-i and then a lookup in Database Configuration. If unsure, you can use ALN. This assumes the datatype isn't YORN and will pass the validation from Maximo.

While keeping person ID is important to be the same across different tables in your sync, you will also want to ensure that login ID matches the login property in WebSphere. Even though you're using LDAP for authentication, Maximo still does its own authorization. This means that when you enter your credentials into the login page, Maximo gets the token from WebSphere, then compare that login ID to its own database in order to grant authorization and know who the user is. If you are syncing the login ID in VMMSYNC as the attribute uid, then the login property in WebSphere (located in the admin console -> Global Security -> Configure -> Repository (Fig. LoginProp). It is under the principal user used to connect to the domain). If you sync mail as your login ID, then the login property for WebSphere should be mail also. Without these being the same, users will not be able to log in. image

Filtering:

The syntax of filtering on VMMSYNC is best determined by what is possible and business needs. The best way to see possible filters is by using examples. The first thing to note is the placement of the single quotation marks before the filter begins and after the filter ends, there is an implicit single quotation mark. Therefore, this means that each filter begins with a ' and ends with a ' and encompassing the filter. Usually the first attribute is PersonAcount, so do not include a single quotation mark before it, and then leave out the closing single quotation mark at the end of your last attribute.
Here are some practical attributes to use, and that uses them in a filter. MemberOf, useraccountcontrol, uid, cn, and mail. Keep in mind that the usersearchattribute defined in the sync also plays a part here. As it is usually uid, all searches mean that the objects in the directory must have a uid (uid in VMM means sAMAccountName in the directory).

First filter is all users who are part of the group maximousers or part of the maximoadminusers group. (Note I've shortcut the full domain name for groups).

<filter>PersonAccount' and memberof='cn=maximousers,ou=etc' or memberof='cn=maximoadminusers,ou=etc</filter>

Second filter is all users who have an email address

<filter>PersonAcount' and mail='*</filter>

Third filter is all users whose common name starts with n and email ends in "@ibm.com."

<filter>PersonAccount' and cn='n*' and mail='*@ibm.com</filter>

Fourth filter is all users whose common name does not start with $

<filter>PersonAccount' and cn!='*$*</filter>

Fifth filter is all users whose name does not start with $, they have an email address and are part of the maximousers group or a part maximoadminusers group.

<filter>PersonAccount' and cn!='*$*' and mail='*' and useraccountcontrol='514' and memberof='cn=maximousers,ou=etc' or memberof='cn=maximoadminusers,ou=etc</filter>

Debugging:

Debugging VMMSYNC is as important as setting it up. Is the sync doing what I want it to be doing? Are all users successfully coming in to Maximo? Are all attributes coming in to Maximo?

A common error seen in the VMMSYNC log is null Error count = 1. This error means that there is an exception coming from the WebSphere WIM process, and requires enabling WIM tracing in order to see the exception (see https://www.ibm.com/docs/en/was/8.5.5?topic=support-logs-trace for enabling this).  
Common resolutions for
null Error count = 1:

  • Populate the RealmName in the VMMSYNC crontask parameters to match what is in WebSphere.
  • Check that all attributes mapped and requested in the Usermapping.xml and Groupmapping.xml exist in the Person or Group (respectively) entity in WebSphere's VMM.
  • Other WIM exceptions that require tracing to see and correct.

As some directories can be large, it means the amount of information being retrieved is also large. Due to this, I would recommend separating out VMMSYNC to its own appender and keeping it in a separate log in order to track any potential problems or failures.

To do this, go to the Logging application in Maximo.
Under Select Action go to Manage Appenders.
In Manage Appenders, select new row, complete the required fields. (Fig. VMMAppend)

image

After creating the appender, under Root Loggers find the crontask logger (not crontaskmgr).
Select crontask and in the bottom section under Loggers, select new row.
Complete the required fields. (Fig. VMMLog)

image

I hope you've found this helpful in setting up VMMSYNC. If there is clarification needed on how something works or something you would like to recommend being added, let us know through a support case.

[{"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SSLKT6","label":"IBM Maximo Asset Management"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB59","label":"Sustainability Software"}}]

UID

ibm11114011