Monday, March 31, 2008

Problem with AD Connector updating City, State with literal text

The Problem:
When a user is created in AD (using out of the box OIM connector 9041), all values for city, state etc change in AD to be literally "city", "state" etc. instead of correct values supplied via AD User Provisioning form (even with prepop).

The Resolution:
There is a task in AD called Set Exchange Related Properties in Exchange Provisioning Definition. This task has a literal value for all the AD fields like "city", "state". Either make this task conditional or map these values from Xellerate User City / State UDFs.

Wednesday, March 26, 2008

Changing Oracle Logo in OIM

If you ever need to customize the logo in Oracle Identity Manager, the do the following steps:



1. Take the file xlWebApp.war from your oim server installation folder and copy it to another folder - say C:\CustomWebApp.
RECOMMENDATION: Take a Backup of this file in another location as well (just incase).

2. Go to command prompt and change your current directory to be C:\CustomWebApp.

3. Run the following command:
jar -xvf xlWebApp.war

4. Copy your company's logo file(s) to the following folder:
C:\CustomWebApp\images

Suppose you have 2 files header_r1_c1.gif (actual logo file) and header_r1_c2.gif (company punch line file).

5. After this, edit the following file in any editor -

C:\CustomWebApp\WEB-INF/classes/xlDefaultAdmin.properties

Search for the following line:
global.image.clientlogo=/images/client_logo.gif

And change this to
global.image.clientlogo=/images/header_r1_c1.gif
global.image.clientlogo1=/images/header_r1_c2.gif

6. Next, edit this file C:/CustomWebApp/tiles/common/tjspHeader.jsp and look for this line (NOTE : This line may appear different in different versions. So, just concentrate on looking for clientlogo keyword.

<html:img bundle="xlDefaultAdmin" pageKey="global.image.clientlogo" height="80"/>

And change it to

<TD valign="center" align="left" width="650px" height="80px" background="/xlWebApp/images/header_bkgd.gif">
<html:img bundle="xlDefaultAdmin" pageKey="global.image.clientlogo" height="80"/>
<html:img bundle="xlDefaultAdmin" pageKey="global.image.clientlogo1" height="80"/>
</TD>

AGAIN NOTE: You might just have one file. In that case, you do not need the second line (referring clientlogo1). You may also adjust the alignment left, center or changing the width of the table.

7. Save all the files and come out of text editors.

8. Now, delete the xlWebApp.war from C:\CustomWebApp

9. Issue the following command:
jar -cvf xlWebApp.war .

10. It will create a new xlWebApp.war file now. Copy this xlWebApp.war in your OIM Server Xellerate installation webapp folder.

11. Then go to OIM Server Xellerate Installation setup folder and run the following command while jboss is still running.
patch_jboss.cmd xlAdm
or
./patch_jboss.sh xlAdm (in Unix flavors).

NOTE: "xlAdm" here is the database password for your OIM schema User that you created while OIM installation.

12. This will deploy your new war file and all you need is a restart to your jboss application server. Now you should see new logo in your OIM on all the pages.

Thursday, March 20, 2008

Getting your definitions straight

Reconciliation

Reconciliation involves duplicating in Oracle Identity Manager the creation of and modifications to user accounts on the target system. It is an automated process initiated by a scheduled task that you configure.

Types of Reconciliation
While configuring the connector, the target system can be designated as a Trusted Source or Target Resource (also known as Non-Trusted Source). Usually there is a parameter on your Scheduled Task (for eg., IsTrusted = True or False or something like TrustedSource=True or False) that differentiates or tells OIM how to consider the events associated with this scheduled job recon.


  • Trusted Reconciliation
    If you designate the target system as a trusted source, then both newly created and modified user accounts are reconciled in Oracle Identity Manager.

  • Non-Trusted Reconciliation
    If you designate the target system as a target resource or Non-Trusted Source, then only modified user accounts are reconciled in Oracle Identity Manager.


Provisioning

Provisioning involves creating or modifying a user's access rights on the target system through Oracle Identity Manager. You use the Oracle Identity Manager Administrative and User Console to perform provisioning operations.

Wednesday, March 19, 2008

AD Child Domain Referral Searches

If your ldp tool fails to find users / groups from other child / brother domains due to referral issues, use the following method to override the search criteria.

First create an account with Enterprise Admin rights over the full root domain. Once the rights are properly given, in ldp tool, set connection options to add LDAP_OPT_REFERRALS to 1 (after binding with this enterprise admin user) and then retry your search.

Add cross reference of trusted domain. You may use the following Microsoft support link as a reference:
http://support.microsoft.com/kb/241737

If you are coding, add this statement to make it work:
env.put( Context.REFERRAL, "follow" );

Here is the sample code:

import javax.naming.ldap.*;
import javax.naming.directory.*;
import javax.naming.*;
import javax.naming.directory.BasicAttributes;
import java.util.Properties;

public class test {
public static void main(String[] args) {

Properties env = new Properties();

env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389");
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.REFERRAL, "follow" );
env.put(Context.SECURITY_PRINCIPAL, "Rajnish");
env.put(Context.SECURITY_CREDENTIALS, "Bhatia01");

try {
LdapContext context = new InitialLdapContext(env, null);
String base = "DC=nj,DC=bhatiacorp,DC=com";
String filter = "(&(objectClass=group)(CN=rajadmin))";

SearchControls controls = new SearchControls();

String []strReturningAttr = {"member"};

controls.setReturningAttributes(strReturningAttr);
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);

NamingEnumeration answer = context.search(base, filter, controls);
int totalResults = 0;
String strMember ;
BasicAttributes userattrs;

// ... process attributes ...
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult)answer.next();

System.out.println(">>>" + sr.getName());

//Print out the groups

Attributes attrs = sr.getAttributes();

if (attrs != null) {

try {
for (NamingEnumeration ae = attrs.getAll();ae.hasMore();) {
Attribute attr = (Attribute)ae.next();
System.out.println("Attribute: " + attr.getID());
for (NamingEnumeration e = attr.getAll();e.hasMore();totalResults++) {

strMember = (String) e.next();
System.out.println(" " + totalResults + ". " + strMember);
userattrs = (BasicAttributes)context.getAttributes(strMember);


}

}

}
catch (NamingException e) {
System.err.println("Problem listing membership: " + e);
}

}
}
System.out.println("TotalResults " + totalResults );
}
catch (NamingException e) {
System.out.println("Problem retrieving RootDSE: " + e);
}
}
}

Monday, March 17, 2008

Custom Sybase Connector for Non-Supported Versions

import java.sql.*; // JDBC
import com.sybase.jdbc2.*; // Sybase jConnect
import java.util.Properties; // Properties

public class ExtendedUserUtilities {
private static Connection getSybaseConnection( String machine,String port, String userID,String password ) {

Connection connection;
String url;
Properties properties;
connection = null;
url = "jdbc:sybase:Tds:" + machine + ":" + port;
properties = new Properties();
properties.put ( "user", userID );
properties.put ( "password", password );
try {
Class.forName ( "com.sybase.jdbc2.jdbc.SybDriver" ).newInstance();
connection = DriverManager.getConnection( url, properties );
connection.setAutoCommit( false ) ;
}
catch ( Exception exception ) {
System.out.println ( "Error: " + exception.getMessage() );
exception.printStackTrace();
}
System.out.println ( "Connection url: '" + url + "'" );
return connection;

}

public static void main(String[] args){
ExtendedUserUtilities e=new ExtendedUserUtilities("192.168.2.10", "3083", "bhatia_su", "bhatia123");
String Pwd = "Password";
String User = "bhatia01";
e.sybase_adduser(User, pwd,"cp", "g_cp", "Rajnish", "Bhatia");
// e.sybase_dropuser(User);
}

public String sybase_adduser(String user, String password, String database, String group, String firstname, String lastname){
String rtnval="Success";
Connection connection1 = getSybaseConnection( SybaseServer, Port, Admin, Pwd);
if ( connection1 != null ) {
System.out.println( "Connection to Sybase successful" );
} else {
System.out.println( "Connection to Sybase failed" );
}
try {

CallableStatement proc = connection1.prepareCall("{call sp_addlogin( ?, ?, ?, ?, ?) }");
connection1.setAutoCommit(true);
proc.setString( 1, user);
proc.setString( 2, password);
proc.setString( 3, database);
proc.setString( 4, null);
proc.setString( 5, firstname+" "+lastname);
proc.executeUpdate();
System.out.println( "Executed sp_addlogin : User "+user +" created with password " );

CallableStatement proc2 = connection1.prepareCall("{call "+database+".dbo.sp_adduser( ?, ? , ?) }");
proc2.setString( 1, user);
proc2.setString( 2, user);
proc2.setString( 3, group);
proc2.executeUpdate();
System.out.println( "Executed sp_adduser : User "+user +" added." );

} catch( Throwable e ) {
rtnval="Error";
e.printStackTrace();
}
return rtnval;
}

public String sybase_dropuser(String user){
String rtnval="Success";
Connection connection1 = getSybaseConnection( SybaseServer, Port, Admin, Pwd);
if ( connection1 != null ) {
System.out.println( "Connection to Sybase successful" );
} else {
System.out.println( "Connection to Sybase failed" );
}
try {

CallableStatement proc = connection1.prepareCall("{call databasename.dbo.sp_dropuser( ?) }");
connection1.setAutoCommit(true);
proc.setString( 1, user);

proc.executeUpdate();
System.out.println( "Executed sp_dropuser : User "+user +" dropped" );

CallableStatement proc2 = connection1.prepareCall("{call sp_droplogin( ?) }");
proc2.setString( 1, user);
proc2.executeUpdate();
System.out.println( "Executed sp_droplogin : User "+user +" dropped." );

} catch( Throwable e ) {
rtnval="Error";
e.printStackTrace();
}
return rtnval;
}
}

Add jconn2.jar Sybase driver to this code.

AD Move User to New OU

The Active Directory Connector by default creates users in CN=Users. Oftentimes, you need to move user to another ou based on some logic, for example based of location. So, here I present you with a code snippet that you can use to move user to another ou and attach it to create user "Success" response code in AD Provisioining process.

import javax.naming.*;
import javax.naming.directory.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import Thor.API.Exceptions.tcAPIException;
import Thor.API.tcResultSet;
import Thor.API.tcUtilityFactory;
import Thor.API.Base.tcUtilityOperationsIntf;
import Thor.API.Operations.tcUserOperationsIntf;

import com.thortech.util.logging.Logger;
import java.util.Hashtable;
public class MoveUserToOU {
public Logger logger;

public String MoveUser2NewOU(String cn, String ADServer, String domain,String Location, String AdminID, String Password){
String rtnval="EXECUTION_SUCCESS";
if (Location.equalsIgnoreCase(""))
{
return rtnval;
}
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.PROVIDER_URL, "ldaps://"+ADServer+":636/");
//AdminID="Administrator@bhatia.com"
env.put(Context.SECURITY_PRINCIPAL, AdminID);
//Password="Password1";
env.put(Context.SECURITY_CREDENTIALS, Password);
try {
DirContext ctx = new InitialDirContext(env);
String OldCN="CN="+cn+",OU=Users,OU=OTHR,"+domain;
logger.debug("Old CN:"+OldCN);
String NewCN="CN="+cn+",OU=Users,OU="+getNewOU(Location)+","+domain;
logger.debug("New CN:"+NewCN);
logger.debug("Starting Modify DN ");
ctx.rename(OldCN, NewCN);
logger.debug("Ended Modify DN with Success..."+rtnval);
//ctx.rename("CN=Rajnish Bhatia,OU=HR,dc=bhatia,dc=com", "CN=Rajnish Bhatia,OU=IT,dc=bhatia,dc=com");
//System.out.println(ctx.lookup("CN=Rajnish Bhatia,OU=IT,dc=bhatia,dc=com"));
ctx.close();
} catch (Exception e) {
logger.debug("Ended Modify DN with Error...");
rtnval="ERROR : "+e.getMessage();
e.printStackTrace();
}
return rtnval;
}

public String getNewOU(String Location) {
String NewOU="";
if(Location.equalsIgnoreCase("CA"))
NewOU="CA";
else
if(Location.equalsIgnoreCase("TN"))
NewOU="TN";
else
if(Location.equalsIgnoreCase("NJ"))
NewOU="NJ";
else
if(Location.equalsIgnoreCase("TX"))
NewOU="TX";
return NewOU;
}
}

Active Directory SSL Test

You may use this code to test the SSL connection with your AD server.

=====================================================
ADSSLConnectionTest.java
=====================================================

import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
public class ADSSLConnectionTest
{

private DirContext getContext(String ldaphost, String ldapport, String adminID, String adminpassword, boolean useSSL)
{
DirContext ctx=null;
String providerurl=ldaphost+":"+ldapport;
if(ldapport=="")
{
ldapport="636";
}
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY ,"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL ,providerurl);
if(useSSL==true)
{
// if SSL is used - use can use ssl enabled ldaphost
// eg. "ldaps://localhost:636"
// else
// eg. "ldap://localhost:636"
env.put(Context.SECURITY_PROTOCOL, "ssl");
}
env.put(Context.SECURITY_AUTHENTICATION ,"simple");
env.put(Context.SECURITY_PRINCIPAL ,adminID);
env.put(Context.SECURITY_CREDENTIALS ,adminpassword);
ctx = new InitialDirContext(env);
}
catch(Exception ex)
{
ex.printStackTrace();
}
return ctx;
}

public DirContext getContext()
{
DirContext ctx=null;
try {
ctx=getContext("ldaps://localhost","636","CN=Rajnish Bhatia,DC=bhatia,DC=com","Password1",true);
System.out.println("Connected with SSL");
}
catch(Exception ex)
{
System.out.println("NOT Connected with SSL");
ex.printStackTrace();
}
return ctx;
}

public static void main(String[] args) {
try
{
ADSSLConnectionTest c = new ADSSLConnectionTest();
c.getContext();
}catch(Exception ex)
{
ex.printStackTrace();
}
}
}

Compile and run with your credentials as following:

C:\>javac ADSSLConnectionTest.java

C:\>java ADSSLConnectionTest

=============================
Notes
=============================

1. If you have issues, make sure your SSL Certificate is in proper java store such as C:\j2sdk1.4.2_13\jre\lib\security. Make sure you are adding the certificate to the correct (& in path) java cacerts keystore.

2. You may also test by telnet to the server - telnet localhost 636

3. You may list the keystore values as follows:
C:\j2sdk1.4.2_13\jre\lib\security>keytool -list -v -storepass changeit -keystore cacerts

This is how it looks:


*******************************************
*******************************************


Alias name: someclass3g3ca
Creation date: Jun 15, 2004
Entry type: trustedCertEntry

Owner: CN=Some Authority, OU="(c)
1999 Bhatia, Inc. - For authorized use only", OU=Bhatia Trust Network, O="Bhatia, Inc.", C=US
Issuer: CN=Some Authority, OU="(c)
1999 Bhatia, Inc. - For authorized use only", OU=Bhatia Trust Network, O="Bhatia, Inc.", C=US
Serial number: 9b7e0649a33e62b9d5ee90487129ef53
Valid from: Thu Sep 30 20:00:00 EDT 1999 until: Wed Jul 16 19:59:59 EDT 2036
Certificate fingerprints:
MD5: CD:68:B6:A7:C7:C4:CE:75:E0:1D:2F:57:44:61:92:09
SHA1: 13:2D:0D:45:53:4B:69:97:CD:B2:D6:C3:39:E2:55:76:60:9B:5C:C6


*******************************************
*******************************************

Alias name: corp9
Creation date: Mar 17, 2008
Entry type: trustedCertEntry

Owner: CN=srvr-corp9.nj.bhatia.com
Issuer: CN=SRVR-RAS-DC, DC=bhatia, DC=com
Serial number: 2714a16c000000000013
Valid from: Mon Jan 28 12:14:58 CST 2008 until: Tue Jan 27 12:14:58 CST 2009
Certificate fingerprints:
MD5: CD:48:B6:A7:C7:C4:CE:75:E0:1D:2F:57:44:61:92:09
SHA1: 12:1D:0D:45:52:4B:64:97:CD:B2:D6:C3:39:E2:55:76:60:9B:5C:C6


*******************************************
*******************************************

4. Then, make sure your ADITResource in OIM - The server is srvr-corp9.nj.bhatia.com (as per your keystore).

5. For specific ldap error codes, look at the following url:
http://www.directory-info.com/LDAP/LDAPErrorCodes.html

xell-ds.xml encrypted

A solution to having the DB credentials in cleartext for OIM on jboss in the xell-ds.xml file.

Here is how to encrypt the password.

execute the following to get the encrypted data for the password:

cd to your jboss home directory (example: /opt/jboss-4.0.3SP1) and execute the following (replacing <password> with the actual password)

java -cp lib/jboss-jmx.jar:lib/jboss-common.jar:server/default/lib/jbosssx.jar:server/default/lib/jboss-jca.jar org.jboss.resource.security.SecureIdentityLoginModule <password>


repace the contents of your xell-ds.xml file with the following (modify the connection-url to reflect your environment)
replace it with the following file contents
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>jdbc/xlDS</jndi-name>
<connection-url>jdbc:oracle:thin:@some.corpdev1.bhatia.com:1575:dbidm</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<!--new below in red -->
<security-domain>EncryptDBPassword</security-domain>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<check-valid-connection-sql>select 1 from USR where 1=2 </check-valid-connection-sql>
</local-tx-datasource>
<xa-datasource>
<jndi-name>jdbc/xlXADS</jndi-name>
<track-connection-by-tx>true</track-connection-by-tx>
<isSameRM-override-value>false</isSameRM-override-value>
<xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
<xa-datasource-property name="URL">jdbc:oracle:thin:@some.corpdev1.bhatia.com:1575:dbidm</xa-datasource-property>
<!--new below-->
<security-domain>EncryptDBPasswordXA</security-domain>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<no-tx-separate-pools/>
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name>
</xa-datasource>
<mbean code="org.jboss.resource.adapter.jdbc.vendor.OracleXAExceptionFormatter"
name="jboss.jca:service=OracleXAExceptionFormatter">
<depends optional-attribute-name="TransactionManagerService">jboss:service=TransactionManager</depends>
</mbean>
</datasources>

Add the following to the login-config.xml file....
================================================================
<application-policy name="EncryptDBPassword">
<authentication>
<login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">
<module-option name="username">oim</module-option>
<module-option name="password">-34a58ed26f8d8263e0f4fadaae6c7657</module-option>
<module-option name="managedConnectionFactoryName">jboss.jca:name=jdbc/xlDS,service=LocalTxCM</module-option>
</login-module>
</authentication>
</application-policy>
<application-policy name="EncryptDBPasswordXA">
<authentication>
<login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">
<module-option name="username">oim</module-option>
<module-option name="password">-34a58ed26f8d8263e0f4fadaae6c7657</module-option>
<module-option name="managedConnectionFactoryName">jboss.jca:name=jdbc/xlXADS,service=XATxCM</module-option>
</login-module>
</authentication>
</application-policy>

courtesy:Patrick Dooley