LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Blogs > anomie
User Name
Password

Notices


Rate this Entry

OpenLDAP and Perl

Posted 01-12-2012 at 05:15 PM by anomie
Updated 01-12-2012 at 05:19 PM by anomie

I recently deployed a slapd(8) instance, and immediately recognized the need for a robust directory entry management utility. After doing some reading and experimentation, I discovered that Perl - and a few accompanying modules - handle the job nicely. What I'm sharing here is a brief, rather disjointed synopsis and some code samples.

In order to understand and use the samples, you should be comfortable with Perl and the installation of modules. And you'll certainly want a good fundamental understanding of LDAPv3 itself. (Both are outside the scope of this post.)

References
Useful Lingo

Before we get started, there are some acronyms and other terminology that you should become familiar with. This list is very limited, and is no substitute for a strong understanding of the object class you will be working with (e.g. inetOrgPerson).

Code:
      |                                          |
 TERM |         DESCRIPTION                      |         EXAMPLE 
--------------------------------------------------------------------------------------
      | Distinguished name of an LDAP entry.     | dn: 
dn    | (Uniquely identifies it.)                | uid=tia,ou=users,dc=shushu,dc=local 
      |                                          |
--------------------------------------------------------------------------------------
      | Relative distinguished name of an LDAP   | rdn:
rdn   | entry. (Think of 'rdn' as relative name, | uid=tia
      | vs. 'dn' as fully-qualified name.)       |
--------------------------------------------------------------------------------------
      | Domain component. For instance, in the   | dc:
dc    | root DN "dc=shushu,dc=local", the first  | shushu
      | domain component is "shushu".            | 
--------------------------------------------------------------------------------------
      | Common name. An entry attribute that,    | cn: 
cn    | for user entries, is often first and     | Tia Sato
      | last name.                               | 
--------------------------------------------------------------------------------------
      | User account ID. Another entry attribute | uid: 
uid   | often used to identify users.            | t.sato
      |                                          |
Connecting to your LDAP service with Perl

The first example utilizes Net::LDAP to connect to a localhost instance. Note the bind->code check; this is generally important for error handling after Net::LDAP operations.

Code:
#!/usr/bin/perl
 
use warnings ;
use strict ;
use Net::LDAP ;
 
my $auth_account = qq/cn=Mr Admin,dc=shushu,dc=local/ ; 
my $auth_pass    = qq/good.nice.password/ ;
 
# Connect to the OpenLDAP daemon
my $ldap_conn = Net::LDAP->new("localhost", port => 389, timeout => 15)
  or die "Unable to connect to LDAP server: $@" ;
 
# Login (aka "bind") to the directory
my $bind = $ldap_conn->bind($auth_account, password => $auth_pass ) ;
 
# Check code for success or failure (0 is success)
if($bind->code) {
  die $bind->error_name . ': ' . $bind->error_text ;
}
Connecting to the same localhost instance over TLS (assuming it's configured and available) is only slightly different. We simply use Net::LDAPS instead.

Code:
...
use Net::LDAPS ;
...
# Connect to the OpenLDAP daemon
my $ldap_conn = Net::LDAPS->new("localhost", port => 636, timeout => 15)
  or die "Unable to connect to LDAP server: $@" ;
Performing a search using Perl

In order to ensure that we're writing proper and efficient search criteria, a quick look at search scope first.
  • sub -- Recursively search all subtrees / entries below the specified entity
  • one -- Search only the immediate children of the specified entity
  • base -- Search only the specified entity itself

In the code example that follows, search scope is specified in the Net::LDAP->search( scope => ... ) value.

Code:
# Code assumes active, authenticated Net::LDAP session in $ldap_conn..

my $cn = 'Beverly Xin' ;
 
my $search = $ldap_conn->search(
  base   =>     "ou=users,dc=shushu,dc=local",
  scope  =>     "one",
  filter =>     "cn=$cn") ;
 
# Unbind when finished with the query
$ldap_conn->unbind() ;

print $search->error_name . ': ' . $search->error_text . "\n" ;
 
foreach($search->entries) {

  print $_->ldif() ;
 
}
Some points to note about the code above: The Beverly Xin cn is a child of ou=users, so we use the "one" scope. We are able to unbind() after $ldap_conn->search(), because the results (if any) are stored in the $search object.

Adding a new entry using Perl

This example provides a way to add users without using LDIF entries. Note the error checking via Net::LDAP->code.

Code:
# Code assumes active, authenticated Net::LDAP session in $ldap_conn..

my $dn = 'cn=Sasha Lee,ou=users,shushu,dc=local' ;
my $cn = 'Sasha lee' ;
my $sn = 'Lee' ;
my $uid = 's.lee' ;
my $mail = 'sasha.lee@shushu.local' ;
my @dept = ['Info Tech', 'Financial'] ;
my $objclass = 'inetOrgPerson' ;
 
my $add =
  $ldap_conn->add( $dn,
         attr => [ 'cn' => $cn, 
                   'sn' => $sn, 
                   'uid' => $uid,
                   'mail' => $mail,
                   'departmentNumber' => @dept,
                   'objectClass' => $objclass ] ) ;
 
# add() failure checking ('code' is 0 upon success)
if($add->code) {
  die $add->error_name . ': ' . $add->error_text ;
}
Deleting an entry using Perl

This example deletes the user we just created - referring to the entry by dn.

Code:
# Code assumes active, authenticated Net::LDAP session in $ldap_conn..

my $dn = 'cn=Sasha Lee,ou=users,shushu,dc=local' ;
 
my $delete = $ldap_conn->delete($dn) ;
 
# delete() failure checking ('code' is 0 upon success)
if($delete->code) {
  die $delete->error_name . ': ' . $delete->error_text ;
}
Modifying entry attributes using Perl

Modifying entries is slightly more complicated. At least three types of modifications can be made:
  1. Attributes can be added
  2. Attributes can be deleted
  3. Attributes can be changed

The following example provides a look at all three operations.

Code:
# Code assumes active, authenticated Net::LDAP session in $ldap_conn..

my $dn = 'cn=Crystal Zhao,ou=users,dc=shushu,dc=local' ;
 
# Replace attribute (i.e. change an existing value to a new value)
my $mod = $ldap_conn->modify($dn, 
            replace => { 'mail' => 'hmm@localhost' } ) ;
 
# Status checking ('code' is 0 upon success)
if($mod->code) {
  die $mod->error_name . ': ' . $mod->error_text ;
}
 
# ------------------------------------------------------------------- #
 
# Add attribute values
$mod = $ldap_conn->modify($dn, 
          add => { 'departmentNumber' => ['Unknown', 'Payroll'] } ) ;
 
# Status checking ('code' is 0 upon success) and commit
if($mod->code) {
  die $mod->error_name . ': ' . $mod->error_text ;
}
 
# ------------------------------------------------------------------- #
 
# Delete attribute by value
$mod = $ldap_conn->modify($dn, 
          delete => { 'departmentNumber' => 'Unknown' } ) ;
 
# Status checking ('code' is 0 upon success) and commit
if($mod->code) {
  die $mod->error_name . ': ' . $mod->error_text ;
}
 
# Alternatively, we can delete all attribute values
$mod = $ldap_conn->modify($dn, 
          delete => [ 'departmentNumber' ] ) ;
 
# Status checking ('code' is 0 upon success) and commit
if($mod->code) {
  die $mod->error_name . ': ' . $mod->error_text ;
}
This approach is not the only (or necessarily the best) way to modify entries. The Net::LDAP module also provides an excellent interface through Net::LDAP::Entry.
Posted in Uncategorized
Views 3552 Comments 0
« Prev     Main     Next »

  



All times are GMT -5. The time now is 07:18 AM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration