Tuesday, February 21, 2012

OIM 11g DB password account expiry ORA-28001

On dev environments 11g DB introduced an account password expiry feature. This is very annoying as a OIM 11g developer as I don't want OIM passwords to expire. This article provides a procedure how to get around this issue.

OIM Schemas for which passwords need to be updated:

select * from dba_users (where expiry_date is within the range of your expiry time) and reset all teh passwords to the same value as before. Below is the list of accounts that have expired in my case

kpsoftoim_db_mds, kpsoftoim_db_oim, kpsoftoim_db_soainfra, kpsoftoim_db_orasdpm, kpsoftoim_db_oam







change the profile of 11g
----------------------------
ALTER PROFILE DEFAULT LIMIT
  FAILED_LOGIN_ATTEMPTS UNLIMITED
  PASSWORD_LIFE_TIME UNLIMITED;

run select * from dba_profiles

and confirm the above updates to the profile

For each of the user accounts mentioned above, run the following:
----------------------------------------------------------------

select * from dba_users

-- mds
alter user kpsoftoim_db_mds identified by xxxxxx;
alter user kpsoftoim_db_mds account unlock;

-- oim
alter user kpsoftoim_db_oim identified by xxxxxx;
alter user kpsoftoim_db_oim account unlock;

-- soainfra
alter user kpsoftoim_db_soainfra identified by xxxxxx;
alter user kpsoftoim_db_soainfra account unlock;

-- orasdpm
alter user kpsoftoim_db_ias_orasdpm identified by xxxxxx;
alter user kpsoftoim_db_ias_orasdpm account unlock;

-- oam
alter user kpsoftoim_db_oam identified by xxxxxx;
alter user kpsoftoim_db_oam account unlock;

Monday, February 13, 2012

Installation of Android APK file App

Assuming that you have installed android SDK and tools as shown here, this article focuses on installing the individual apps or the apk files. Eclipse gives you an environment that will allow you to deploy android applications automatically. However one needs to use adb tool for installing app to the virtual device (simulator).

open a command prompt -> cmd in my case. I have this setup on a windows 7 machine. adb in my version (3.2) is located in platform-tools and not tools.
cd to C:\Android\android-sdk\platform-tools
adb install "c:\androidapps\kpsofthello.apk"

120 KB/s .....
Success

Android app is now installed.

OIM 11g Create and disable accounts


/**
 * @author VKanigicherla
 *
 *         Utility for bulk loading users into the OIM system Data must be
 *         exported to an excel spreadsheet with the following attributes in the
 *         order specified below
 *            samid    dn    desc    sid    upn    fn    mi    ln    display    office    tel    email    title    dept    company    loscr    disabled
 *
 *             In this example we used Active Directory to export user account data
*              Ideally, connector reconciliation tasks must be used for importing users, in case you need
*              do this manually for whatever reason, the below program could be used.

 *             Libraries needed are primarily from oim 11g environment and apache POI project for reading excel xml workbooks
 *
 */
public class OimReconBulkUserLoad {

    // Read the input feed from the excel file
    public static String filename = "C:\\kpsoft\\junk\\Users1.xlsx";
    public static List sheetData = new ArrayList();
    public static FileInputStream fis = null;
    public static ArrayList<OimBulkUser> oimUsers = new ArrayList<OimBulkUser>();
    public static tcUtilityFactory ioUtilityFactory;
    public static String updatedByUserName = "BULKLOADER";
    static final Logger logger = Logger.getLogger(OimReconBulkUserLoad.class);

    // OIM Env Data
    public static String id;
    public static OIMClient oimClient;
    private static String OIMUserName = "prasad";
    private static String OIMPassword = "xxxxxx";
    private static final String OIM_PROVIDER_URL = "t3://sandbox-oim.kpsoft.org:14000/oim";

    private static String OIMInitialContextFactory = "weblogic.jndi.WLInitialContextFactory";
    private static UserManager userMgrSrvc = null;
    private static tcOrganizationOperationsIntf orgSrvc = null;
    private static String orgName = "Terminations";

    public OimReconBulkUserLoad() {
        super();
    }

    /**
     * main control method for running the bulk load initiates connection with
     * OIM reads the bulk load contents executes API for loading users cleans up
     * the connection
     *
     * @param args
     * @throws Exception
     */
    public static void main(String args[]) throws Exception {

        init();
        readBulkLoadInputFile();
        loadBulkLoadInputFile();
        // printOimUsers();       
        execBulkLoadInputFile(orgName);
        clean();
    }

    private static void printOimUsers() {
        // TODO Auto-generated method stub
        LOGGER("Printing OIM Users");
        for (int i = 0; i < oimUsers.size(); i++) {
            LOGGER(oimUsers.get(i).getSamAccountId());
        }
       
    }

    /**
     * creates a connection to the OIM with the passed in credentials
     *
     * @throws LoginException
     */
    private static void init() throws LoginException {
        LOGGER("Creating client....");
        Hashtable env = new Hashtable();

        env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, OIMInitialContextFactory);
        env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, OIM_PROVIDER_URL);

        /**
         * Passing environment in constructor disables lookup for environment in
         * setup. In any case, we can always enforce manual environment settings
         * by OIMClient.setLookupEnv(configEnv) method.
         */
        oimClient = new OIMClient(env);
        LOGGER("Logging in");

        oimClient.login(OIMUserName, OIMPassword);
        LOGGER("Log in successful");

        // get the user Manager
        userMgrSrvc = oimClient.getService(UserManager.class);
        orgSrvc = oimClient.getService(tcOrganizationOperationsIntf.class);
    }

    /**
     * parse the input file and iterate through the content
     *
     * @throws IOException
     */
    protected static void readBulkLoadInputFile() throws IOException {

        try {
            fis = new FileInputStream(filename);

            XSSFWorkbook workbook = new XSSFWorkbook(fis);
            XSSFSheet sheet = workbook.getSheetAt(0);
            Iterator rows = sheet.rowIterator();

            // get rid of the title columns
            if (rows.hasNext())
                rows.next();

            while (rows.hasNext()) {

                XSSFRow row = (XSSFRow) rows.next();
                Iterator cells = row.cellIterator();
                List data = new ArrayList();

                while (cells.hasNext()) {
                    XSSFCell cell = (XSSFCell) cells.next();

                    data.add(cell);
                }

                sheetData.add(data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                fis.close();
            }
        }

    }

    /**
     * create a arraylist of model user objects
     */
    protected static void loadBulkLoadInputFile() {

        //
        // Iterates the data and print it out to the console.
        // TODO - update these things based on teh excel spreadsheet header
        //

        int col_samid = 0;
        int col_dn = 1;
        int col_desc = 2;
        int col_sid = 3;
        int col_upn = 4;
        int col_fn = 5;
        int col_mi = 6;
        int col_ln = 7;
        int col_display = 8;
        int col_office = 9;
        int col_tel = 10;
        int col_email = 11;
        int col_title = 12;
        int col_dept = 13;
        int col_company = 14;
        int col_loscr = 15;
        int col_disabled = 16;

        for (int i = 0; i < sheetData.size(); i++) {
            List list = (List) sheetData.get(i);

            OimBulkUser ssoUser = new OimBulkUser();
            for (int j = 0; j < list.size(); j++) {
                XSSFCell cell = (XSSFCell) list.get(j);
                int cellType = cell.getCellType();
                int cellColumnIndex = cell.getColumnIndex();

                String cellValue = "";
                if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
                    cellValue = Float.toString((float) cell
                            .getNumericCellValue());
                } else if (cellType == HSSFCell.CELL_TYPE_STRING) {
                    cellValue = cell.getRichStringCellValue().getString();
                }

                if (cellColumnIndex == col_samid) {

                    ssoUser.setSamAccountId(cellValue);
                } else if (cellColumnIndex == col_dn) {

                    ssoUser.setDistinguishedName(cellValue);
                    ssoUser.setOrganization(getOrganizationFromDN(cellValue));
                } else if (cellColumnIndex == col_desc) {

                    ssoUser.setDescription(cellValue);
                } else if (cellColumnIndex == col_sid) {
                    ssoUser.setSid(cellValue);
                } else if (cellColumnIndex == col_upn) {
                    ssoUser.setUpnName(cellValue);
                } else if (cellColumnIndex == col_fn) {
                    ssoUser.setFirstName(cellValue);
                } else if (cellColumnIndex == col_mi) {
                    ssoUser.setMiddleName(cellValue);
                } else if (cellColumnIndex == col_ln) {
                    ssoUser.setLastName(cellValue);
                } else if (cellColumnIndex == col_display) {
                    ssoUser.setDisplayName(cellValue);
                } else if (cellColumnIndex == col_office) {
                    ssoUser.setOffice(cellValue);
                } else if (cellColumnIndex == col_tel) {
                    ssoUser.setTelephoneNumber(cellValue);
                } else if (cellColumnIndex == col_email) {
                    ssoUser.setEmailAddress(cellValue);
                } else if (cellColumnIndex == col_title) {
                    ssoUser.setTitle(cellValue);
                } else if (cellColumnIndex == col_dept) {
                    ssoUser.setDepartmentName(cellValue);
                } else if (cellColumnIndex == col_company) {
                    ssoUser.setCompany(cellValue);
                } else if (cellColumnIndex == col_loscr) {
                    ssoUser.setLogikpsoftript(cellValue);
                } else if (cellColumnIndex == col_disabled) {
                    ssoUser.setDisabledString(cellValue);
                }
               
            }
            oimUsers.add(ssoUser);
        }
    }

    private static String getOrganizationFromDN(String cellValue) {
        // TODO Auto-generated method stub
        String orgUnit = null;
        try {
            LdapName dnName = new LdapName(cellValue);
            // get OU from the dn whis is always in teh second place 0
            // (dc=org),1 (dc=kpsoft), 2, 3
            orgUnit = dnName.get(3);
            orgUnit = orgUnit.substring(orgUnit.indexOf('=') + 1);
        } catch (InvalidNameException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return orgUnit;
    }

    /**
     * calls the create user API in SsoProvisioningServiceImpl logs the
     * exceptions if any
     *
     * @throws SsoOrganizationException
     */
    protected static void execBulkLoadInputFile(String orgName) {

        for (OimBulkUser su : oimUsers) {
           
            // do it only for organization specified
            if (su.getOrganization().equals(orgName)) {
                User blkUser = new User("");

                // first name
                blkUser.setAttribute("First Name", su.getFirstName());
                // last name
                blkUser.setAttribute("Last Name", su.getLastName());
                // middle name
                blkUser.setAttribute("Middle Name", su.getMiddleName());
                // physicalDeliveryOfficeName
                blkUser.setAttribute("Office", su.getOffice());
                // telephoneNumber
                blkUser.setAttribute("Telephone Number",
                        su.getTelephoneNumber());
                // givenName

                // displayName
                blkUser.setAttribute("Display Name", su.getDisplayName());
                // sAMAccountName
                blkUser.setAttribute("User Login", su.getSamAccountId());
                // title
                blkUser.setAttribute("Title", su.getDescription());
                // mail
                blkUser.setAttribute("Email", su.getEmailAddress());

                // system stuff
                blkUser.setAttribute("Xellerate Type", "End-User");
                // full time employee
                blkUser.setAttribute("Role", "Full-Time Employee");
                // get org key
                long adUsersOimOrg = 1;
                try {
                    adUsersOimOrg = Long.parseLong(findOimOrganizationKey(su
                            .getOrganization()));
                } catch (NumberFormatException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // set the organization
                blkUser.setAttribute("act_key", adUsersOimOrg);

                // create the user now
                UserManagerResult result;
                UserManagerResult disableResult;
                try {
                    result = userMgrSrvc.create(blkUser);
                    String usrKey = result.getEntityId();
                    LOGGER("User created in OIM for AD User: "
                            + su.getSamAccountId() + " with user id: " + usrKey);
                   
                    // if the user is disabled in AD export spreadsheet
                    // disable here as well
                    if (su.getDisabledString().equalsIgnoreCase("yes")) {
                        try {
                            disableResult = userMgrSrvc.disable(usrKey, false);
                        } catch (UserDisableException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (NoSuchUserException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }   
                    }
                   
                } catch (ValidationFailedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (UserAlreadyExistsException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (UserCreateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (AccessDeniedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
               
            }

        }

    }

    private static String findOimOrganizationKey(String orgName)
            throws Exception {
        LOGGER("Entering Method findOrganizationKey");

        String organizationKey = null;

        try {
            LOGGER("Getting utility interfaces...");

            tcOrganizationOperationsIntf moOrganizationUtility = (tcOrganizationOperationsIntf) oimClient
                    .getService(Thor.API.Operations.tcOrganizationOperationsIntf.class);

            // find users
            Hashtable mhSearchCriteria = new Hashtable();

            if (orgName.startsWith("HR"))
                mhSearchCriteria.put("Organizations.Organization Name", "HR*");
            else
                mhSearchCriteria
                        .put("Organizations.Organization Name", orgName);

            tcResultSet moResultSet = moOrganizationUtility
                    .findOrganizations(mhSearchCriteria);

            if (moResultSet == null || moResultSet.getRowCount() == 0)
                throw new Exception("Organizations not found");

            for (int i = 0; i < moResultSet.getRowCount(); i++) {
                moResultSet.goToRow(i);
                organizationKey = moResultSet
                        .getStringValue("Organizations.Key");
                LOGGER("Organization Key is: " + organizationKey);
            }

            LOGGER("Done with getting organization key");
        } catch (Exception e) {
            LOGGER(e.getMessage());
            throw new Exception(e);
        }
        LOGGER("Exiting Method");

        return organizationKey;
    }

    /**
     *
     */
    private static void clean() {
        LOGGER("OIM Logging out....");
        // release resources
        System.out.println("Releasing resources");
        oimClient.logout();
        LOGGER("OIM Log out successful");
    }

    public static void LOGGER(String msg) {
        System.out.println("LOGGER >> " + msg);
    }
}

Friday, February 3, 2012

OIM 11g - Active Directory Integration Logging in a clustered environment

I was trying to debug an issue with Active Directory Connector customization. Wanted to turn the debug logs on but logging.xml file was getting overwritten after a restart of OIM managed servers. Found the issue and documented some notes below.

OIM documentation for setting detailed logging for connectors etc is posted here.  OIM used weblogic Oracle Diagnostic Logging (ODL) feature. Primary components of this feature are message types and levels, log handler and logger configurations.

Instead of updating logging.xml on the managed server in a standalone install, updates such as below must be made on the admin server configuration files. Ofcourse this requires managed servers to be restarted for immediate effect. An example is given below:

file location of the admin server of clsuter in my case:
/kpsoftfileshare/orafmw/admin/IDMDomain/adminserver/IDMDomain/config/fmwconfig/servers/wls_oim1
/kpsoftfileshare/orafmw/admin/IDMDomain/adminserver/IDMDomain/config/fmwconfig/servers/wls_oim2

take a backup of logging.xml and update with components as below. In this case i used AD connector logging handlers.

in the log_handler section:
<log_handler name='adcs-handler' level='TRACE:32' class='oracle.core.ojdl.logging.ODLHandlerFactory'>
<property name='logreader:' value='off'/>
<property name='path' value='${domain.home}/servers/${weblogic.Name}/logs/ActiveDirectory.log'/>
<property name='format' value='ODL-Text'/>
<property name='useThreadName' value='true'/>
<property name='locale' value='en'/>
<property name='maxFileSize' value='5242880'/>
<property name='maxLogSize' value='52428800'/>
<property name='encoding' value='UTF-8'/>
</log_handler>

in the loggers section:

<logger name="OIMCP.ADCS" level="TRACE:32" useParentHandlers="false">
<handler name="adcs-handler"/>
<handler name="console-handler"/>
</logger>