LDAP Resources

  


Configure System Authentication Using OpenLDAP on CentOS 5

by Jeff Hunter, Sr. Database Administrator

Contents

Introduction

When a user logs in to a Linux system, the username and password combination must be verified, or authenticated, as a valid and active user. A lot of times the information needed to authenticate the user is located on the local system through entries in the /etc/passwd and /etc/shadow files. Another option is to allow the system to defer user authentication to a user database on a remote system like, for example, an LDAP directory. This is a popular option as it allows administrators to centralize username and password information.

In this guide, I will present the steps required to configure authentication for a Linux client through LDAP using Pluggable Authentication Modules (PAM) and Name Service Switch (NSS). The Linux client will be configured to access user information stored in an LDAP directory database such as username, UID number, GID number, home directory, login shell, and other user information that can be used to authenticate to the client system.

An LDAP client machine named ldaptest.idevelopment.info will be configured in this guide to authenticate users through an LDAP server named ldapsrv.idevelopment.info. The example used in this tutorial is based on a clean installation of OpenLDAP Software on the CentOS 5 platform. This tutorial will also work for Red Hat Enterprise Linux 5 and Oracle Linux 5. The LDAP directory used in this guide has been initialized with a base DN of dc=idevelopment,dc=info and organization units People, Group, and Hosts. Obviously, the name of your LDAP server and the base DN will differ and the examples presented in this guide will need to be modified accordingly for you environment.

Refer to the following three tutorials on how to install OpenLDAP Software, initialize the LDAP directory, and then import OS users and groups into the LDAP directory on the server (ldapsrv.idevelopment.info in this guide) on the CentOS 5 platform.

Install OpenLDAP Client

Installing the OpenLDAP client software will be done using the yum package manager. Yum is available on any of the Red Hat Enterprise Linux distributions including its clones like CentOS.

Log in to the client machine as root and install the OpenLDAP Software client packages from the yum repository. This will update any previously installed release of the OpenLDAP Software packages.


[root@ldaptest ~]# yum -y install openldap openldap-clients nss_ldap authconfig

The following table summarizes the OpenLDAP Software packages installed in the above step.

openldap Contains all configuration files, libraries, and documentation for OpenLDAP.
openldap-clients Contains the client programs needed for accessing and modifying LDAP directories.
nss_ldap Contains access client software for using LDAP as a method of user authentication for Linux.
authconfig An interface for configuring system authentication resources including basic LDAP, Kerberos 5, and SMB (authentication) client configuration.

Configure LDAP Client

After installing OpenLDAP Software on the client machine, the next step is to modify the necessary configuration files to customize the client for LDAP authentication. While in some cases this can be performed by manually editing the associated configuration files, the recommended method is to use an interface that automates the process. Manually editing the configuration files used for authentication imposes the risk of losing those changes since any manual modifications will be reset any time the the configuration wizard is run.

Configure LDAP Client Files for LDAP Authentication

CentOS provides two interfaces to configure client system authentication:

For users with access to an X server, system-config-authentication is a GUI application that comes recommended as it provides the most ease and flexibility. authconfig, on the other hand, is a command-line tools but does produce equivalent client configuration files. In fact, system-config-authentication runs the authconfig command-line utility behind the scenes when updating the client configuration files.

system-config-authentication - (GUI)

The system-config-authentication script provides a graphical utility used to configure client authentication. This method can be used if you are running an X server or have X11 forwarding set up through an SSH connection.


[root@ldaptest ~]# system-config-authentication &

You can also access the Authentication Configuration application from the GNOME desktop toolbar using System / Administration / Authentication.

This will bring up the Authentication Configuration window.

Figure 1: Authentication Configuration Window

Click the check-box next to Enable LDAP Support under the User Information tab which instructs the system to retrieve user information via LDAP.

Figure 2: Enable LDAP Support for User Information

This will enable the Configure LDAP button to the right of that option. Click on that button to enter your LDAP server settings. Here you enter the LDAP search base DN and the URL address of your LDAP server. If the LDAP server is on the local machine, it is safe to accept the default IP address 127.0.0.1. If the LDAP server is on another machine (which is the case in this guide), enter the IP address or hostname of that server. When using a hostname, make certain it can be resolved with relying on LDAP itself (if your LDAP server is configured to resolve hostnames to IP addresses).

You can also indicate that the LDAP server is using TLS encryption for connections. TLS encryption falls outside the scope of this article and will not be covered.

Figure 3: LDAP Server Settings

Click [OK] on the LDAP Settings dialog.

Next, click on the Authentication tab. This is where you specify that your client machine should use LDAP for authentication and not just user information. Just like with the User Information tab, click the check-box next to Enable LDAP Support which will allow the client authentication through LDAP.

Figure 4: Enable LDAP Support for Authentication

Like before, the Configure LDAP button is enabled after clicking on the check-box. In this case you don't need to enter the LDAP server settings a second time since the information is carried over from the previous step. Even though the information will be identical to that entered on the User Information tab, it is still recommended to verify the settings are correct.

Figure 5: LDAP Server Settings

Finally, click on the Options tab. This is where you can specify any additional authentication options. For this example, select:

Use Shadow Passwords

Local authentication is sufficient for local users

Password hashing algorithm: [SHA256]

Create home directories on the first login

Figure 6: Additional Authentication Options

After setting all of your options, click [OK] to close the window. The system-config-authentication application will configure client authentication to use LDAP.

authconfig - (CLI)

The other method for configuring client authentication in CentOS is the authconfig command. If you don't have a GUI available or prefer the command-line like I do, this is the option to use. As mentioned earlier, the authconfig command-line utility is executed behind the scenes when using the system-config-authentication GUI.

The following authconfig command will perform the same actions and generate the same configuration files that was done using the system-config-authentication GUI in the previous method.


[root@ldaptest ~]# authconfig \ --enableldap \ --enableldapauth \ --ldapserver='ldap://ldapsrv.idevelopment.info/' \ --ldapbasedn='dc=idevelopment,dc=info' \ --enablemkhomedir \ --enableshadow \ --enablelocauthorize \ --passalgo=sha256 \ --update

Verify LDAP Client Configuration

After configuring the LDAP client (using either system-config-authentication or authconfig), verify the the configuration of the client using the authconfig --test command.


[root@ldaptest ~]# authconfig --test caching is disabled nss_files is always enabled nss_compat is disabled nss_db is disabled nss_hesiod is disabled hesiod LHS = "" hesiod RHS = "" nss_ldap is enabled LDAP+TLS is disabled LDAP server = "ldap://ldapsrv.idevelopment.info/" LDAP base DN = "dc=idevelopment,dc=info" nss_nis is disabled NIS server = "" NIS domain = "" nss_nisplus is disabled nss_winbind is disabled SMB workgroup = "MYGROUP" SMB servers = "" SMB security = "user" SMB realm = "" Winbind template shell = "/bin/false" SMB idmap uid = "16777216-33554431" SMB idmap gid = "16777216-33554431" nss_sss is disabled by default nss_wins is disabled pam_unix is always enabled shadow passwords are enabled password hashing algorithm is sha256 pam_krb5 is disabled krb5 realm = "EXAMPLE.COM" krb5 realm via dns is disabled krb5 kdc = "kerberos.example.com:88" krb5 kdc via dns is disabled krb5 admin server = "kerberos.example.com:749" pam_ldap is enabled LDAP+TLS is disabled LDAP server = "ldap://ldapsrv.idevelopment.info/" LDAP base DN = "dc=idevelopment,dc=info" pam_pkcs11 is disabled use only smartcard for login is disabled smartcard module = "coolkey" smartcard removal action = "Ignore" pam_smb_auth is disabled SMB workgroup = "MYGROUP" SMB servers = "" pam_winbind is disabled SMB workgroup = "MYGROUP" SMB servers = "" SMB security = "user" SMB realm = "" pam_sss is disabled by default pam_cracklib is enabled (try_first_pass retry=3) pam_passwdqc is disabled () pam_access is disabled () pam_mkhomedir is enabled () Always authorize local users is enabled () Authenticate system accounts against network services is disabled

Password Hashing

Although authentication for the client was configured in the previous step (using either system-config-authentication or authconfig), there is one last setting that will need to be fixed manually. system-config-authentication and authconfig do not set up proper handling of password hashing in /etc/ldap.conf. Open this file and search for an un-commented line with either of the two directives:


pam_password crypt

or


pam_password md5

This setting needs to be changed so that PAM will not perform a hash on passwords and allow LDAP to handle the hashing. Comment that line out by putting '#' at the beginning and add the following entry in its place:


# pam_password md5 pam_password exop

The above setting will tell the client to use an external operation in LDAP. In this guide, LDAP will use the SSHA algorithm I specified in /etc/slapd.conf on the LDAP server.

 

If you change your configuration in the future using system-config-authentication or authconfig, you will need to remember to redo this manual change in /etc/ldap.conf.

Verify the Connection

The test performed in this section will verify the client and server configuration at one time. This test assumes the LDAP directory already contains users and groups that can authenticate through LDAP. Please refer to the following guide on how to load user and group information into an LDAP directory:

Use the ldapsearch utility to search through the LDAP directory tree to return user and group entries. You will be prompted to enter the password for the rootdn user you specified when installing the LDAP server.

Users


[root@ldaptest ~]# ldapsearch -x -W -D 'cn=Manager,dc=idevelopment,dc=info' -b 'ou=People,dc=idevelopment,dc=info' dn cn Enter LDAP Password: ********* # extended LDIF # # LDAPv3 # base with scope subtree # filter: (objectclass=*) # requesting: dn cn # # People, idevelopment.info dn: ou=People,dc=idevelopment,dc=info # jhunter, People, idevelopment.info dn: uid=jhunter,ou=People,dc=idevelopment,dc=info cn: Jeffrey Hunter # grid, People, idevelopment.info dn: uid=grid,ou=People,dc=idevelopment,dc=info cn: Grid Infrastructure Owner # oracle, People, idevelopment.info dn: uid=oracle,ou=People,dc=idevelopment,dc=info cn: Oracle Software Owner # search result search: 2 result: 0 Success # numResponses: 5 # numEntries: 4

Groups


[root@ldaptest ~]# ldapsearch -x -W -D 'cn=Manager,dc=idevelopment,dc=info' -b 'ou=Group,dc=idevelopment,dc=info' dn cn Enter LDAP Password: ********* # extended LDIF # # LDAPv3 # base with scope subtree # filter: (objectclass=*) # requesting: dn cn # # Group, idevelopment.info dn: ou=Group,dc=idevelopment,dc=info # jhunter, Group, idevelopment.info dn: cn=jhunter,ou=Group,dc=idevelopment,dc=info cn: jhunter # oinstall, Group, idevelopment.info dn: cn=oinstall,ou=Group,dc=idevelopment,dc=info cn: oinstall # asmadmin, Group, idevelopment.info dn: cn=asmadmin,ou=Group,dc=idevelopment,dc=info cn: asmadmin # asmdba, Group, idevelopment.info dn: cn=asmdba,ou=Group,dc=idevelopment,dc=info cn: asmdba # asmoper, Group, idevelopment.info dn: cn=asmoper,ou=Group,dc=idevelopment,dc=info cn: asmoper # dba, Group, idevelopment.info dn: cn=dba,ou=Group,dc=idevelopment,dc=info cn: dba # oper, Group, idevelopment.info dn: cn=oper,ou=Group,dc=idevelopment,dc=info cn: oper # search result search: 2 result: 0 Success # numResponses: 9 # numEntries: 8

Notice when running ldapsearch in the previous example that I didn't need to specify the host for the LDAP server with -h command-line parameter. This is because the client machine I ran the example from was configured with system-wide defaults in the /etc/openldap/ldap.conf file to specify the LDAP server URI:


[root@ldaptest ~]# cat /etc/openldap/ldap.conf # # LDAP Defaults # # See ldap.conf(5) for details # This file should be world readable but not world writable. #BASE dc=example, dc=com #URI ldap://ldap.example.com ldap://ldap-master.example.com:666 #SIZELIMIT 12 #TIMELIMIT 15 #DEREF never URI ldap://ldapsrv.idevelopment.info/ BASE dc=idevelopment,dc=info TLS_CACERTDIR /etc/openldap/cacerts

We can actually take this example one step further and leave out the rootdn user (and password) given my LDAP server is configured with a global read ACL that grants anonymous access:

Users


[root@ldaptest ~]# ldapsearch -x -b 'ou=People,dc=idevelopment,dc=info' dn cn # extended LDIF # # LDAPv3 # base with scope subtree # filter: (objectclass=*) # requesting: dn cn # # People, idevelopment.info dn: ou=People,dc=idevelopment,dc=info # jhunter, People, idevelopment.info dn: uid=jhunter,ou=People,dc=idevelopment,dc=info cn: Jeffrey Hunter # grid, People, idevelopment.info dn: uid=grid,ou=People,dc=idevelopment,dc=info cn: Grid Infrastructure Owner # oracle, People, idevelopment.info dn: uid=oracle,ou=People,dc=idevelopment,dc=info cn: Oracle Software Owner # search result search: 2 result: 0 Success # numResponses: 5 # numEntries: 4

Groups


[root@ldaptest ~]# ldapsearch -x -b 'ou=Group,dc=idevelopment,dc=info' dn cn # extended LDIF # # LDAPv3 # base with scope subtree # filter: (objectclass=*) # requesting: dn cn # # Group, idevelopment.info dn: ou=Group,dc=idevelopment,dc=info # jhunter, Group, idevelopment.info dn: cn=jhunter,ou=Group,dc=idevelopment,dc=info cn: jhunter # oinstall, Group, idevelopment.info dn: cn=oinstall,ou=Group,dc=idevelopment,dc=info cn: oinstall # asmadmin, Group, idevelopment.info dn: cn=asmadmin,ou=Group,dc=idevelopment,dc=info cn: asmadmin # asmdba, Group, idevelopment.info dn: cn=asmdba,ou=Group,dc=idevelopment,dc=info cn: asmdba # asmoper, Group, idevelopment.info dn: cn=asmoper,ou=Group,dc=idevelopment,dc=info cn: asmoper # dba, Group, idevelopment.info dn: cn=dba,ou=Group,dc=idevelopment,dc=info cn: dba # oper, Group, idevelopment.info dn: cn=oper,ou=Group,dc=idevelopment,dc=info cn: oper # search result search: 2 result: 0 Success # numResponses: 9 # numEntries: 8

Test User Authentication Through LDAP

Log in as a directory user to the client machine configured in this guide to test authenticate through LDAP. The example client machine should not have any local user accounts or groups defined with the same name as those being authenticated through the LDAP directory.


[root@testnode1 ~]# ssh jhunter@ldaptest The authenticity of host 'ldaptest (192.168.1.104)' can't be established. RSA key fingerprint is f8:76:8c:98:62:b0:f0:29:21:19:18:ea:f6:24:23:bc. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'ldaptest,192.168.1.104' (RSA) to the list of known hosts. jhunter@ldaptest's password: Creating directory '/home/jhunter'. Creating directory '/home/jhunter/.mozilla'. Creating directory '/home/jhunter/.mozilla/plugins'. Creating directory '/home/jhunter/.mozilla/extensions'. [jhunter@ldaptest ~]$ id uid=500(jhunter) gid=500(jhunter) groups=500(jhunter),1300(dba),1301(oper) [jhunter@ldaptest ~]$ cat /etc/passwd | grep jhunter [jhunter@ldaptest ~]$ cat /etc/group | grep jhunter

Notice that jhunter was able to authenticate through LDAP and log in to the machine. Since this was the first time logging in as the jhunter user, the home directory was automatically created. Also notice that the jhunter user account and the associated groups are not listed in /etc/passwd and /etc/group on the local system. This account was authenticated through LDAP and uses the values from the LDAP server for the account.

Managing LDAP User Accounts

This section covers several administration tasks that can be performed on users and groups in an LDAP directory.

Create a New LDAP User Account and Group

The following example demonstrates how to create a new user account and group in a directory that can authenticate to a client machine through LDAP. The new user account will be named ahunter with a primary group of ahunter. In addition, the new ahunter user account will be added to two already existing groups in the directory named dba and oper.

The directory operations will be performed by creating or modifying a template record in the LDAP Data Interchange Format, or LDIF, file format. A separate LDIF file will be created for the new user account and the new group. The appropriate LDAP client command will then be run to either add, modify, or remove records in the directory using the contents found in the LDIF files.

Create New Group

Start by creating an LDAP record for the new user's group. The LDIF record below demonstrates how to create a new group in LDAP with custom changes like the group name and group ID highlighted in blue.


[root@ldapsrv ~]# vi new-group.ldif dn: cn=ahunter,ou=Group,dc=idevelopment,dc=info objectClass: posixGroup objectClass: top cn: ahunter userPassword: {crypt}x gidNumber: 501 [root@ldapsrv ~]# ldapadd -x -W -h ldapsrv -D "cn=Manager,dc=idevelopment,dc=info" -f new-group.ldif Enter LDAP Password: ********* adding new entry "cn=ahunter,ou=Group,dc=idevelopment,dc=info"

Generate Password Hash for the New User

Before creating a new user account, you must first generate a hash of the user's password. The hashed version of the password will be used in the next section as the userPassword attribute value for the new user. There are several methods to generate the hash; however, I prefer use /usr/sbin/slappasswd.


[root@ldapsrv ~]# /usr/sbin/slappasswd New password: alexpwd123 Re-enter new password: alexpwd123 {SSHA}FNiHoY39y9MOCIzW+IVVDYDmSdlCrx31

Create New User

Using the same method for creating the new group, create or modify a template record in the LDIF file format for the new user. Again, the non-static information for the new user is highlighted in blue. Remember to use the hash generated in the previous step for the userPassword attribute value as well as the correct user ID number (uidNumber) and group ID number (gidNumber) for the user's primary group.


[root@ldapsrv ~]# vi new-user.ldif dn: uid=ahunter,ou=People,dc=idevelopment,dc=info uid: ahunter cn: Alex Hunter givenName: Alex sn: Hunter mail: ahunter@idevelopment.info objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: {SSHA}FNiHoY39y9MOCIzW+IVVDYDmSdlCrx31 shadowLastChange: 15360 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 501 gidNumber: 501 homeDirectory: /home/ahunter gecos: Alex Hunter [root@ldapsrv ~]# ldapadd -x -W -h ldapsrv -D "cn=Manager,dc=idevelopment,dc=info" -f new-user.ldif Enter LDAP Password: ********* adding new entry "uid=ahunter,ou=People,dc=idevelopment,dc=info"

Verify ahunter was added to directory.


[root@ldapsrv ~]# ldapsearch -x -h ldapsrv 'uid=ahunter' # extended LDIF # # LDAPv3 # base <> with scope subtree # filter: uid=ahunter # requesting: ALL # # ahunter, People, idevelopment.info dn: uid=ahunter,ou=People,dc=idevelopment,dc=info uid: ahunter cn: Alex Hunter givenName: Alex sn: Hunter mail: ahunter@idevelopment.info objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword:: e1NTSEF9Rk5pSG9ZMzl5OU1PQ0l6VytJVlZEWURtU2RsQ3J4MzE= shadowLastChange: 15360 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 501 gidNumber: 501 homeDirectory: /home/ahunter gecos: Alex Hunter # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1

Add New User to a Secondary Groups

Next, modify the existing dba and oper group in the directory to add ahunter as a memberUid. Create an LDIF file named modify-oraclegroup.ldif using the following template then run ldapmodify to modify the directory records. It may be helpful to use the verbose option (-v) here to verify the actions performed by ldapmodify.


[root@ldapsrv ~]# vi modify-oraclegroup.ldif dn: cn=dba,ou=Group,dc=idevelopment,dc=info changetype: modify add: memberUid memberUid: ahunter dn: cn=oper,ou=Group,dc=idevelopment,dc=info changetype: modify add: memberUid memberUid: ahunter [root@ldapsrv ~]# ldapmodify -x -W -h ldapsrv -D "cn=Manager,dc=idevelopment,dc=info" -f modify-oraclegroup.ldif -v ldap_initialize( ldap://ldapsrv ) Enter LDAP Password: ********* add memberUid: ahunter modifying entry "cn=dba,ou=Group,dc=idevelopment,dc=info" modify complete add memberUid: ahunter modifying entry "cn=oper,ou=Group,dc=idevelopment,dc=info" modify complete

Verify ahunter was added to the dba and oper group.


[root@ldapsrv ~]# ldapsearch -x -h ldapsrv "(|(cn=dba)(cn=oper))" -b "ou=Group,dc=idevelopment,dc=info" # extended LDIF # # LDAPv3 # base with scope subtree # filter: (|(cn=dba)(cn=oper)) # requesting: ALL # # dba, Group, idevelopment.info dn: cn=dba,ou=Group,dc=idevelopment,dc=info objectClass: posixGroup objectClass: top cn: dba userPassword:: e2NyeXB0fXg= gidNumber: 1300 memberUid: jhunter memberUid: oracle memberUid: ahunter # oper, Group, idevelopment.info dn: cn=oper,ou=Group,dc=idevelopment,dc=info objectClass: posixGroup objectClass: top cn: oper userPassword:: e2NyeXB0fXg= gidNumber: 1301 memberUid: jhunter memberUid: oracle memberUid: ahunter # search result search: 2 result: 0 Success # numResponses: 3 # numEntries: 2

Test User Authentication Through LDAP

Finally, log in as the new directory user to the client machine configured in this guide to authenticate through the LDAP server. The client machine should not have any local user accounts or groups defined with the same name as those being authenticated through the LDAP directory.


[root@ldapsrv ~]# ssh ahunter@ldaptest ahunter@ldaptest's password: alexpwd123 Creating directory '/home/ahunter'. Creating directory '/home/ahunter/.mozilla'. Creating directory '/home/ahunter/.mozilla/plugins'. Creating directory '/home/ahunter/.mozilla/extensions'. [ahunter@ldaptest ~]$ id uid=501(ahunter) gid=501(ahunter) groups=501(ahunter),1300(dba),1301(oper)

Changing User Passwords

The LDAP directory server used in this example is configured with a change user password ACL which allows directory users to change their password.


[ahunter@ldaptest ~]$ passwd Changing password for user ahunter. Enter login(LDAP) password: alexpwd123 New UNIX password: MyN3wPassword Retype new UNIX password: MyN3wPassword LDAP password information changed for ahunter passwd: all authentication tokens updated successfully.

Delete User Account

Use ldapdelete to delete an entry from the LDAP directory.

The following example deletes the ahunter user and his primary group (also ahunter). This example also demonstrates how to remove ahunter as a memberUid of the dba and oper secondary groups.


[root@ldapsrv ~]# ldapdelete -x -W -h ldapsrv -D "cn=Manager,dc=idevelopment,dc=info" "uid=ahunter,ou=people,dc=idevelopment,dc=info" -v ldap_initialize( ldap://ldapsrv ) Enter LDAP Password: ********* deleting entry "uid=ahunter,ou=people,dc=idevelopment,dc=info"


[root@ldapsrv ~]# ldapdelete -x -W -h ldapsrv -D "cn=Manager,dc=idevelopment,dc=info" "cn=ahunter,ou=Group,dc=idevelopment,dc=info" -v ldap_initialize( ldap://ldapsrv ) Enter LDAP Password: ********* deleting entry "cn=ahunter,ou=Group,dc=idevelopment,dc=info"


[root@ldapsrv ~]# vi delete-oraclegroup.ldif dn: cn=dba,ou=Group,dc=idevelopment,dc=info changetype: modify delete: memberUid memberUid: ahunter dn: cn=oper,ou=Group,dc=idevelopment,dc=info changetype: modify delete: memberUid memberUid: ahunter [root@ldapsrv ~]# ldapmodify -x -W -h ldapsrv -D "cn=Manager,dc=idevelopment,dc=info" -f delete-oraclegroup.ldif -v ldap_initialize( ldap://ldapsrv ) Enter LDAP Password: ********* delete memberUid: ahunter modifying entry "cn=dba,ou=Group,dc=idevelopment,dc=info" modify complete delete memberUid: ahunter modifying entry "cn=oper,ou=Group,dc=idevelopment,dc=info" modify complete

About the Author

Jeffrey Hunter is an Oracle Certified Professional, Java Development Certified Professional, Author, and an Oracle ACE. Jeff currently works as a Senior Database Administrator for The DBA Zone, Inc. located in Pittsburgh, Pennsylvania. His work includes advanced performance tuning, Java and PL/SQL programming, developing high availability solutions, capacity planning, database security, and physical / logical database design in a UNIX / Linux server environment. Jeff's other interests include mathematical encryption theory, tutoring advanced mathematics, programming language processors (compilers and interpreters) in Java and C, LDAP, writing web-based database administration tools, and of course Linux. He has been a Sr. Database Administrator and Software Engineer for over 20 years and maintains his own website site at: http://www.iDevelopment.info. Jeff graduated from Stanislaus State University in Turlock, California, with a Bachelor's degree in Computer Science and Mathematics.



Copyright (c) 1998-2017 Jeffrey M. Hunter. All rights reserved.

All articles, scripts and material located at the Internet address of http://www.idevelopment.info is the copyright of Jeffrey M. Hunter and is protected under copyright laws of the United States. This document may not be hosted on any other site without my express, prior, written permission. Application to host any of the material elsewhere can be made by contacting me at jhunter@idevelopment.info.

I have made every effort and taken great care in making sure that the material included on my web site is technically accurate, but I disclaim any and all responsibility for any loss, damage or destruction of data or any other property which may arise from relying on it. I will in no case be liable for any monetary damages arising from such loss, damage or destruction.

Last modified on
Tuesday, 04-Sep-2012 00:30:22 EDT
Page Count: 43839