Directory Software Options

Understanding and Deploying LDAP Directory Services > 21. Directory-Enabling ExistingApplications > Example 1: A Directory-Enabled finger Service

<  BACK CONTINUE  >
153021169001182127177100019128036004029190136140232051053054012002234180116211133139101

Example 1: A Directory-Enabled finger Service

A finger service is a simple client/server account lookup mechanism supported by all UNIX operating systems. A finger client exists for most desktop operating systems, including all flavors of UNIX, Microsoft Windows, and Apple MacOS. A finger server, included with all UNIX systems, can return information about local accounts to all finger clients on the network ( finger servers have been developed for non-UNIX systems as well). The finger clients and servers communicate using a simple text-based protocol.

Assuming that many end users have access to a finger client and know how to use it, it's sensible to make some of the people information stored in a directory service available via finger . In this section, we provide source code and usage examples for a directory-enabled finger server written in Perl. Our service searches an LDAP directory and returns information about people.

The Integration Approach

Our goal is to leverage the knowledge and client software that users already have, so we use a gateway to integrate finger with LDAP. On most UNIX systems, an executable called in.fingerd is used in response to incoming finger protocol requests . By replacing that executable with our own script that understands the finger protocol but speaks LDAP to retrieve information, we maintain compatibility with existing clients.

Our LDAP finger gateway is a standalone executable ”it does not execute within the confines of an existing application. Therefore, nearly any programming language that provides access to LDAP could be used. We chose to write our gateway by using the Perl 5 language and the PerLDAP object-oriented LDAP access module available from Netscape's developer Web site. This choice allows rapid prototyping, provides maximum portability for our code, and performs acceptably. Our ldapfinger.pl script replaces the in.xfingerd binary program executed by UNIX's inetd process, which is responsible for executing a variety of Internet services.

The Source Code

The source code consists of a single script, which we present here in pieces to aid understanding. The prelude and main module are shown in Listing 21.1.

Listing 21.1 The ldapfinger.pl prelude and main module

1. #!/usr/local/bin/perl 2. # 3. # fingerd -- Perl 5 script that implements the server side 4. # of the finger protocol using an LDAP server as its 5. # database of user information. 6. # 7. # Requires: PerLDAP 8. # 9. use Mozilla::LDAP::Conn; 10. # LDAP server information 11. $ldapbase = "dc=airius,dc=com"; 12. $ldaphost = "ldap.airius.com"; 13. $ldapport = "389"; 14. # constants 15. $unknown = "???"; 16. $separator = "\n"; 17. @attrlist = ( "cn", "uid", "mail", "departmentnumber", 18. "telephonenumber", "roomnumber", "postaladdress", 19. "ou", "title", " displayname ", "description", 20. "labeleduri" ); 21. # Start of main: 22. print "LDAP Finger Service\n\n"; 23. # grab query string and chop off newline and return characters 24. $query = <STDIN>; 25. chop $query; 26. if ( $query =~ /\r$/ ) { 27. chop $query; 28. } 29. # form filter using query string 30. $filter = "(&(objectClass=person)" 31. . "((sn=$query)(cn=$query)(uid=$query)))"; 32. # open an anonymous connection to the LDAP server 33. $ldap = new Mozilla::LDAP::Conn( $ldaphost, $ldapport ); 34. die "Unable to connect to server at " 35. . "ldap://$ldaphost:$ldapport\n" unless $ldap; 36. # search it 37. $entry = $ldap->search( $ldapbase, " subtree ", $filter, 38. 0, @attrlist ); 39. # display results 40. if ( $entry ) { 41. $count = 0; 42. do { 43. displayEntry( $entry ); 44. $entry = $ldap->nextEntry; 45. ++$count; 46. } while ( $entry ); 47. if ( $count >1 ) { 48. print $count, " entries matched '$query'\n"; 49. } else { 50. print "One entry matched '$query'\n"; 51. } 52. } else { 53. print "No entries matched '$query'\n"; 54. } 55. # clean up 56. $ldap->close; 57. # End of main.

The following list summarizes the actions performed in Listing 21.1:

  1. The LDAP server information is specified on lines 10 “13. Constants used elsewhere in the script are defined on lines 14 “20.

  2. When executed, the main module displays a banner string that lets the user know that he has connected to an LDAP finger service (line 22).

  3. The query string sent by the client is read and cleaned up. In the finger protocol, the client sends a text query string that is terminated with a newline and a carriage return. The Perl code on lines 23 “28 reads the query string from standard input and removes any end-of-line characters ( inetd always arranges for protocol data sent by clients to be passed to standard input).

  4. The query string is used to form an LDAP search filter (lines 29 “31).

  5. The code on lines 32 “57 uses PerLDAP calls to connect to the LDAP server, perform one search, and display any entries found.

The work to produce a nicely formatted entry display is done by the displayEntry subroutine, which is shown in Listing 21.2.

Listing 21.2 The ldapfinger.pl displayEntry subroutine

1. # Start of displayEntry: 2. sub 3. displayEntry { 4. local( $entry ) = @_; 5. local( $value, @attrs ); 6. @attrs = ( "displayName", "cn" ); 7. printf( "Login name : %-8s " 8. . " In real life: %s\n", 9. getSimpleValue( $entry, "uid" ), 10. getFirstValue( $entry, *attrs )); 11. printf( "E-Mail: %-32s Phone: %s\n", 12. getSimpleValue( $entry, "mail" ), 13. getSimpleValue( $entry, "telephonenumber" )); 14. @attrs = ( "ou", "departmentnumber" ); 15. printf( "Department: %-32s Room: %s\n", 16. getFirstValue( $entry, *attrs ), 17. getSimpleValue( $entry, "roomnumber" )); 18. $value = getSimpleValue( $entry, "postaladdress" ); 19. if ( $value ne $unknown ) { 20. print "Address: $value\n"; 21. } 22. $value = getSimpleValue( $entry, "title" ); 23. if ( $value ne $unknown ) { 24. print "Title: $value\n"; 25. } 26. $value = getSimpleValue( $entry, "description" ); 27. if ( $value ne $unknown ) { 28. print "Description: $value\n"; 29. } 30. displayAllValues( $entry, "labeleduri", "URL: " ); 31. print $separator; 32. } 33. # End of displayEntry.

The displayEntry subroutine is straightforward. It uses simple printf statements to produce a formatted display of an LDAP entry. The resulting text is sent to standard output, which the UNIX inetd process has arranged to be sent back to the finger client.

Three additional subroutines are used by displayEntry : displayAllValues , getSimpleValue , and getFirstValue . These three subroutines are shown in Listing 21.3.

Listing 21.3 Additional ldapfinger.pl display subroutines

1. # Start of displayAllValues: 2. sub 3. displayAllValues { 4. local( $entry, $attr, $prefix ) = @_; 5. local( $value ); 6. if ( $entry->{$attr} ) { 7. foreach $value (@{$entry->{$attr}}) { 8. print $prefix, $value, "\n"; 9. } 10. } 11. } 12. # End of displayAllValues. 13. # Start of getSimpleValue: 14. sub 15. getSimpleValue { 16. local( $entry, $attr ) = @_; 17. local( $value ); 18. if ( $entry->{$attr} ) { 19. $value = $entry->{$attr}[0]; 20. } else { 21. $value = $unknown; 22. } 23. $value; 24. } 25. # End of getSimpleValue. 26. # Start of getFirstValue: 27. sub 28. getFirstValue { 29. local( $entry, *attrs ) = @_; 30. local( $a ); 31. local( $value ); 32. $value = $unknown; 33 foreach $a (@attrs) { 34 $value = getimpleValue( $entry, $a ); 35. last if ( $value ne $unknown ) 36. } 37. $value; 38. } 39. # End of getFirstValue.

All these display subroutines access values from an LDAP entry by using PerLDAP's attribute hash array.

Finally, the system's /etc/inetd.conf configuration file has to be modified to tell inetd to execute our script instead of the standard in.fingerd executable. Listing 21.4shows the altered portion of the /etc/inetd.conf file used on a Sun Solaris 2.6 UNIX system.

Listing 21.4 Changes to /etc/inetd.conf to enable the ldapfinger.pl script

1.#finger stream tcp nowait nobody /usr/sbin/in.fingerd in.fingerd 2. finger stream tcp nowait nobody /usr/local/etc/ldapfinger.pl ldapfinger.pl

Line 1, which is commented out, is the line originally used to invoke the standard in.fingerd executable. Line 2 is the line we added to invoke our new ldapfinger.pl Perl script. It assumes that we have installed the script in the /usr/local/etc directory.

The Resulting End User Experience

Listing 21.5shows a finger command along with its output produced by a standard, non “LDAP-enabled UNIX finger service.

Listing 21.5 A non-LDAP-enabled UNIX finger lookup for dsmith

% finger dsmith@airius.com Login name: dsmith In real life: Daniel Smith Directory: /u/dsmith Shell: /bin/tcsh On since Jul 14 09:05:10 on console from :0 8 minutes 42 seconds Idle Time No unread mail Project: Human Resources web site Plan: Send me e-mail at dsmith@airius.com

Listing 21.6shows a lookup using our LDAP directory-enabled finger service. In this case, only one entry matches the query string.

Listing 21.6 An LDAP finger lookup for smith

% finger smith@airius.com [airius.com] LDAP Finger Service Login name: dsmith In real life: Daniel Smith E-Mail: dsmith@airius.com Phone: +1 408 555 9519 Department:Human Resources Room: 0368 One entry matched 'smith'

An LDAP-enabled finger example that returns an entry with more attributes is shown in Listing 21.7. Babs's entry contains postalAddress and labeledURI attributes (which Daniel Smith's entry did not have in Listing 21.6).

Listing 21.7 . An LDAP finger lookup for bjensen

LDAP finger lookup for % finger bjensen@airius.com [airius. com] LDAP Finger Service Login name: bjensen In real life: Barbara Jensen E-Mail: bjensen@airius.com Phone: +1 408 555 1862 Department: Product Development Room: 0209 Address: 1234 Airius Way $ Mountain View, CA 94043 URL:http://www.airius.com/babs My Home Page One entry matched 'bjensen'

A final example is shown in Listing 21.8. Nine entries match the query string jensen ; our service returns information about all of them, along with the number of entries found.

Listing 21.8 An LDAP finger lookup for jensen

% finger jensen@airius.com [airius.com] LDAP Finger Service Login name: kjensen In real life: Kurt Jensen E-Mail: kjensen@airius.com Phone: +1 408 555 6127 Department: Product Development Room: 1944 Login name: bjensen In real life: Barbara Jensen E-Mail: bjensen@airius.com Phone: +1 408 555 1862 Department: Product Development Room: 0209 Address: 1234 Airius Way $ Mountain View,CA 94043 URL: http://www.airius.com/babs My Home Page Login name: gjensen In real life: Gern Jensen E-Mail: gjensen@airius.com Phone: +1 408 555 3299 Department: Human Resources Room: 4609 Login name: jjensen In real life: Jody Jensen E-Mail: jjensen@airius.com Phone: +1 408 555 7587 Department: Accounting Room: 4882 Login name: ajensen In real life: Allison Jensen E-Mail: ajensen@airius.com Phone: +1 408 555 7892 Department: Product Development Room: 0784 Login name: bjense2 In real life: Bjorn Jensen E-Mail: bjense2@airius.com Phone: +1 408 555 5655 Department: Accounting Room: 4294 Login name: tjensen In real life: Ted Jensen E-Mail: tjensen@airius.com Phone: +1 408 555 8622 Department: Accounting Room: 4717 Login name: rjensen In real life: Richard Jensen E-Mail: rjensen@airius.com Phone: +1 408 555 5957 Department: Accounting Room: 2631 Login name: rjense2 In real life: Randy Jensen E-Mail: rjense2@airius.com Phone: +1 408 555 9045 Department: Product Testing Room: 1984 9 entries matched 'jensen'

Ideas for Improvement

Many things could be done to improve our LDAP finger gateway. Here are some ideas:

  • Sort the entries before displaying them. This would be helpful when more than a few entries are found.

  • Improve the display of special attributes. For example, postalAddress attributes use the dollar sign ( $ ) character as a line separator, but the ldapfinger.pl script does not take this into account.

  • Improve the generation of search filters. As written, the script does not examine the query string at all ”it just searches for all entries whose surname , full name, or user ID exactly match the query string. A more intelligent script might examine the query string and generate different filters depending on its contents. For example, a query string that consists only of numbers might trigger a search by telephone number.



Understanding and Deploying LDAP Directory Services,  2002 New Riders Publishing
<  BACK CONTINUE  >

Index terms contained in this section

applications
         directory-enabling
                    finger service example 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th
directories
         enabling applications
                    finger service 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th
display subroutines
          ldapfinger.pl source code 2nd 3rd 4th
displayEntry subroutine
          ldapfinger.pl source code 2nd 3rd 4th
enabling
         applications
                    finger service example 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th
          ldapfinger.pl source code
existing applications
         directory-enabling
                    finger service example 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th
LDAP finger lookup for bjensen (source code) 2nd
LDAP finger lookup for jensen (source code) 2nd 3rd 4th
LDAP finger lookup for smith(source code) 2nd
ldapfinger.pl
          additional display subroutines 2nd 3rd 4th
          displayEntry subroutine 2nd 3rd 4th
          enabling
          prelude and main module (source code) 2nd 3rd 4th 5th 6th
listings
          LDAP finger lookup for bjensen 2nd
          LDAP finger lookup for jensen 2nd 3rd 4th
          LDAP finger lookup for smith 2nd
         ldapfinger.pl
                    additional display subroutines 2nd 3rd 4th
                    displayEntry subroutine 2nd 3rd 4th
                    enabling
                    prelude and main module 2nd 3rd 4th 5th 6th
          non-LDAP-enabled UNIX finger lookup for mcs 2nd
non-LDAP-enabled UNIX finger lookup for mcs (source code) 2nd
source code
          LDAP finger lookup for bjensen 2nd
          LDAP finger lookup for jensen 2nd 3rd 4th
          LDAP finger lookup for smith 2nd
         ldapfinger.pl
                    additional display subroutines 2nd 3rd 4th
                    displayEntry subroutine 2nd 3rd 4th
                    enabling
                    prelude and main module 2nd 3rd 4th 5th 6th
          non-LDAP-enabled UNIX finger lookup for mcs 2nd

2002, O'Reilly & Associates, Inc.



Understanding and Deploying LDAP Directory Services
Understanding and Deploying LDAP Directory Services (2nd Edition)
ISBN: 0672323168
EAN: 2147483647
Year: 1997
Pages: 245

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net