OUD&EUS Take 1: DB Accounts Stored in OUD

By Sylvain Duloutre on Jul 09, 2013

This post is the first one of a serie focusing on Enterprise User Security (EUS) and Oracle Unified DIrectory (OUD).

Enterprise User Security (EUS), an Oracle Database Enterprise Edition feature, leverages the Oracle Directory Services and gives you the ability to centrally manage database users and role memberships in an LDAP directory. EUS reduces administration costs and increases security

Storing DB Accounts in OUD

OUD is specifically tailored to work seamlessly with EUS. Database user information, passwords and privileges information for a database or for a database domain can be stored in OUD.

EUS can leverage existing user and group information stored in OUD to provide single password authentication and consistent password policy across enterprise applications. User data, database meta-data, such as DB registration information, user/role Mappings, and other EUS specific meta-data are stored in OUD using a specific, supported, read-to-use LDAP schema. These meta-data are stored in a separate OUD suffix, called Oracle Context, making a clean logical separation between EUS data and user information that can be shared across applications.

In addition to providing centralized database user management, Enterprise EUS provides three different methods of user authentication: X.509 certificate authentication (introduced in DB 8i); Password-based authentication (since DB 9i); and authentication via Kerberos (since DB 10g). OUD support for Password-based authentication for EUS was introduced in OUD 11gR2. The other authentication methods were introduced in OUD 11gR2PS1.

In the password authentication scenario, the database does not perform user authentication via LDAP bind to OUD. Instead the database collects user credentials, hashes the password, and compares the password hash value retrieved from OUD. More detailed information about EUS can be found in the Enterprise User Administrator’s Guide in the Database documentation section on OTN.


OUD Database Indexes & Performance Tuning

Oracle Unified Directory (OUD) database indexes enable (search) directory requests  to be processed efficiently.

Indexes are files that contain lists of values, where each value is associated with a list of entry identifiers to suffixes in the directory server database. When the directory server processes a search request, it searches the database using the list of entry identifiers in the indexes, thus speeding up the search. If indexes did not exist, the directory server would have to look up each entry in the database, which dramatically degrades performance.

First of all, unindexed searches are rejected by default unless the (authenticated)  user has the privilege to perform them because unindexed searches  may negatively impact overall directory performances. In some circumstances, unindexed searches are a valid approach, so it is possible to explicitely  assign the unindexed-search privilege to a user or a group of user. A user attempting to perform an unindexed search gets the message “you do not have sufficient privileges to perform an unindexed search”.

Note that unindexed searches always complete sucessfully when the amount of entries in the database does not exceed the value if index-entry-limit (4000 by default), which is unlikely to be seen in real deployments.

The verify-index command can be used to check the consistency between the index and entry data within the directory server database. This command also provides information about the number of index keys that have reached the index entry limit (See below).

The rebuild-index command can be used to rebuild an index. It is useful in the following cases:

  • When the index-entry-limit property of an index changes
  • When a new index is created

The index-entry-limit tuning parameter (known as AllIDs threshold in Oracle Directory Server Entreprise Edition) controls the maximum numbers of entries kept in an index record as scaning the whole database may become a more efficient option when the number of entries associated with a given index value becomes huge.

Tuning indexes upfront may not be an obvious task, that’s the reason why OUD provides you with  both  static and  dynamic index analyser tools:

The static analyser is delivered as part of the dbtest tool.  The dbtest list-index-status -n <dbName> -b <dbSuffix> command let you figure out how many entries are associated with each index value, and tune index-entry-limit when needed..

The dynamic analyser can be used to monitor live search filters received by OUD and corresponding  index usage: Live index analysis must be first enabled at the database level. At that point, subsequent searches hitting OUD are analysed and the corresponding statistics are kept in memory.  Statistics can be retrieved from the in-memory suffix cn=monitor as part of the database environmenent entry.

To enable live index data collection, run  the following command:

$ dsconfig set-workflow-element-prop –element-name userRoot  –set index-filter-analyzer-enabled:true  –set max-entries:100 -h localhost -p 4444 -D cn=directory\ manager -w <password>

The set-max-entries parameter controls how many statistical records are kept in memory.

To retrieve the results, run the following search:

$ ldapsearch -p 1389 -D cn=directory\ manager -w <password>  -b “cn=<dbName> Database Environment,cn=monitor”  “(objectclass=*)”  filter-usefilter-use: (description=*) hits:2 maxmatches:-1 message:presence index type is disabled for the description attribute

Important note:  It is not recommanded to enable statistic collection in a production system for a long time as it consumes ressources.

It is also possible to use the operational attribute debugsearchindex to figure out which entries are targetted by each component of a LDAP search filter. This is a lightweight yet convenient way to debug index-related issues.

$ ./ldapsearch -p 11389 -b “o=example” -D “cn=directory manager” -w *** “(&(uid=user.9*)(objectclass=*))”debugsearchindex
dn: cn=debugsearch
debugsearchindex: filter=(&(objectClass=*)[NOT-INDEXED](uid=user.9*)[COUNT:111]) [COUNT:111] scope=wholeSubtree[LIMIT-EXCEEDED:4101] final=[COUNT:111]