Skip to main content

Office of Information Technology (OIT)

UT Arlington
OIT: Office of Information Technology

helpdesk@uta.edu · · Work Order · 817-272-2208 · System Status

Frequently Asked Questions

Using CEDAR

How should I request access to CEDAR?

Please refer to the Accessing CEDAR page for information on requesting LDAP access.

Authorization (LDAP)
Authorization services are handled by our Enterprise Directory (LDAP). Access to the directory is restricted, requiring the use of IP-restricted, application-specific, bind credentials. The attributes that each application may access requires approval from the CEDAR Development Team and a higher controlling body made of representatives from various data providers.

To request access to the directory, or to use it for authorization services, you must complete a project request form. If you lack the ability to submit OIT project requests, please email OIT Production Control, providing your name, telephone number, and department.

In your requst, please state the name of your application (including any applicable version information) , the intended use of the data, who will be consuming the data, from which IP address(es) your application will operate, and a list of attributes that you need to access. Once approved, you will be contacted with appropriate credentials as well as a list of attributes that you may access.

Authentication (Kerberos)
Authentication is handled by the MIT Kerberos realm CEDAR.UTA.EDU. This realm is fully supported by UT Arlington's domain name service (DNS) configuration. Most client operating systems will allow you to either specify the Key Distribution Center (KDC) and Kerberos Admin (kadmin) server or have the servers configured dynamically using DNS SVR record identifiers. The use of DNS SRV records is strongly encouraged. If your client requires a manual configuration, please contact us.

Our LDAP directory servers (ldap.cedar.uta.edu) are set up to authenticate using the CEDAR.UTA.EDU Kerberos realm, your application or operating system may be configured to utilize LDAP for authentication. Note that the CEDAR Development Team does not recommend using LDAP in this manner, as the LDAP protocol was designed specifically for authentication. Also note that in order to authenticate someone to LDAP you must attempt to bind to the server with their credentials -- this usually requires you to first obtain their NetID and password internally before processing. If your web application does collect a NetID, you must use SSL encryption. (see UT System Business Procedures Memorandum 53)

LDAP

What is LDAP?

Lightweight Directory Access Protocol (LDAP) is an open-standard protocol for accessing X.500 directory services.

The protocol runs over Internet transport protocols, such as TCP. LDAP is a lightweight alternative to the X.500 Directory Access Protocol (DAP) for use on the Internet. It uses TCP/IP stack verses the overly complex OSI stack. It also has other simplications, such as the representing most attribute values and many protocol items as textual strings, that are designed to make clients easier to implement.

X.500 recommendations are available from the ITU (http://www.itu.int/).

LDAP version 3 (LDAPv3) is an Internet "Proposed Standard" and is documented by the various RFCs, including:

  • RFC 4510 - Lightweight Directory Access Protocol: Technical Specification Road Map
  • RFC 4511 - LDAP: The Protocol * RFC 4512 - LDAP: Directory Information Models
  • RFC 4513 - LDAP: Authentication Methods and Security Mechanisms
  • RFC 4514 - LDAP: DN
  • RFC 4515 - LDAP: Search Filters
  • RFC 4516 - LDAP: URL
  • RFC 4517 - LDAP: Syntaxes and Matching Rules
  • RFC 4518 - LDAP: Internationalized String Preparation
  • RFC 4519 - LDAP: Schema for User Applications

LDAP version 2 (LDAPv2) is a now Historic (see RFC 3494).

What is a Directory?

A directory is a database specifically designed for the searching and browsing of information.

A directory is like a phone book, and is not like a directory (folder) on your computer. Like a phone book, the directory holds information about a thing, like a doctor: First, you find the phone book, then you find "Doctors," then you look for the type of doctor, then you decide which doctor you want to see. The directory is like that.

Directories vs. Relational Database Management Systems

This question is raised many times in different forms. The most common, however, is: Why doesn't OpenLDAP drop Berkeley DB and use a relational database management system (RDBM) instead? In general, expecting that the sophisticated algorithms implemented by commercial-grade RDBM would make OpenLDAP be faster or somehow better and, at the same time, permitting sharing of data with other applications.

The short answer is that use of an embedded database and custom indexing system allows OpenLDAP to provide greater performance and scalability without loss of reliability. OpenLDAP 2.1 (back-bdb) uses Berkeley DB concurrent / transactional database software. This is the same software used by leading commericial directory software.

Now for the long answer. We are all confronted all the time with the choice RDBMs vs. directories. It is a hard choice and no simple answer exists.

It is tempting to think that having a RDBMS backend to the directory solves all problems. However, it is a pig. This is because the data models are very different. Representing directory data with a relational database is going to require splitting data into multiple tables.

Think for a moment about the person objectclass. Its definition requires attribute types objectclass, sn and cn and allows attribute types userPassword, telephoneNumber, seeAlso and description. All of these attributes are multivalued, so a normalization requires putting each attribute type in a separate table.

Now you have to decide on appropriate keys for those tables. The primary key might be a combination of the DN, but this becomes rather inefficient on most database implementations.

The big problem now is that accessing data from one entry requires seeking on different disk areas. On some applications this may be OK but in many applications performance suffers.

The only attribute types that can be put in the main table entry are those that are mandatory and single-value. You may add also the optional single-valued attributes and set them to NULL or something if not present.

But wait, the entry can have multiple objectclasses and they are organized in an inheritance hierarchy. An entry of objectclass organizationalPerson now has the attributes from person plus a few others and some formerly optional attribute types are now mandatory.

What to do? Should we have different tables for the different objectclasses? This way the person would have an entry on the person table, another on organizationalPerson, etc. Or should we get rid of person and put everything on the second table?

But what do we do with a filter like (cn=*) where cn is an attribute type that appears in many, many objectclasses. Should we search all possible tables for matching entries? Not very attractive.

Once this point is reached, three approaches come to mind. One is to do full normalization so that each attribute type, no matter what, has its own separate table. The simplistic approach where the DN is part of the primary key is extremely wasteful, and calls for an approach where the entry has a unique numeric id that is used instead for the keys and a main table that maps DNs to ids. The approach, anyway, is very inefficient when several attribute types from one or more entries are requested. Such a database, though cumbersomely, can be managed from SQL applications.

The second approach is to put the whole entry as a blob in a table shared by all entries regardless of the objectclass and have additional tables that act as indices for the first table. Index tables are not database indices, but are fully managed by the LDAP server-side implementation. This is exactly the approach used by the ldbm backend in slapd. However, the database becomes unusable from SQL. And, thus, a fully fledged database system provides little or no advantage. The full generality of the database is unneeded. Much better to use something light and fast, like Berkeley DB. And it is cheap, too.

A completely different way to see this is to give up any hopes of implementing the directory data model. In this case, LDAP is used as an access protocol to data that provides only superficially the directory data model. For instance, it may be read only or, where updates are allowed, restrictions are applied, such as making single-value attribute types that would allow for multiple values. Or the impossibility to add new objectclasses to an existing entry or remove one of those present. The restrictions span the range from allowed restrictions (that might be elsewhere the result of access control) to outright violations of the data model. It can be, however, a method to provide LDAP access to preexisting data that is used by other applications. But in the understanding that we don't really have a "directory".

Existing commercial LDAP server implementations that use a relational database are either from the first kind or the third. I don't know of any implementation that uses a relational database to do inefficiently what BDB does efficiently.

How do I authenticate users with LDAP in my application?

A common way of authenticating a user with LDAP in another application (such as a Perl script) is to:

  1. Bind with a known user (usually anonymous) and lookup the DN of the UID given.
  2. Try binding with this DN and supplied user password.

Programming

Example PHP Code - Authenticate a user

Please refer to http://php.net/ldap for complete function description and usage.

The typical sequence of LDAP calls you will make in an application will follow this pattern:

ldap_connect() // establish connection to server
ldap_bind() // "login"
...// do something
ldap_close() // "logout"

A detailed example is provided below:

// using ldap bind
$ldapdn = 'uid=maverick,cn=accounts,dc=uta,dc=edu'; // dn of your NetID
$ldappass = 'password'; // your NetID password

// connect to ldap server
$ldapconn = ldap_connect("ldap.cedar.uta.edu") or die("Could not connect to LDAP server.");

if ($ldapconn) {
   // binding to ldap server
   $ldapbind = ldap_bind($ldapconn, $ldapdn, $ldappass);

   // verify binding
   if ($ldapbind) {

      echo "LDAP bind successful...";
   } else {
      echo "LDAP bind failed...";
   }
}

Example PHP Code - Lookup user attributes

Please refer to http://php.net/ldap for complete function description and usage.

This example binds using an application account (cn=applications,dc=uta,dc=edu) and searched the account branch (cn=accounts,dc=uta,dc=edu) for all users (uid=*). It returns the uid (NetID), mail (email address), and cn (common name) attributes for each entry. Finally, it displays them, grouping each user entry.

// using ldap bind
$ldapdn = 'cn=mavapp,cn=applications,dc=uta,dc=edu';
$ldappass = 'mavAppPass';

// connect to ldap server
$ldapconn = ldap_connect("ldap.cedar.uta.edu") or die("Could not connect to LDAP server.");

if ($ldapconn) {
   // binding to ldap server
   $ldapbind = ldap_bind($ldapconn, $ldapdn, $ldappass);

   // verify binding
   if ($ldapbind) {
      echo "LDAP bind successful...";

      // search at this base
      $base_dn = "cn=accounts,dc=uta,dc=edu";

      // only return entries matching this filter
      $filter = "(uid=*)";

      // only return these attributes, or * for all
      $attrs = array("uid","mail","cn");

      $read = ldap_search($ldapconn, $base_dn, $filter, $attrs) or die(">>Unable to search ldap server<<");
      $info = ldap_get_entries($ldapconn, $read);

      echo $info["count"]." entries returned<br>";

      // $i = entries
      // $ii = attributes for entry
      // $iii = values per attribute

      for ($i = 0; $i<$info["count"]; $i++) {
         for ($ii=0; $ii<$info[$i]["count"]; $ii++){
            $data = $info[$i][$ii];
            for ($iii=0; $iii<$info[$i][$data]["count"]; $iii++) {
               echo "$data: $info[$i][$data][$iii]<br>";
            }
         }
         echo "<p>";
         // separate entries
      }
   }
}

Example Perl Code - Lookup user attributes

Please refer to http://search.cpan.org for Net::LDAP and Net::LDAPS module documentation and usage examples.

This example binds using an application account (cn=applications,dc=uta,dc=edu) and searches the account branch (cn=accounts,dc=uta,dc=edu) for all users (uid=*). It returns the uid (NetID), mail (email address), and cn (common name) attributes for each entry. Finally, it displays them, grouping each user entry.

#!/usr/bin/perl -w
use strict;

use Net::LDAPS;

my $bind_dn = 'cn=mavapp,cn=applications,dc=uta,dc=edu';
my $bind_password = 'mavAppPass';

my $ldaps = Net::LDAPS->new('ldap.cedar.uta.edu');
my $mesg = $ldaps->bind( $bind_dn, password => $bind_password );

my $result = $ldaps->search(
   base => "cn=accounts,dc=uta,dc=edu",
   filter => "(uid=*)",

   attrs => ['uid','mail','cn']
);

my $entries = $result->as_struct();

print scalar $entries . " entries returned\n";

foreach my $dn ( keys %{$entries} ) {
   foreach my $attr ( keys %{$entries->{$dn}} ) {
      foreach my $val ( @{$entries->{$dn}->{$attr}} ) {

         print $attr - $val\n";
      }
   }
   print "\n";
}