I’ve used OpenLDAP for my name service at home for several years. I don’t have a ton of databases, but most of the pcs have XE installed and my sandbox server always has multiple Enterprise Edition databases of various versions for me to try things. It wouldn’t be too hard to maintain all of them through TNSNAMES files copied around to each machine. Another option, I could use a shared network mount, pointed to by TNS_ADMIN environment variable. Instead though, I decided I would go with LDAP name resolution. Doing so still gives me centralized management as well as providing me an environment to learn about and use LDAP itself.
Unfortunately, in my latest server build, using Oracle Linux 8, I found the OpenLDAP server is no longer available by simple yum installation with the openldap-servers package. So, in this article I’ll show the steps I used to compile and configure the server software as well as setup the name resolution.
Initial setup and testing mostly followed the Quick Start guide found here: https://www.openldap.org/doc/admin24/quickstart.html . Setup of the TNS name resolution based on OID schema came from notes I kept several years ago from a dizwell.com article which is no longer available. The information there was dated as the current versions of OpenLDAP are installed and configured differently. The schemas were managed externally to the storage mechanism in the old version and portions were installed in /etc by default. The new versions manage the LDAP configuration within itself and use LDIF files instead of schema files. Also, /etc isn’t used as the storage area for configuration files. Still, the old notes acted as an outline to follow and update as I went.
I should note, I am not an LDAP expert, so while the steps I will detail below create a functioning installation – it is a simplified configuration. I do not intend to imply “best practice” in these. I am sure there are more sophisticated installations for better performance, security, and administration. As all of my home use is non-production, what I list below is sufficient for my needs and will hopefully provide a foundation to build and expand on.
First, while the server itself is not available via a yum install, you can still install the libraries and client modules.
yum install openldap openldap-clients
Next, download the OpenLDAP source from https://www.openldap.org/software/download/ then unzip and untar it. At the time of this writing 2.4.48 is most recent version and what I used in my installation.
The Quick Start guide suggests using “./configure” as the simplest startup. However, this install assumes you already have Berkeley DB installed, which I do not. Both BDB and HDB (which uses BDB) are slated for deprecation though in favor of the new Memory-Mapped database (MDB.) So removing BDB and HDB support not only negates the need for additional installs, it also uses a backend that is the direction of the OpenLDAP project anyway. Thus, I removed those DBs in my configuration steps
./configure --disable-bdb --disable-hdb make depend make
It’s not strictly necessary, but it is possible to have the make process run an extensive series of tests prior to continuing. As I had never done this before I ran the full suite. It took a several minutes but confirmed everything looked good to continue. Had the tests failed I would have needed to dig into the configure and compilation documentation for how to proceed.
make test
After the tests completed, the last make step is the install which creates many files under /usr/local/etc/openldap. This destination is configurable, but using the defaults as I did, this is where they ended up.
The steps below are all performed as root.
make install cd /usr/local/etc/openldap
Another slight deviation from the Quick Start guide, it shows using a plain text password. While that is fine for illustration purposes, it is better to use a secure hash. So you can use slappasswd utility to create a hash. Obviously you should use a different password than “secret” as shown here.
slappasswd -s secret {SSHA}wwqfTd+b25PPnBMkqFoL8ytRqd1IisPZ
Once you have your hash, you will edit the slapd.ldif file. There should be a section for the Lightning Memory-Mapped Database (LMDB) configuration which you will customize for your installation, changing the portions in [] as needed.
####################################################################### # LMDB database definitions ####################################################################### # dn: olcDatabase=mdb,cn=config objectClass: olcDatabaseConfig objectClass: olcMdbConfig olcDatabase: mdb OlcDbMaxSize: 1073741824 olcSuffix: dc=[MY-DOMAIN],dc=[COM] olcRootDN: cn=Manager,dc=[MY-DOMAIN],dc=[COM] olcRootPW: {SSHA}[INSERT-YOUR-SLAPPASSWD-HASH-HERE] olcDbDirectory: /usr/local/var/openldap-data olcDbIndex: objectClass eq
The olcDbDirectory value will default to /usr/local/var/openldap-data. You must create this directory and should secure it. The Quick Start guide doesn’t specify the next steps but continues on the assumption you have created an additional configuration directory as well and you will use the LDIF file you just modified to begin populating it.
mkdirchmod 700 mkdir /usr/local/etc/slapd.d slapadd -n 0 -F /usr/local/etc/slapd.d -l /usr/local/etc/openldap/slapd.ldif
Next we will start the LDAP server process and perform a top level search to confirm initialization has worked as expected.
/usr/local/libexec/slapd -F /usr/local/etc/slapd.d ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts
Create a new LDIF file (myinit.ldif in my example) to seed some sample objects with the following contents, populating for your install as needed.
dn: dc=[MY-DOMAIN],dc=[COM] objectclass: dcObject objectclass: organization o: My Sample Server dc:dn: cn=Manager,dc=[MY-DOMAIN],dc=[COM] objectclass: organizationalRole cn: Manager
Add your objects to the database and then search for them.
ldapadd -a -x -D "cn=Manager,dc=[MY-DOMAIN],dc=[COM]" -W -f myinit.ldif ldapsearch -x -b 'dc=[MY-DOMAIN],dc=[COM]' '(objectclass=*)'
At this point the server should be running and is ready for use. The Quick Start steps have been exhausted and it’s time to add the schema definitions needed for TNS name resolution. For this we will need an administrative login to the configuration database. An LDIF file will have been created under the slapd.d tree. Edit the file to set the Root DN and Password values. For simplicity I’ll show the plain text password but you should generate a slappasswd hash as shown above and use a hash here as well.
vi /usr/local/etc/slapd.d/cn=config/'olcDatabase={0}config.ldif'
olcRootDN: cn=admin,cn=config olcRootPW: secret
Stop and restart the service to load the new configuration. Then import some of the schema files already provided by the make process. These define object types needed by the OID schemas.
kill -INT `cat /usr/local/var/run/slapd.pid` /usr/local/libexec/slapd -F /usr/local/etc/slapd.d ldapadd -h localhost -x -W -f schema/cosine.ldif -D "cn=admin,cn=config" ldapadd -h localhost -x -W -f schema/inetorgperson.ldif -D "cn=admin,cn=config" ldapadd -h localhost -x -W -f schema/nis.ldif -D "cn=admin,cn=config"
Next, the LDIF files defining the OID schemas are needed and they can found in a tar.gz file here. The next instructions assume the extracted files are in the current directory. If you have placed them in different path then simply include that path (relative or exact) in each command below.
ldapadd -h localhost -x -W -f alias.ldif -D "cn=admin,cn=config" ldapadd -h localhost -x -W -f oidbase.ldif -D "cn=admin,cn=config" ldapadd -h localhost -x -W -f oidnet.ldif -D "cn=admin,cn=config" ldapadd -h localhost -x -W -f oidrdbms.ldif -D "cn=admin,cn=config"
Now that the schemas have been defined we can create the orclContext hierarchy in our LDAP database. Edit a file “oid.ldif” as follows using values of your installation.
dn: dc=[MY-DOMAIN],dc=[COM]> objectClass: top objectClass: dcObject objectClass: organization o: Oracle Internet Directory dc: [MY-DOMAIN] dn: cn=OracleContext,dc=[MY-DOMAIN],dc=[COM] objectclass: orclContext cn: OracleContext
Import your LDIF.
ldapadd -c -x -D "cn=Manager,dc=[MY-DOMAIN],dc=[COM]" -W -f oid.ldif
At this point your directory is ready to add your name resolution rules. As with all of the other changes these will be added through LDIF files. Here is an example of one where I map the name “testxe” to one of my pcs, named simply enough ‘”testpc”, running Oracle XE. Note the TNS name is entered twice, once in the dnline and again on the cn line.
dn: cn=testxe,cn=OracleContext,dc=[MY-DOMAIN],dc=[COM] objectclass: top objectclass: orclNetService cn: testxe orclNetDescString: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=testpc)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=xe)))
Add the name lookup.
ldapadd -c -x -D "cn=Manager,dc=[MY-DOMAIN],dc=[COM]" -W -f addname.ldif
To begin using it we simply need to add LDAP to the sqlnet.ora directory path and edit the ldap.ora to point to our new server and context.
### SQLNET.ORA NAMES.DIRECTORY_PATH=(TNSNAMES, LDAP, EZCONNECT) ### LDAP.ORA DIRECTORY_SERVERS= ([my-ldap-host]:389) DEFAULT_ADMIN_CONTEXT = "dc=[MY-DOMAIN],dc=[COM]" DIRECTORY_SERVER_TYPE = OID
Now we can begin using the name.
$ tnsping testxe TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 29-DEC-2019 15:31:33 Copyright (c) 1997, 2019, Oracle. All rights reserved. Used parameter files: /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/sqlnet.ora Used LDAP adapter to resolve the alias Attempting to contact (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=testpc)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=xe)))
Additional names can be added through more LDIF files, using LDAP editing tools such as JXplorer, or, my prefered method, using a PL/SQL interface such as my package described here. I hope this helps others that may be struggling with the disappearance of openldap-servers from yum and in the establishment of a simple name resolution service without needing a full OID install.
hi; i did a similar thing…
installed from EPEL the ‘389 directory server’ – it’s a free software variant of the redhat ds. it’s also somehow based on slapd; see https://en.wikipedia.org/wiki/389_Directory_Server
yum install –enablerepo=epel 389-ds-base
easiest way to add the minimal for me working oracle schema definitions to the schema was to add this to /etc/dirsrv/slapd-localhost/schema/99user.ldif:
attributeTypes: ( 2.16.840.1.113894.3.1.13 NAME ‘orclNetDescString’ EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
attributetypes: ( 2.16.840.1.113894.3.1.17 NAME ‘orclNetAddrList’ DESC ‘boo’ EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
attributetypes: ( 2.16.840.1.113894.3.1.12 NAME ‘orclNetDescName’ EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributetypes: ( 2.16.840.1.113894.3.1.6 NAME ‘orclNetServiceName’ EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
attributetypes: ( 2.16.840.1.113894.3.1.14 NAME ‘orclNetAddressString’ EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
attributetypes: ( 2.16.840.1.113894.3.1.15 NAME ‘orclNetProtocol’ EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
objectclasses: ( 2.16.840.1.113894.7.2.3 NAME ‘orclContext’ SUP ‘top’ STRUCTURAL MUST ( cn ) )
objectclasses: ( 2.16.840.1.113894.7.2.3 NAME ‘orclContext’ SUP ‘top’ STRUCTURAL MUST ( cn ) )
objectclasses: ( 2.16.840.1.113894.3.2.3 NAME ‘orclNetDescription’ SUP ‘top’ STRUCTURAL MUST ( cn ) MAY ( orclNetAddrList $ orclNetServiceName))
objectclasses: ( 2.16.840.1.113894.3.2.5 NAME ‘orclNetService’ SUP ‘top’ STRUCTURAL MUST ( cn ) MAY ( orclNetDescName $ orclNetDescString ) )
objectclasses: ( 2.16.840.1.113894.3.2.2 NAME ‘orclNetAddressList’ SUP ‘top’ STRUCTURAL MUST ( cn ) MAY ( orclNetAddrList ) )
objectclasses: ( 2.16.840.1.113894.3.2.1 NAME ‘orclNetAddress’ SUP ‘top’ STRUCTURAL MUST ( cn ) MAY ( orclNetAddressString $ orclNetProtocol) )
hope that helps
i just wonder why i had to make more entries then above, where only a orclNetDescString was sufficient. maybe because my tns connection string has more than one server..
I’m afraid I don’t know anything about the 389 server setup myself. I’ve only ever dabbled with openldap.
The ldap schema does define more fields than are strictly necessary; but I never had a need to try to adjust it to only what was strictly needed for my minimal usage.
I use the whole schema files so the structure would match what is expected by other Oracle tools even if the name lookup itself only needs a subset of the fields.
Sean, great how-to article! I build my openldap in 2016 to replace the old Oracle oid/names server. Has been working for 6 years. in the process to replace linux 6 vm with 8; used your article and got it up and running in no time ! the only thing i can’t figure out is sql developer doesn’t connect to my new ldap (does work with my older one…) have you tried it on your end?
Yes, I have used sql developer with my ldap setup. I just set up a new connection again to make sure.
My only complaint is the “Load” button is kind of slow, even for a short list.
But it’s only a couple seconds so it doesn’t really impact me.
I didn’t do anything special that I can think of.
Connection Type – LDAP
LDAP Server: myhost:389:636 — yours will be different
Context: dc=mydomain,dc=home — yours will be different
Then click Load, wait a second or two and then the DB Service dropdown is populated with my connect strings.
The LDAP Server and Context values were pulled from my ldap.ora
I just thought of something.
I have my TNS_ADMIN environment variable set. So that tells sqldeveloper where to find my ldap.ora.
I just tried unsetting it and then restarting sqldeveloper and then the server/context dropdowns were blank.