Understanding and Deploying LDAP Directory Services > 21. Directory-Enabling ExistingApplications > Example 1: A Directory-Enabled finger Service |
Example 1: A Directory-Enabled finger ServiceA 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 ApproachOur 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 CodeThe 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 module1. #!/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:
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 subroutine1. # 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 subroutines1. # 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 script1.#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 ExperienceListing 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 bjensenLDAP 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 ImprovementMany things could be done to improve our LDAP finger gateway. Here are some ideas:
|
Index terms contained in this sectionapplicationsdirectory-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. |