Build new adapters for IBM Security Identity Manager

Use IBM Tivoli Directory Integrator to develop a simulated LDAP server adapter

Build an LDAP server adapter for IBM Security Identity Manager, then use it to provision user accounts on a test service. You'll need a new adapter anytime you want to connect IBM Security Identity Manager with an unsupported application or service, including custom applications. In this article, get step-by-step instructions for building a simulated LDAP server adapter with IBM Tivoli Directory Integrator. After you've got your new LDAP server adapter up and running, practice using it to add, reconcile, delete, and modify user accounts between IBM Security Identity Manager and a test service.

Ori Pomerantz (orip@us.ibm.com), Technical Enablement Specialist, IBM

Photo of Ori PomerantzOri Pomerantz has been securing computer networks and teaching other people how he does it since 1995. Since joining IBM in 2003, he has written and taught classes on several IBM Security products, including IBM Security Identity Manager.



04 November 2013

Gartner Magic Quadrant for SIEM

IBM has been positioned again in the Leaders quadrant of the Gartner Magic Quadrant for Security Information and Event Management. Learn more about the evaluation of IBM's offerings by downloading the "2013 Gartner Magic Quadrant for SIEM."

An adapter is the component that connects IBM Security Identity Manager to the systems that it manages. As a developer or administrator, you might need to write an adapter to connect IBM Security Identity Manager with an unsupported application or service, such as a custom application. You could then use IBM Security Identity Manager to provision, modify, de-provision, and list existing accounts on that system.

In this article, I introduce a simple technique for building adapters. Using IBM Tivoli Directory Integrator, I walk through the process of configuring an adapter as an LDAP server, which is then used to add, reconcile, modify, and delete new user accounts with IBM Security Identity Manager.

To follow the exercises in this article you should have prior experience using IBM Security Identity Manager and IBM Tivoli Directory Integrator. You should also be familiar with the Lightweight Directory Access Protocol and basic JavaScript programming.

Building adapters

There are several ways to implement new adapters for use in IBM Security Identity Manager:

  1. You could build an adapter in Java™ code by writing classes that implement the interface com.ibm.itim.remoteservices.provider.ServiceProviderFactory. See the /opt/IBM/isim/extensions/6.0/examples/serviceprovider/Readme.html on any computer that runs IBM Security Identity Manager to learn more about this approach.
  2. You could use the IBM Adapter Development Tool (ADT), which is available from the IBM Open Process Automation Library (see Resources for a link).
  3. You could use IBM Tivoli Directory Integrator to simulate an LDAP server implementation. LDAP servers are made to handle account information, so they support all of the functions required for an adapter.

The demonstrations in this article are based on an LDAP server implementation. If you do not already have IBM Security Identity Manager set up in your development or administration environment, see Resources to download and install it now.


The LDAP server adapter

The demonstration adapter for this article works as an LDAP server implemented in IBM Tivoli Directory Integrator. Figure 1 shows the data flow schematic for this type of adapter.

Figure 1. Data flow schematic
A data flow schematic for an LDAP server adapter implementation.

Requests are generated in IBM Security Identity Manager, which runs as an application inside IBM WebSphere Application Server. These requests are sent to the remote method invocation (RMI) dispatcher, which is an AssemblyLine running inside IBM Tivoli Directory Integrator. The process starts when you issue ITIMAd start from the command line. Note that this data flow is the same as the data flow used in other agentless adapters, such as the Linux® adapter or the IBM Security Access Manager adapter.

The RMI dispatcher then communicates with the LDAP server, which is actually your AssemblyLine running in a separate IBM Tivoli Directory Integrator instance, using LDAP. This AssemblyLine provisions, modifies, and deletes accounts on the managed system, using any of IBM Tivoli Directory Integrator's many connectors.

Create an LDAP server AssemblyLine

The first step to creating a new adapter skeleton is to configure the LDAP server AssemblyLine, which I'll do as follows:

  1. Run IBM Tivoli Directory Integrator as shown in the following code (make sure it uses a different API port from the RMI dispatcher, ITIMAd):
    /opt/IBM/TDI/V7.1.1/ibmditk &
  2. Select Create Tivoli Directory Integrator Project.
  3. Name the project LDAPServerAdapter.
  4. Right-click LDAPServer Project > AssemblyLines and select New AssemblyLine.
  5. Name the new AssemblyLine LDAPListener.
  6. Click Add component. Create an LDAP Server Connector connector in Server mode. Click Next.
  7. Select a port that is not currently in use, for example, 12345.
  8. Click Finish.
  9. In the Input Map tab, select all the attributes.
  10. Add a script that dumps the work entry.
  11. Start your new AssemblyLine.

Create a test service

Next, I'll create a test service for the adapter. I'll then be able to use the test service to add, modify, and delete user accounts.

  1. Log on to IBM Security Identity Manager as an administrative user.
  2. Create an LDAP profile service with the attributes shown in Table 1.
Table 1. Attributes for the LDAP profile service
AttributeValue
Service nameTestService
Directory server locationldap://localhost:12345
Administrator namecn=root
Passwordwhatever

Note: The directory server location should be the host name and port needed to get to your LDAP server.

  1. Click Test Connection. It will fail, but see that the requests are relayed to the IBM Tivoli Directory Integrator console, as shown in Figure 2.
    Figure 2. Requests from test connection
    A screenshot of a request in the IBM Tivoli Directory Integrator console.
  2. Click Next.
  3. Specify the user base DN as ou=users, and group base DN as ou=groups.
  4. Click Finish.

That's it. You've built your new adapter as an LDAP server implementation, it just doesn't do anything yet. In the next sections, I'll run through some exercises using your adapter to add, reconcile, delete, and modify user accounts between your IBM Security Identity Manager and a target system.


The add request

The easiest LDAP server request to implement is the add request. I'll start by adding a new user account to the test service, then I'll create a branch for new requests.

Attempt to request an account for a user on the new service. The work object created by the request should be similar to the window in Figure 3.

Figure 3. Making an add request in the TestService
A screenshot of an add request in the test service.

You should see in the IBM Security Identity Manager console that, despite the lack of response, the request is considered to be successful.

Switch elements

A switch element allows the AssemblyLine to run different branches depending on the value of an attribute of the work object. The switch element defines the attribute, and the case elements within it define the values that cause different branches to run. This is similar to the switch statement in C-derived languages such as JavaScript.

Next, try adding a branch for add requests:

  1. Stop the AssemblyLine in IBM Tivoli Directory Integrator.
  2. Add a switch based on a work attribute and select ldap.operation, as follows:
    • Click Add component.
    • Select Switch, leave the default name, and click Finish.
    • Select Work Attribute.
    • Select the attribute ldap.operation.
  3. Add a case for add (click the Add Case component, type add, and click OK).
  4. Within the case, add an AttributeMap.
  5. Add the mappings in Table 2 to read the uid, sn, and cn values from the LDAP request.
    Table 2. Variables for the attribute map
    Work attributeAssignment
    cnwork["ldap.entry"].getValue(0).cn
    snwork["ldap.entry"].getValue(0).sn
    uidwork["ldap.entry"].getValue(0).uid
  6. Now drag the SWITCH component above the DumpWorkEntry component, as shown in Figure 4.
    Figure 4. AssemblyLine with the add operation
    A screenshot of the AssemblyLine with the add operation.
  7. Run the AssemblyLine.
  8. Now run the following command to add an entry. Be sure to type an empty line at the end of the entry. Use Ctrl-C to quit.
    ldapadd -h localhost -p 12345 -x
    dn: uid=test,ou=users
    uid: test
    sn: Est
    cn: Tom Est
    objectClass: inetOrgPerson

    Why use the command-line?

    Note that we use ldapadd to add an entry rather than creating a new user in IBM Security Identity Manager. Restarting the LDAP server in IBM Tivoli Directory Integrator could cause a delay of a few minutes in adding new users, which would be a challenge during development.

  9. See that the new entry includes the uid, sn, and cn, as shown in Figure 5.
    Figure 5. Entry with attributes from LDAP
    A screenshot of the new entry with attributes from LDAP.

Adding new entries to a database

Next I'll create a database table and add entries to it. Before I can add new entries to the DB2 table, I'll need to create it.

  1. Run the following command to create the table:
    db2
    CREATE DATABASE adapter
    CONNECT TO adapter
    CREATE TABLE accts(uid VARCHAR(10), cn VARCHAR(30))
    quit
  2. Click Add Component in the CASE: add branch.
  3. Select Database Connector (JDBC), name the connector addEntry, set the mode to AddOnly, and click Finish.
  4. Drag the new connector after the attribute map, as shown in Figure 6.
    Figure 6. The AssemblyLine with addEntry
    A screenshot of the AssemblyLine with addEntry
  5. Click the connector's Connection tab.
  6. Select the database type, DB2.
  7. Type the host name localhost (or the server where you run DB2), the port number (typically, 50000), and the database name, adapter. (If the port is wrong, use grep db2 /etc/services to see the port numbers used by DB2 on the given system.)
  8. Type the user credentials for the database (for example, root and object00).
  9. Click Select to get the list of database tables and select ACCTS.
  10. Click the Output Map tab.
  11. Click Connect. The schema attributes should appear.
  12. Click Add and map work.cn to cn and work.uid to uid. (Note that case doesn't matter in these instances: work.CN is the same as work.cn.)

You've configured the database adapter. Now test it by adding a new account:

  1. Run the AssemblyLine.
  2. Attempt to provision an account to TestService in IBM Security Identity Manager.
  3. See the request in the IBM Tivoli Directory Integrator console log.
  4. Run the following commands to verify that the account was added to the database:
    db2 CONNECT TO adapter
    db SELECT cn,uid FROM accts
  5. You should see the output shown in Figure 7.
    Figure 7. Users added to the database
    Output from adding new users to the database.

Reconciliation

Reconciliation is the process of ensuring that user accounts in a service match the account record in IBM Security Identity Manager. For reconciliation to work, the service must be able to respond to search requests.

Start by attempting to run a reconciliation with your test service. It will fail, but you will see the search requests that must be handled for the reconciliation to work. The attempt results in the three search requests shown in the following windows:

Figure 8. User search
A screenshot of a user search.
Figure 9. Organizational unit search
A screenshot of an organizational user search.
Figure 10. Group search
A screenshot of a group search.

The test service must be able to respond to the user search request with results. For the other two requests I can send an empty reply.

The search branch

The first thing I need to do is create a search branch, as follows:

  1. Stop the AssemblyLine in IBM Tivoli Directory Integrator.
  2. Add a case for search in SWITCH: {work.ldap.operation}.
  3. Within the case of search, add an IF component.
  4. Set the condition as shown in Table 3 and Figure 11:
    Table 3. Branch attributes
    AttributeNotOperatorValueCase sensitive
    ldap.searchfilterClearequals(objectclass=inetOrgPerson)Clear
    Figure 11. Condition for the search branch
    A screenshot of the condition for the search branch.
  5. Within the branch, create a Connector Loop. Call it forEachUser.
  6. Within the loop, create a script to send user information back to the LDAP client. The AssemblyLine should now look like the screen capture shown in Figure 12.
    Figure 12. AssemblyLine with add and search operations
    A screenshot of the AssemblyLine with add and search operations.

Next I'll create a loop to iterate over the users in the database. Many of the steps here are the same as the ones I followed to connect the database to the add branch earlier.

  1. Select the FOR-EACH forEachUser component, which appears in the AssemblyLine.
  2. Click ibmdi.FileSystem to change the inheritance to Database Connector (JDBC).
  3. Click the Connection tab.
  4. Select the database type of DB2.
  5. Type the host name localhost (or use the server where you run DB2), the port number 50000, and the database adapter. (If the port is wrong, use grep db2 /etc/services to see the port numbers used by DB2 on the database system.)
  6. Type the user credentials for the database (for example, root and object00).
  7. Click Select to get the list of database tables and select ACCTS.
  8. Click the Input Map tab.
  9. Click Connect.
  10. Drag CN and UID to the work entry area.

Finally, I'll use a script to send users to the LDAP server connector.

Modify the script inside the FOR-EACH component by specifying the script in Listing 1.

Listing 1. Script inside the FOR-EACH loop
// Create a new Entry object. This is the same class as the work and conn
// objects of IBM Tivoli Directory Integrator
usr = new com.ibm.di.entry.Entry();

// Add the attribute for the distinguished name, $dn
usr.addAttributeValue("$dn", "uid=" + work.uid + ",ou=users");

// To create a multi-value attribute, such as objectClass, add several
// attribute values to the same attribute name
usr.addAttributeValue("objectClass", "inetOrgPerson");
usr.addAttributeValue("objectClass", "organizationalPerson");
usr.addAttributeValue("objectClass", "person");
usr.addAttributeValue("objectClass", "top");
usr.addAttributeValue("sn", "Not Implemented");
usr.addAttributeValue("cn", work.cn);
usr.addAttributeValue("uid", work.uid);

// The userpassword attribute is necessary to mark the account as
// active rather than suspended
usr.addAttributeValue("userpassword", "active");

// Send the finished Entry to the LDAP Server connector, 
// LDAPServerConnector
LDAPServerConnector.getConnector().putEntry(usr);

Test the search operation

I'll conclude with a reconciliation to test the search function.

  1. Run the following command to create a few more accounts to reconcile:
    db2
    CONNECT TO adapter
    INSERT INTO accts(uid,cn) VALUES ('test','Tom Est')
    INSERT INTO accts(uid,cn) VALUES ('jdoe','Jane Doe')
    quit
  2. Run the AssemblyLine.
  3. Run ldapsearch and see that you get all the users. Type the following command all on one line:
    ldapsearch -x -h localhost -p 12345 objectclass=inetOrgPerson
  4. Run ldapsearch again with a different filter; note that you do not get any results.
  5. Now try to run a full reconciliation and see that it works.

The delete request

In this section, I'll investigate delete requests between IBM Security Identity Manager and the AssemblyLine. As you'll discover, there's more to deleting a user account than simply issuing the request.

Start by deleting an account using IBM Security Identity Manager. The request will fail on the test service, resulting in the error message shown in Figure 13.

Figure 13. Deletion failed
A screenshot of an error message.

Let's investigate what happened. First, check the AssemblyLine's console log to see that IBM Security Identity Manager attempted to verify the account:

Figure 14. Request to verify the account
A screenshot of the AssemblyLine's console log.

As you can see, the previous request uses the filter (&(uid=<user id>)(objectclass=inetorperson)).

Note that the AssemblyLine must be able to respond to this kind of individual search request before IBM Security Identity Manager can even try to issue the delete request.

Responding to individual search requests

To respond to individual search requests, use a regular expression to find those requests that contain (uid=<uid>) conditions.

  1. Within the CASE: search, create an ELSE-IF component.
  2. Create the condition shown in Table 4:
    Table 4. Condition to identify requests for individual entries
    AttributeNotOperatorValueCase sensitive
    ldap.searchfilterClearcontains(uid=Selected
  3. Create an attribute map within the ELSE-IF branch. Within that attribute map, create an attribute uid whose value is calculated using the script in Listing 2.
    Listing 2. The UID attribute in a filter
    // This is to identify the UID in filters of the type
    // (&(uid=<UID>)(objectclass=inetorgperson))
    
    // Convert the attribute ldap.searchfilter to a string.
    // The simple notation work.ldap.searchfilter does not
    // work here because it would look for the ldap attribute
    // in the work object, which does not exist.
    var filter = work["ldap.searchfilter"].toString();
    
    // Remove everything prior to the UID
    var nohead = filter.replace(/.*uid=/, "");
    
    // The UID will always be followed by a close parenthesis.
    // Remove it and everything after it.
    var notail = nohead.replace(/\).*/, "");
    
    return notail;
  4. Create a new connector below the attribute map with the following parameters:
    Table 5. Attributes for the new connector
    AttributeValue
    Component nameDatabase Connector (JDBC)
    NamereadUser
    ModeLookup
    Database typeDB2
    Hostnamelocalhost1
    Port50000
    Databaseadapter
    UsernameExample: root
    PasswordExample: object00
    Table nameACCTS
    Note that Table 5 shows the values on my system. Enter the data for your database server, port number, and account.
  5. Next, make sure that the connector is in the correct location:
    Figure 15. Database lookup connector in the AssemblyLine
    A screenshot showing the database lookup connector in the AssemblyLine.
  6. Click the connector's Input Map tab.
  7. Click Connect to verify the database configuration and read the schema.
  8. Drag CN into the work attributes area.
  9. Click the Link Criteria tab.
  10. Create the following criterion:
    UID equals $uid
  11. Now open the Hooks tab.
  12. Select DataFlow (Lookup) > Lookup > On No Match.
  13. Type the following script to send an empty response in the case of no match:
    LDAPServerConnector.reply(new com.ibm.di.entry.Entry());
  14. Copy sendUser and paste it into the new branch:
    Figure 16. The AssemblyLine with the sendUser script in two places
    A screenshot of the AssemblyLine with the sendUser script in two places.
  15. Run the AssemblyLine.
  16. Search for user information from the command line:
    ldapsearch -x -h localhost -p 12345 uid=jdoe

Now attempt to delete an account again. As you can see in Figure 17 and Figure 18, there are still two unhandled requests:

Figure 17. A new delete request
A screenshot of the new delete request.
Figure 18. Search for groups that contain the deleted account
A screenshot of a search for groups that contain the deleted account.

Handling delete requests

The next step is to handle the delete request you saw in Figure 17.

  1. Click SWITCH: {work.ldap.operation}.
  2. Click Add Case components and add delete.
  3. Create an attribute map within the CASE: delete branch. Within that attribute map, create an attribute uid whose value is calculated using the script in Listing 3.
    Listing 3. The CASE: delete branch
    // Convert the attribute ldap.dn to a string.
    var dn = work["ldap.dn"][0].toString();
    
    // Remove everything prior to the UID
    var nohead = dn.replace(/uid=/, "");
    
    // The UID will always be followed by a comma.
    // Remove it and everything after it.
    var notail = nohead.replace(/,ou=users/, "");
    
    return notail;
  4. Right-click ReadUser and select Re-use connector.
  5. Name the new connector DeleteUser.
  6. Drag DeleteUser into the CASE: delete branch, below the attribute map.
  7. Click DeleteUser and change the mode to Delete. Figure 19 shows how the AssemblyLine should now look:
    Figure 19. AssemblyLine with the new delete operation
    A screenshot of the AssemblyLine with the new delete operation.
  8. Run the AssemblyLine.
  9. Use the following commands to see the list of users in the database:
    db2 connect to adapter
    db2 select cn,uid from accts
  10. Delete an account in IBM Security Identity Manager.
  11. Check to see that the account was actually deleted:
    db2 select cn,uid from accts

The modify request

In this section I'll add the necessary components to the AssemblyLine to implement modify requests.

  1. Attempt to modify the full name (cn) of an account. As you can see, there are two requests. The first is a search for user information, which I've already handled. The second is the modify request itself, shown in Figure 20.
    Figure 20. The modify request
    A screenshot of the modify request.
  2. Create a modify branch using the same procedure you used to create the previous branches.
  3. The mechanism to get the UID from the DN is the same as in the delete branch. Right-click the attribute map to copy it, then paste it into the modify branch.
  4. Create the new script shown in Listing 4, called getLDAPAttrs.
    Listing 4. getLDAPAttrs
    // The ldap.entry attribute always has one child, which is itself an Entry
    // object.
    var value = work["ldap.entry"].getFirstChild().getValue();
    
    // The attribute names of that Entry are the attributes that are being 
    // modified.
    var attrnames = value.getAttributeNames();
    
    for (i = 0; i < attrnames.length; i++) {
            var attr = value.getAttribute(attrnames[i]);
            var attrName = attr.getName();
            task.logmsg(attrName);
            for (j = 0; j < attr.size(); j+=2) {
            
                    // The attribute values are in pairs. The first
                    // item in the air is the operation (add, delete, and
                    // so on) and the second is the value on which the
                    // operation is applied.
                    var oper = attr.getValue(j);
                    var val = attr.getValue(j+1)
                    task.logmsg("\t" + oper + "->" + val);
                    
                    // The values that are added are the relevant ones
                    if (oper == "add") {
                            work.addAttributeValue(attrName, val);
                    }
            }
    }
  5. Reuse the deleteUser connector, call the copy modifyUser, drag it to the bottom of the modify branch and change the mode to Update. The AssemblyLine should now look as shown in Figure 21.
    Figure 21. AssemblyLine with the modify branch
    A screenshot of the AssemblyLine with the modify branch.
  6. Click the modifyUser connector's Output Map.
  7. Click Add and select the cn attribute.
  8. Run the AssemblyLine and attempt to modify the full name of an account on the test service. See that the change propagates to the database.

Modify the user form

So far, I've been using the standard LDAP user form. However, a more user-friendly system would only show the fields that I am actually using, and would label them as appropriate for the given service type. In this section, you'll learn how to modify a user form for a given service type.

The first step is to create a new service type:

  1. Create a new directory and change to the new directory.
    mkdir ~/new_adapter
    cd ~/new_adapter
  2. Open the LDAP adapter as shown:
    jar xvf /opt/IBM/isim/config/adapters/LdapProfile.jar
  3. Rename the directory with the following profile information:
    mv LdapProfile TestProfile
  4. Rename the user form:
    mv TestProfile/erLDAPUserAccount.xml \
    TestProfile/erTestUserAccount.xml
  5. Now edit the TestProfile/service.def file as follows:
    • On line 3, change the name from LdapProfile to TestProfile
    • On line 5, change the profile from LdapProfile to TestProfile
    • On line 11, change the name from erLDAPUserAccount to erTestAccount
    • On line 12, change the profile from LdapAccount to TestAccount
    • On line 16, change the location from erLDAPUserAccount.xml to erTestUserAccount.xml
  6. Edit the TestProfile/schema.dsml file:
    • On line 356, change the name from erLDAPUserAccount to erTestAccount.
  7. Edit the TestProfile/CustomLabels.properties file:
    • Change line 16 to TestAccount=Test Account
    • Change line 18 to TestProfile=Test Profile
  8. Create a new service definition file:
    jar cvf TestProfile.jar TestProfile/
  9. In the IBM Security Identity Manager user interface, click Configure System > Manage Service Types. Then, click Import and import the new service definition file: ~/new_adapter/TestProfile.jar.
  10. Wait a few minutes for the new profile to be installed. After it is installed, you will see it in your IBM Security Identity Manager administrative interface, as shown in Figure 22:
    Figure 22. The new profile is installed
    A screenshot of the new profile in the IBM Security Identity Manager administrative interface.

Now I can modify the user form.

  1. Click Configure System > Design Forms.
  2. Click Account > Test Account in the form designer.
  3. Delete the following right tabs by selecting them and clicking Tab > Delete Tab:
    • $tag.ldap.Business
    • $tag.ldap.Address
    • $tag.ldap.Other
  4. Delete all the account attributes except for $eruid, $cn, and $sn.
  5. Click the diskette icon to save the new form.
  6. Create a service with the new type.
  7. Request an account and see that the account form is the new customized version shown in Figure 23.
    Figure 23. Account form for the new service type
    A screenshot of the custom account form.

Conclusion

In this article you've learned how to create a new LDAP server adapter for IBM Security Identity Manager using IBM Tivoli Directory Integrator. You'll need to build an adapter anytime you need to connect IBM Security Identity Manager with an unsupported application or service. As you've seen, an LDAP server adapter is relatively easy to configure and handles all the functions required to manage user accounts with IBM Security Identity Manager.

Acknowledgements

Eddie Hartman and Jens Thomassen helped me with IBM Tivoli Directory Integrator, especially implementing the LDAP search operation. I would also like to thank Clyde W. Zoch for reading this paper and correcting some errors. The remaining mistakes are, of course, my own fault.

Resources

Learn

Get products and technologies

Discuss

  • Get involved in the developerWorks Community: Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Security on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Security
ArticleID=951618
ArticleTitle=Build new adapters for IBM Security Identity Manager
publish-date=11042013