Using OpenDS for DB2 Authentication

As I mentioned in the previous article about intalling DB2, the DB2 server uses operating system users for authentication. That means that if you want to give Bob Smith access to a database on the server, you need to create a Unix account for him. I like to keep application authentication separated from operating system authentication in most cases, so I didn’t like the way DB2 was working. Luckily, DB2 ships with LDAP authentication plugins to solve this problem.

With LDAP, I can keep all of my user authentication and group membership information in an LDAP directory. If you already have a directory set up, such as Microsoft Active Directory, Novell eDirectory, or an OpenLDAP directory that is in use for authentication, then you can just point at that.

In this case, though, I’m going to create a directory specifically for my DB2 instance. I’ll use OpenDS, an open source Java LDAP server.

After downloading OpenDS, I’ll put unzip it in /opt, resulting in my installation being in /opt/OpenDS-1.0.0:

root@lab01v04# cd /opt
root@lab01v04# unzip /root/
Archive:  /root/
   creating: OpenDS-1.0.0/
   creating: OpenDS-1.0.0/
   creating: OpenDS-1.0.0/
   creating: OpenDS-1.0.0/
   creating: OpenDS-1.0.0/
   creating: OpenDS-1.0.0/
   creating: OpenDS-1.0.0/
  inflating: OpenDS-1.0.0/setup
  inflating: OpenDS-1.0.0/uninstall
  inflating: OpenDS-1.0.0/upgrade

I’m going to create a new user, opends, under which to run the directory server, then change ownership of the installation directory to the new user:

root@lab01v04# cd /opt/OpenDS-1.0.0/
root@lab01v04# groupadd opends
root@lab01v04# useradd -g opends -d /export/home/opends -m \ 
> -s /usr/bin/ksh93 opends
64 blocks
root@lab01v04# passwd opends
New Password: ...password...
Re-enter new Password: ...password...
passwd: password successfully changed for opends
root@lab01v04# chown -R opends:opends /opt/OpenDS-1.0.0/

Now I can perform the rest of the steps as the new users. After logging in as the opends user, I change to the OpenDS directory and start the setup program. This will allow me to set up the basics of the directory service.

I’ll give you the full conversation below. In essence, I’m accepting most of the defaults. I’ll be running on port 1389, so I can start the server as a non-root user. The base DN for my directory will be dc=lab,dc=mattwilson,dc=org (“dc” is short for “domain component,” so this is equivalent to a DNS name of

opends@lab01v04$ cd /opt/OpenDS-1.0.0/
opends@lab01v04$ ./setup --cli

OpenDS Directory Server 1.0.0
Please wait while the setup program initializes...

What would you like to use as the initial root user DN for the Directory
Server? [cn=Directory Manager]:
Please provide the password to use for the initial root user:
Please re-enter the password for confirmation:

On which port would you like the Directory Server to accept connections from
LDAP clients? [1389]:

What do you wish to use as the base DN for the directory data?
[dc=example,dc=com]: dc=lab,dc=mattwilson,dc=org
Options for populating the database:

    1)  Only create the base entry
    2)  Leave the database empty
    3)  Import data from an LDIF file
    4)  Load automatically-generated sample data

Enter choice [1]: 1

Do you want to enable SSL? (yes / no) [no]: no

Do you want to enable Start TLS? (yes / no) [no]: no

Do you want to start the server when the configuration is completed? (yes /
no) [yes]: yes

Setup Summary
LDAP Listener Port: 1389
LDAP Secure Access: disabled
Root User DN:       cn=Directory Manager
Directory Data:     Create New Base DN dc=lab,dc=mattwilson,dc=org.
Base DN Data: Only Create Base Entry (dc=lab,dc=mattwilson,dc=org)

Start Server when the configuration is completed

What would you like to do?

    1)  Setup the server with the parameters above
    2)  Provide the setup parameters again
    3)  Cancel the setup

Enter choice [1]: 1

Configuring Directory Server ..... Done.
Creating Base Entry dc=lab,dc=mattwilson,dc=org ..... Done.
Starting Directory Server ........ Done.

See /var/tmp/opends-setup-23950.log for a detailed log of this operation.

To see basic server configuration status and configuration you can launch

And with that, we have a directory server running! I’m going to update my path to make it easier to use the various LDAP utilities:

opends@lab01v04$ PATH=/opt/OpenDS-1.0.0/bin:$PATH

Now that the directory server is running, we need to create entries in it to support authentication. At the highest level, we’re going to create to “organizational units,” one for users and one for groups. To create LDAP entries, we use LDIF files. The LDIF file with the “ou” definitions, which we’ll call container-setup.ldif, contains the following:

# users
dn: ou=users,dc=lab,dc=mattwilson,dc=org
objectClass: organizationalUnit
ou: users

# groups
dn: ou=groups,dc=lab,dc=mattwilson,dc=org
objectClass: organizationalUnit
ou: groups

To actually import these records into the directory, we’ll use the ldapmodify command. I’m connecting as the directory manager to the LDAP server running on port 1389, and creating records in the container-setup.ldif file:

opends@lab01v04$ ldapmodify -a -D "cn=Directory Manager" -p 1389 \
> -c -f container-setup.ldif
Password for user 'cn=Directory Manager':
Processing ADD request for ou=users,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN ou=users,dc=lab,dc=mattwilson,dc=org
Processing ADD request for ou=groups,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN ou=groups,dc=lab,dc=mattwilson,dc=org

Next we need to create the users. I need to create users to represent the two operating system users that DB2 is already dependent on: db2inst1 and db2fenc1. Additionally, I will create the bsmith user. When we are all done, we should be able to connect as bsmith even though there is no equivalent Solaris user. DB2 should allow the login based on the LDAP entry.

The following user definitions are in user-setup.ldif:

# db2inst1 user -- required to match instance owner
dn: uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=org
objectClass: inetOrgPerson
uid: db2inst1
cn: DB2 Instance 1 Owner
sn: DB2 Instance 1 Owner

# db2fenc1 user -- required to match instance fenced user
dn: uid=db2fenc1,ou=users,dc=lab,dc=mattwilson,dc=org
objectClass: top
objectClass: inetOrgPerson
uid: db2fenc1
cn: DB2 Fenced User 1
sn: DB2 Fenced User 1

# "Bob Smith" user
dn: uid=bsmith,ou=users,dc=lab,dc=mattwilson,dc=org
objectClass: inetOrgPerson
uid: bsmith
cn: Bob Smith
sn: Smith
givenName: Bob

Now we’ll use the ldapmodify tool again to create these entries:

opends@lab01v04$ ldapmodify -a -D "cn=Directory Manager" -p 1389 \
> -c -f user-setup.ldif
Password for user 'cn=Directory Manager':
Processing ADD request for uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=or
Processing ADD request for uid=db2fenc1,ou=users,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN uid=db2fenc1,ou=users,dc=lab,dc=mattwilson,dc=or
Processing ADD request for uid=bsmith,ou=users,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN uid=bsmith,ou=users,dc=lab,dc=mattwilson,dc=org

And now we’ll define the groups. Again, we need to create the current operating system groups that DB2 is using, db2iadm1 and db2fadm1. We also need to create the other security groups that DB2 uses by default, SYSADM, SYSMAINT, SYSCTRL, and SYSMON. Note also how we’re adding members to these groups.

The contents of the group-setup.ldif file are:

# db2iadm1 group
dn: cn=db2iadm1,ou=groups,dc=lab,dc=mattwilson,dc=org
objectClass: top
objectClass: groupOfEntries
cn: db2iadm1
member: uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=org

# db2fadm1 group
dn: cn=db2fadm1,ou=groups,dc=lab,dc=mattwilson,dc=org
objectClass: top
objectClass: groupOfEntries
cn: db2fadm1
member: uid=db2fenc1,ou=users,dc=lab,dc=mattwilson,dc=org

# SYSADM group
dn: cn=SYSADM,ou=groups,dc=lab,dc=mattwilson,dc=org
objectClass: groupOfEntries
ou: Groups
member: uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=org

# SYSMAINT group
dn: cn=SYSMAINT,ou=groups,dc=lab,dc=mattwilson,dc=org
objectClass: groupOfEntries
ou: Groups
member: uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=org

# SYSCTRL group
dn: cn=SYSCTRL,ou=groups,dc=lab,dc=mattwilson,dc=org
objectClass: groupOfEntries
ou: Groups
member: uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=org

# SYSMON group
dn: cn=SYSMON,ou=groups,dc=lab,dc=mattwilson,dc=org
objectClass: groupOfEntries
ou: Groups
member: uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=org

And finally, create these records with ldapmodify:

opends@lab01v04$ ldapmodify -a -D "cn=Directory Manager" -p 1389 \
> -c -f group-setup.ldif
tPassword for user 'cn=Directory Manager':
Processing ADD request for cn=db2iadm1,ou=groups,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN cn=db2iadm1,ou=groups,dc=lab,dc=mattwilson,dc=or
Processing ADD request for cn=db2fadm1,ou=groups,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN cn=db2fadm1,ou=groups,dc=lab,dc=mattwilson,dc=or
Processing ADD request for cn=SYSADM,ou=groups,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN cn=SYSADM,ou=groups,dc=lab,dc=mattwilson,dc=org
Processing ADD request for cn=SYSMAINT,ou=groups,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN cn=SYSMAINT,ou=groups,dc=lab,dc=mattwilson,dc=or
Processing ADD request for cn=SYSCTRL,ou=groups,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN cn=SYSCTRL,ou=groups,dc=lab,dc=mattwilson,dc=org
Processing ADD request for cn=SYSMON,ou=groups,dc=lab,dc=mattwilson,dc=org
ADD operation successful for DN cn=SYSMON,ou=groups,dc=lab,dc=mattwilson,dc=org

The last thing we need to do is assign passwords to the users. OpenDS includes a utility, ldappasswordmodify, to do just that (“adminPassword” is the password I set during setup of OpenDS, and “userPassword” is what I want to set the user’s password to):

opends@lab01v04$ ldappasswordmodify -p 1389 -D "cn=Directory Manager" \
> --authzID "dn:uid=db2inst1,ou=users,dc=lab,dc=mattwilson,dc=org" \
> -w adminPassword -n userPassword
The LDAP password modify operation was successful

opends@lab01v04$ ldappasswordmodify -p 1389 -D "cn=Directory Manager" \
> --authzID "dn:uid=db2fenc1,ou=users,dc=lab,dc=mattwilson,dc=org" \
> -w adminPassword -n userPassword
The LDAP password modify operation was successful

opends@lab01v04$ ldappasswordmodify -p 1389 -D "cn=Directory Manager" \
> --authzID "dn:uid=bsmith,ou=users,dc=lab,dc=mattwilson,dc=org" \
> -w adminPassword -n userPassword
The LDAP password modify operation was successful

And with that, our LDAP directory is created and populated with users and groups, and the users have passwords so they should be able to log in.

After setting up the directory, we need to configure DB2 to use the LDAP plugins. These require some configuration to tell them how to connect to the LDAP user, and how to find users and groups. The configuration is stored in the file sqllib/cfg/IBMLDAPSecurity.ini, relative to the instance root. In my case, that’s /export/home/db2inst1/sqllib/cfg/IBMLDAPSecurity.ini.

For the setup we created above, I’ve entered the following configuration in the file:

LDAP_HOST = localhost:1389
USER_BASEDN = ou=users,dc=lab,dc=mattwilson,dc=org
GROUP_BASEDN = ou=groups,dc=lab,dc=mattwilson,dc=org

With the configuration in place, we’ll change the DB2 instance configuration to use the LDAP plugins:

db2inst1@lab01v04$ db2 update dbm cfg using srvcon_pw_plugin \
> IBMLDAPauthserver

db2inst1@lab01v04$ db2 update dbm cfg using clnt_pw_plugin \
> IBMLDAPauthclient

db2inst1@lab01v04$ db2 update dbm cfg using group_plugin IBMLDAPgroups

For the changes to take effect, we need to restart the instance:

db2inst1@lab01v04$ db2 terminate
DB20000I  The TERMINATE command completed successfully.
db2inst1@lab01v04$ db2stop
SQL1064N  DB2STOP processing was successful.
db2inst1@lab01v04$ db2start
SQL1063N  DB2START processing was successful.

Now to test it: we’ll try to connect to the database we created in the last article, mydb, as the user bsmith. Since there’s no user on my Solaris system named bsmith, this wouldn’t have worked before the LDAP configuration. If we’re able to connect, it means DB2 is now using our LDAP directory for authentication:

db2inst1@lab01v04$ db2
(c) Copyright IBM Corporation 1993,2007
Command Line Processor for DB2 Client 9.5.1

You can issue database manager commands and SQL statements from the command
prompt. For example:
    db2 => connect to sample
    db2 => bind sample.bnd

For general help, type: ?.
For command help, type: ? command, where command can be
the first few keywords of a database manager command. For example:
 ? CATALOG DATABASE for help on the CATALOG DATABASE command
 ? CATALOG          for help on all of the CATALOG commands.

To exit db2 interactive mode, type QUIT at the command prompt. Outside
interactive mode, all commands must be prefixed with 'db2'.
To list the current command option settings, type LIST COMMAND OPTIONS.

For more detailed help, refer to the Online Reference Manual.

db2 => connect to mydb user bsmith
Enter current password for bsmith:

   Database Connection Information

 Database server        = DB2/SUNX8664 9.5.1
 SQL authorization ID   = BSMITH
 Local database alias   = MYDB

db2 =>

Success! You can see that we are logged in as bsmith. You can try other experiments to make sure this is really working—enter an incorrect password or an invalid username that isn’t defined in LDAP, for example, and the server will correctly reject the connection.

2 thoughts on “Using OpenDS for DB2 Authentication”

  1. Dear Mattwilson,
    Your post is so great. Could you please post a guide that tell about IBM LDAP Tivol 6.0 with DB2 v9.5 in windows server 2003?

Comments are closed.