mod_auth(nz)_ibmdb2

A novel authentication method for Apache

This article shows you step by step how to compile and configure mod_auth(nz)_ibmdb2 (an Apache authentication module) using IBM® DB2® Universal Database™ (UDB) as the database for storing user and group information. It explains the creation and use of the User Defined Functions (UDFs) for generating passwords in DB2. The UDFs provided are compatible to the functions that are used in Apache's htpasswd utility.

Share:

Helmut K. C. Tessarek, DB2 Performance and Development, IBM

Helmut K. C. Tessarek works at the IBM Toronto Lab in the area of DB2 performance and development. Before that he worked as an IBM DB2 specialist in Software Group Services at IBM Austria. He is the author of mod_auth(nz)_ibmdb2. You can reach Helmut at tessarek@ca.ibm.com.



15 January 2008 (First published 08 July 2004)

Also available in Chinese

In this article, you will:

  • Compile the module
  • Configure and use the module: the new directives, a practical sample, caching
  • Compile the UDFs

Introduction

Since the first release of this article, the Apache webserver has changed quite a bit and so has the module. Apache 2.2 introduced a new authentication backend provider scheme which explains the change of the module name for Apache versions >= 2.2. Although Apache 2.2 provides a SQL database API, called the DBD framework, it makes sense to use mod_authnz_ibmdb2, which allows you to cache the user and group information and it validates not only the hashes used by Apache but also regular MD5 hashes and plain text passwords. Regular "not seeded" MD5 hashes are very often used in web applications.

Active development of mod_auth_ibmdb2 for Apache 1.x has been stopped, but you can find the latest version for Apache 1.x in the new package 'mod_auth_ibmdb2 (Apache 1.x)' on sourceforge.net.

To begin, you will need access to a DB2 system. It does not matter if DB2 is installed on the same machine as Apache or if the database is located on another machine. If the database is located on another machine, make sure that the application development client is installed and configured on the machine that is running Apache. For information on installing DB2, please refer to Speed-start your Linux app 2003: Installing DB2 Version 8.1.

The module and the UDFs are written in C and should compile and run on all platforms that have the proper include files and libraries installed.

This article focuses on the Linux platform. The modules have been developed on Linux.

Before you begin

Download the latest source codes from the mod_auth(nz)_ibmdb2 Web site, which are at the time of this writing, mod_authnz_ibmdb2-1.26.tar.gz (Apache 2.2), mod_auth_ibmdb2-1.10.tar.gz (Apache 2.0) and db2-auth-udfs-1.3.tar.gz.


Compile the module

Open a terminal and log in as root. Next, change to a directory where you can extract the mod_authnz_ibmdb2-1.26.tar.gz. (in this example I will use the directory /ext).

[root@atvie01s ext]# tar -xzf mod_authnz_ibmdb2-1.26.tar.gz
[root@atvie01s ext]# cd mod_authnz_ibmdb2
[root@atvie01s mod_authnz_ibmdb2]# ls -l
total 80
-rw-r--r-- 1 tessus tessus 13521 2007-03-21 22:39 caching.h
-rw-r--r-- 1 tessus tessus   778 2008-01-08 05:47 CHANGES
-rw-r--r-- 1 tessus tessus  1514 2008-01-08 05:47 INSTALL
-rwxr-xr-x 1 tessus tessus   940 2007-03-21 06:50 makemod
-rwxr-xr-x 1 tessus tessus   993 2008-01-08 05:16 makemod.bat
drwxr-xr-x 3 tessus tessus    16 2008-01-08 05:49 man
-rw-r--r-- 1 tessus tessus 36003 2008-01-08 03:40 mod_authnz_ibmdb2.c
-rw-r--r-- 1 tessus tessus  4022 2008-01-07 00:44 mod_authnz_ibmdb2.h
-rw-r--r-- 1 tessus tessus  4218 2008-01-08 05:47 README

You will find a makemod script within this directory that we will use to build the module (shared object) for Apache. For this you have to check some parameters in the script. Use your favorite editor for changing the following parameters to the appropriate values for your environment.

DB2PATH=/home/db2inst1/sqllib
APXS=/usr/local/apache/bin/apxs

Set DB2PATH to the directory where DB2 UDB is accessed. This is usually the instance home directory. Set APXS to the path that points to your apxs binary. The apxs binary is usually installed in the /<your apache home>/bin directory.

After changing the above settings, run the following script:

[root@atvie01s mod_authnz_ibmdb2]# ./makemod

Next, add the following line to your httpd.conf:

Apache >= 2.2:

LoadModule    authnz_ibmdb2_module        modules/mod_authnz_ibmdb2.so

Apache 2.0.x and Apache 1.3.x:

LoadModule    ibmdb2_auth_module          modules/mod_auth_ibmdb2.so

You may also need to add the following line when using Apache 1.3.x:

AddModule     mod_auth_ibmdb2.c

If the sqlcli1.h header file or the DB2 library libdb2.so cannot be found, it is likely that you have not set the DB2PATH correctly. In this situation search your system for the two above-mentioned files.


Configure and use the module

The new directives

With the module comes several new directives for Apache to control the behavior of the authentication process. Here is a list of the new directives, their default values and a description.

Table 1. Listing of directives
DirectiveDefault ValueDescription



AuthIBMDB2User
User for connecting to the DB2 database
AuthIBMDB2Password
Password for connecting to the DB2 database
AuthIBMDB2Database

Database name
AuthIBMDB2UserTable

Name of the user table. If not fully qualified, the user that was used to connect to the database is used as the schema name.
AuthIBMDB2GroupTable

Name of the group table. If not fully qualified, the user that was used to connect to the database is used as the schema name.
AuthIBMDB2NameField
username
Name of the username column within the user and group table
AuthIBMDB2GroupField
groupname
Name of the groupname column within the group table
AuthIBMDB2PasswordField
password
Name of the password column within the user table
AuthIBMDB2CryptedPasswords
on
If AuthIBMDB2CryptedPasswords is "On," then the passwords are stored encrypted. You do not have to specify what kind of encryption was used. Valid encryption methods are: normal md5 hash (32 chars as in php), seeded md5 value (as generated with Apache's htpasswd utility or as in /etc/shadow), crypt. If "Off," plain text passwords are used. For generating passwords within DB2, see the UDFs section in this article.
AuthIBMDB2KeepAlive
on
If AuthIBMDB2KeepAlive is "On," then the server instance will keep the IBMDB2 server connection open.
AuthIBMDB2Authoritative
on
If AuthIBMDB2Authoritative is "Off," then iff the user is not found in the database, let other auth modules try to find the user.
AuthIBMDB2NoPasswd
off
If AuthIBMDB2NoPasswd is "On," then any password the user enters will be accepted as long as the user exists in the database.
AuthIBMDB2UserCondition

Can be used to restrict queries made against the user table. The value should be a string that you want to be added to the end of the where-clause when querying the table. For example, if your user table has an "active" field and you only want users to be able to login if that field is 1, you could use a directive like this: AuthIBMDB2UserCondition active=1
AuthIBMDB2GroupCondition

Can be used to restrict queries made against the group table. The value should be a string that you want to be added to the end of the where-clause when querying the table. For example, if your group table has an "active" field and you only want users to be able to login if that field is 1, you could use a directive like this: AuthIBMDB2GroupCondition active=1
AuthIBMDB2UserProc

Name of the stored procedure for user authentication
AuthIBMDB2GroupProc

Name of the stored procedure for group authentication
AuthIBMDB2Caching
off
If AuthIBMDB2Caching is "On," the user credentials are cached in a file.
AuthIBMDB2GroupCaching
off
If AuthIBMDB2GroupCaching is "On," group information is cached in a file.
AuthIBMDB2CacheFile
/tmp/auth_cred_cache
Defines the location and name of the cache file.
AuthIBMDB2CacheLifetime
300
Sets the expiration timeout in seconds of the cached elements.

A practical sample

In this example, we will use /var/www as the Web root and /data/private for the /private alias. To connect to the database, enter the user name tessarek and the password helmut. The name of the database is auth.

If you need to protect the Web location http://yourserver/private using the new installed mod_auth(nz)_ibmdb2 module:

First, you need to create the two tables in DB2 UDB that will be used for storing the users and the groups.

db2 => connect to auth user tessarek using helmut

   Database Connection Information

 Database server        = DB2/LINUX 9.5.0
 SQL authorization ID   = TESSAREK
 Local database alias   = AUTH

db2 => CREATE TABLE USERS ( USERNAME VARCHAR(40) NOT NULL, PASSWORD VARCHAR(40) )

db2 => ALTER TABLE USERS ADD PRIMARY KEY (USERNAME)

db2 => CREATE TABLE GROUPS ( USERNAME VARCHAR(40) NOT NULL, GROUPNAME VARCHAR(40) NOT NULL )

db2 => ALTER TABLE GROUPS ADD PRIMARY KEY (USERNAME,GROUPNAME)

The tables do not need to be created as in the example above. They could be views or they could have additional columns. The point that has to be taken into account is that there must be a username and a password column in the usertable and the username column must be unique. Furthermore, there must be a username and a groupname column in the grouptable and the username and groupname columns must be unique. You can choose whatever names you want for the username, groupname, and password columns.

Next, you need to insert user and group information in the newly created tables. If you don't want to do any of the following:

  • Use clear text passwords
  • Use Apache's htpasswd to create a new encrypted password
  • Copy the encrypted password from an existing userfile

You will have to install the UDFs as described in the next section.

db2 => insert into users (username,password) values ('test', apr_md5('testpwd'))

db2 => insert into groups (username,groupname) values ('test','admin') 

db2 => select * from users

USERNAME                                 PASSWORD                                
---------------------------------------- ----------------------------------------
test                                     $apr1$bZGrA...$Ic7E68bhwdDnpX6XG/w8i/   

  1 record(s) selected.

db2 => select * from groups

USERNAME                                 GROUPNAME                               
---------------------------------------- ----------------------------------------
test                                     admin                                   

  1 record(s) selected.

Note: apr_md5 is a User Defined Function that is explained in the UDFs section of this article.

Finally, you need to edit the httpd.conf file and add the following lines. For the changes to be effective, the Web server has to be restarted.

Alias	/private	"/data/private/"

<Directory "/data/private">
    AuthName			"DB2 Authentication for private"
    AuthType			Basic
    AuthBasicProvider           ibmdb2     # Apache >= 2.2.x only
    
    AuthIBMDB2User		tessarek
    AuthIBMDB2Password		helmut
    AuthIBMDB2Database		auth
    AuthIBMDB2UserTable		users
    AuthIBMDB2NameField		username
    AuthIBMDB2PasswordField	password

    AuthIBMDB2CryptedPasswords	On
    AuthIBMDB2KeepAlive		On
    AuthIBMDB2Authoritative	On
    AuthIBMDB2NoPasswd		Off

    AuthIBMDB2GroupTable	groups
    AuthIBMDB2GroupField	groupname

    require			group admin
    AllowOverride		None
</Directory>

You also could have omitted the parameters AuthIBMDB2NameField, AuthIBMDB2PasswordField, AuthIBMDB2CryptedPasswords, AuthIBMDB2KeepAlive, AuthIBMDB2Authoritative, AuthIBMDB2NoPasswd because we are using the default values.

If the tables are declared without a schema name, the username that is used for connecting to the database is taken for the schema name.

Point your Web browser to http://yourserver/private and see what happens. If everything works, you should see something like in Figure 1.

Figure 1. Protected area
Protected area

Caching

For sites with a large number of requests it makes sense to cache the user credentials so that the database requests are minimized. The caching is turned off by default so you have to enable caching with the directives AuthIBMDB2Caching On and AuthIBMDB2GroupCaching On. The cache file is created in the /tmp filesystem, since usually everybody has write access to that filesystem. You can change the path to the cache file with AuthIBMDB2CacheFile. The lifetime of the user credentials within the cache file is set with AuthIBMDB2CacheLifetime. By default the lifetime is set to 300 seconds (5 minutes).

If you want to use caching in RAM, create a RAM disk and point AuthIBMDB2CacheFile to that new filesystem. Make sure that the user, which is used to run Apache, has read and write access to that filesystem.

You can create a RAM disk in Linux with the following command (this RAM disk will be 5 MB in size):

mount -t tmpfs -o size=5M,nr_inodes=2k,mode=770 tmpfs /mnt/ramfs

Stored Procedures

The module supports stored procedures to retrieve the user and group information from the database. The reasons for using stored procedures are ease of administration and performance. They must follow a certain parameter format.

The stored procedure for user authentication expects one input parameter, the username, and one output value, the password for that user:

PROCEDURE user_procedure_name ( IN VARCHAR, OUT VARCHAR )

The stored procedure for group authentication expects one input parameter, the user, and must return an open cursor to the resultset:

PROCEDURE group_procedure_name ( IN VARCHAR )

Here is an example of two stored procedures which are modelled on the table configuration in the practical sample.

File 1: sp.sql
CREATE PROCEDURE user_sp (IN v_username VARCHAR(40), OUT v_password VARCHAR(40))
LANGUAGE SQL
BEGIN
   SELECT password INTO v_password FROM users WHERE username = v_username;
END@

CREATE PROCEDURE group_sp (IN v_username VARCHAR(40))
LANGUAGE SQL
DYNAMIC RESULT SETS 1
BEGIN
   DECLARE res CURSOR WITH RETURN FOR
   SELECT groupname FROM groups WHERE username = v_username;
OPEN res;
END@

You can install the stored procedures by running the following commands as the instance user:

[db2inst1@atvie01s ~]$ db2 connect to auth user tessarek using helmut
[db2inst1@atvie01s ~]$ db2 -td@ -f sp.sql

If you want to use the stored procedures, you have to edit the httpd.conf file and to restart the Web server again.

Alias	/private	"/data/private/"

<Directory "/data/private">
    AuthName			"DB2 Authentication for private"
    AuthType			Basic
    AuthBasicProvider           ibmdb2     # Apache >= 2.2.x only
    
    AuthIBMDB2User		tessarek
    AuthIBMDB2Password		helmut
    AuthIBMDB2Database		auth
    
    AuthIBMDB2UserProc          user_sp
    AuthIBMDB2GroupProc         group_sp

    require			group admin
    AllowOverride		None
</Directory>

Compiling the UDFs

Open a terminal and log in as DB2 UDB instance user. Then change to a directory where you are going to extract the db2-auth-udfs-1.3.tar.gz. (in this example I will use the directory /ext).

[db2inst1@atvie01s ~]$ cd /ext
[db2inst1@atvie01s ext]$ tar -xzf db2-auth-udfs-1.3.tar.gz
[db2inst1@atvie01s ext]$ db2-auth-udfs
[db2inst1@atvie01s db2-auth-udfs]$ ls -l
total 56
-rw-rw-r-- 1 db2inst1 db2grp1  596 2008-01-04 09:03 CHANGES
-rw-rw-r-- 1 db2inst1 db2grp1  102 2006-02-17 11:03 drop_udfs.ddl
-rw-rw-r-- 1 db2inst1 db2grp1 4407 2008-01-04 08:58 hash.c
-rw-rw-r-- 1 db2inst1 db2grp1   55 2007-03-06 03:52 hash.def
-rw-rw-r-- 1 db2inst1 db2grp1 3550 2007-02-27 03:36 hash.h
-rw-rw-r-- 1 db2inst1 db2grp1  892 2007-03-06 03:52 INSTALL
-rwxrwxr-x 1 db2inst1 db2grp1  740 2007-03-06 03:52 maketest
-rw-rw-r-- 1 db2inst1 db2grp1  377 2007-03-06 03:45 maketest.bat
-rwxrwxr-x 1 db2inst1 db2grp1 1218 2007-03-27 18:27 makeudf
-rw-rw-r-- 1 db2inst1 db2grp1  532 2007-03-06 03:45 makeudf.bat
-rw-rw-r-- 1 db2inst1 db2grp1 1131 2007-03-06 03:52 README
-rw-rw-r-- 1 db2inst1 db2grp1 1020 2008-01-04 08:57 reg_udfs.ddl
-rw-rw-r-- 1 db2inst1 db2grp1  595 2007-02-27 03:40 test_hash.c

You will find a makeudf script within this directory that we will use to build the UDFs. For this you have to change a parameter in the script. Use an editor for changing the following parameter to the appropriate value for your environment.

DB2PATH=/home/db2inst1/sqllib

Set DB2PATH to the directory where DB2 is accessed. This is usually the instance home directory.

After changing the above parameter, run the script:

[db2inst1@atvie01s db2-auth-udfs]$ ./makeudf

To register the UDFs, connect to your database and run the script to register the UDFs:

[db2inst1@atvie01s db2-auth-udfs]$ db2 connect to auth user tessarek using helmut

   Database Connection Information

 Database server        = DB2/LINUX 9.5.0
 SQL authorization ID   = TESSAREK
 Local database alias   = AUTH

[db2inst1@atvie01s db2-auth-udfs]$ db2 -tvf reg_udfs.ddl
CREATE FUNCTION md5(VARCHAR(120))
       RETURNS VARCHAR(32)
       NOT FENCED
       DETERMINISTIC
       NO SQL
       NO EXTERNAL ACTION
       LANGUAGE C
       RETURNS NULL ON NULL INPUT
       PARAMETER STYLE SQL
       EXTERNAL NAME 'hash!md5'
DB20000I  The SQL command completed successfully.

CREATE FUNCTION apr_md5(VARCHAR(120))
       RETURNS VARCHAR(37)
       NOT FENCED
       NO SQL
       NO EXTERNAL ACTION
       LANGUAGE C
       RETURNS NULL ON NULL INPUT
       PARAMETER STYLE SQL
       EXTERNAL NAME 'hash!aprmd5'
DB20000I  The SQL command completed successfully.

CREATE FUNCTION apr_crypt(VARCHAR(120))
       RETURNS VARCHAR(13)
       NOT FENCED
       NO SQL
       NO EXTERNAL ACTION
       LANGUAGE C
       RETURNS NULL ON NULL INPUT
       PARAMETER STYLE SQL
       EXTERNAL NAME 'hash!aprcrypt'
DB20000I  The SQL command completed successfully.

CREATE FUNCTION apr_sha1(VARCHAR(120))
       RETURNS VARCHAR(33)
       NOT FENCED
       DETERMINISTIC
       NO SQL
       NO EXTERNAL ACTION
       LANGUAGE C
       RETURNS NULL ON NULL INPUT
       PARAMETER STYLE SQL
       EXTERNAL NAME 'hash!aprsha1'
DB20000I  The SQL command completed successfully.

[db2inst1@atvie01s db2-auth-udfs]$ db2 connect reset

The UDFs are written in ANSI C and are using the APR libraries. They should compile and run on all platforms. You can either use the bldrtn script in your sqllib/samples/c directory as a good start, or you can modify the makeudf script.


Description of the UDFs

Here is a list of the UDFs, an example output, and a description.

Table 2. Listing of the UDFs
UDF nameExample OutputDescription



md5342df5b036b2f28184536820af6d1cafMD5 hash. The MD5 function is compatible to the PHP MD5 function.
apr_md5$apr1$bhX6Z/..$kAxtFQozYsZhgNgqVnJd0.Seeded MD5 hash. The apr_md5 is compatible to the Apache function that is used in the htpasswd utility.
apr_cryptbhqWHYBAJAQ2wUNIX® crypt. The apr_crypt is compatible to the Apache function that is used in the htpasswd utility.
apr_sha1{SHA}mO8HWOaqxvmp4Rl1SMgZC3LJWB0=SHA1 algorithm. The apr_sha1 is compatible to the Apache function that is used in the htpasswd utility.

Debugging

If you set LogLevel debug in the httpd.conf file, you will get detailed information about what is happening during the authentication process. Here are two samples of the debugging text that was generated during the practical sample.

Sample 1. Debugging the authentication process with caching turned off
[notice] Apache/2.2.6 (Unix) mod_ssl/2.2.6 PHP/5.2.5 mod_authnz_ibmdb2/1.26 configured --
         resuming normal operations
[info] Server built: Sep  8 2007 11:57:34
[debug] prefork.c(991): AcceptMutex: sysvsem (default: sysvsem)
[debug] mod_authnz_ibmdb2.c(1134):  begin authenticate for user=[test], uri=[/private/]
[debug] mod_authnz_ibmdb2.c(523):   begin get_ibmdb2_pw()
[debug] mod_authnz_ibmdb2.c(232):     DB connection is dead or nonexistent; 
                                      create connection
[debug] mod_authnz_ibmdb2.c(235):     allocate an environment handle
[debug] mod_authnz_ibmdb2.c(690):       query=[SELECT rtrim(password) FROM users 
                                               WHERE username='test']
[debug] mod_authnz_ibmdb2.c(692):       allocate a statement handle
[debug] mod_authnz_ibmdb2.c(698):       prepare the statement
[debug] mod_authnz_ibmdb2.c(715):       execute the statement
[debug] mod_authnz_ibmdb2.c(772):       fetch each row, and display
[debug] mod_authnz_ibmdb2.c(788):       get data from query resultset
[debug] mod_authnz_ibmdb2.c(795):       password from database=
                                        [$apr1$bZGrA...$Ic7E68bhwdDnpX6XG/w8i/]
[debug] mod_authnz_ibmdb2.c(797):       call SQLFetch() (point to next row)
[debug] mod_authnz_ibmdb2.c(803):       free statement handle
[debug] mod_authnz_ibmdb2.c(309):     keepalive on; do not disconnect from database
[debug] mod_authnz_ibmdb2.c(813):   end get_ibmdb2_pw()
[debug] mod_authnz_ibmdb2.c(877):   begin get_ibmdb2_groups()
[debug] mod_authnz_ibmdb2.c(227):     DB connection is alive; re-using
[debug] mod_authnz_ibmdb2.c(913):       query=[SELECT rtrim(groupname) FROM groups 
                                               WHERE username='test']
[debug] mod_authnz_ibmdb2.c(915):       allocate a statement handle
[debug] mod_authnz_ibmdb2.c(921):       prepare the statement
[debug] mod_authnz_ibmdb2.c(938):       execute the statement
[debug] mod_authnz_ibmdb2.c(1010):      fetch each row, and display
[debug] mod_authnz_ibmdb2.c(1035):      get data from query resultset
[debug] mod_authnz_ibmdb2.c(1050):      group #1 from database=[admin]
[debug] mod_authnz_ibmdb2.c(1052):      call SQLFetch() (point to next row)
[debug] mod_authnz_ibmdb2.c(1058):      free statement handle
[debug] mod_authnz_ibmdb2.c(309):     keepalive on; do not disconnect from database
[debug] mod_authnz_ibmdb2.c(1068):  end get_ibmdb2_groups()
Sample 2. Debugging the authentication process with caching turned on
[notice] Apache/2.2.6 (Unix) mod_ssl/2.2.6 PHP/5.2.5 mod_authnz_ibmdb2/1.26 configured -- 
         resuming normal operations
[info] Server built: Sep  8 2007 11:57:34
[debug] prefork.c(991): AcceptMutex: sysvsem (default: sysvsem)
[debug] mod_authnz_ibmdb2.c(1134):  begin authenticate for user=[test], uri=[/private/]
[debug] caching.h(211):  user [test] - [$apr1$bZGrA...$Ic7E68bhwdDnpX6XG/w8i/] 
                         found in cache
[debug] caching.h(502):  groups for user [test] found in cache

Binary releases

Although there are scripts for building the modules and the UDFs on Windows, most Windows users don't have a development environment installed to compile the packages.

You can download the latest binaries for Windows 32bit in the binary releases package section on the website of mod_auth(nz)_ibmdb2.

Resources

Learn

Get products and technologies

  • Download the source code for mod_authnz_ibmdb2 used in this article.
  • Download the source code for mod_auth_ibmdb2.
  • Download the source code for the UDFs used in this article.
  • Download the documentation as a PDF file.
  • Download the binaries for Windows 32bit.
  • Build your next development project with IBM trial software, available for download directly from developerWorks.

Discuss

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 Information management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management
ArticleID=16213
ArticleTitle=mod_auth(nz)_ibmdb2
publish-date=01152008