::
FIG 2.1 // ENTRY
Back to Index

LDAP on the IBMi

Date:
LDAP on the IBMi Hero Image

Intro

When hosting services alongside IBM i, such as a VPN, unifying user authentication improves the end-user experience. By configuring the LDAP server on IBM i, users can log in to other services using their existing IBM i credentials.

Process

First, add user profiles to the System Distribution Directory. LDAP, like SMTP, uses this directory for user information. You can access it via the WRKDIRE command.

Note: Usernames are limited to 8 characters due to legacy constraints.

Instead of manually keying each user, I wrote a script to transfer all IBM profiles to the System Distribution Directory automatically.

import odbc from 'odbc'
import { Connection, CommandCall } from 'itoolkit'
import { parseString } from 'xml2js'

const config = {
  host: '<ip-address>',
  name: '<dsn-name>',
  username: '<user-name>',
  password: '<password>',
}

// set up ssh connection for running commands
const connection = new Connection({
  transport: 'ssh',
  transportOptions: {
    host: config.host,
    username: config.username,
    password: config.password,
  },
})

// connect via odbc using the DSN defined in odbc.ini
odbc.connect(`DSN=${config.name}`, (error, db) => {
  if (error) {
    throw error
  }

  // query the QSYS2 user info file
  db.query('SELECT USER_NAME,TEXT FROM QSYS2.USER_INFOB', (error, result) => {
    if (error) {
      throw error
    }

    // comb through the results
    result.forEach(({ USER_NAME, TEXT }) => {
      // disregard the IBM defined profiles
      if (USER_NAME.startsWith('Q')) {
        return false
      }

      // USER ID has an 8 character limit
      const USER_ID = USER_NAME.substring(0, 8)
      console.log({ USER_ID })
      // set up the command to run
      const command = new CommandCall({
        type: 'cl',
        command: `ADDDIRE USRID(${USER_ID} ${config.name}) USRD('${TEXT}') USER(${USER_NAME})`,
      })

      // add the command to the connection
      connection.add(command)
    })

    // after we added the commands let's run them
    connection.run((error, xmlOutput) => {
      if (error) {
        console.log({ error })
      } else {
        // parse the results
        parseString(xmlOutput, (parseError, result) => {
          if (parseError) {
            console.log({ parseError })
          }
          console.log({ result })
        })
      }
    })
  })
})

Managing LDAP

IBM integrates the Tivoli LDAP server, which is configurable via the Web Navigator. For detailed instructions, refer to the IBM i LDAP documentation. Like standard LDAP servers, it uses Common Names (CN) and Organization Names (ON) for authentication integration.

IBMi LDAP Properties

Implementation

I most commonly use this to authenticate pfSense OpenVPN users. Configuring pfSense to authenticate against the IBM i LDAP server is straightforward. Once set up, you can assign this authentication method to your OpenVPN configuration. This approach works for many other services that support LDAP.

PFSense LDAP