Book Home Perl for System AdministrationSearch this book

5.2. NIS, NIS+, and WINS

Developers at Sun Microsystems realized that the "edit one file per machine" approach endemic to host files didn't scale, so they invented something called Yellow Pages (YP). Yellow Pages was designed to distribute all the network-wide configuration file information found in files like /etc/hosts, /etc/passwd, /etc/services, etc. In this chapter, we'll concentrate on its use as a network name service to distribute the machine name-to-IP address mapping information.

YP was renamed Network Information Service, or NIS, in 1990, shortly after British Telecom asserted (with lawyers) that it held the trademark for "Yellow Pages" in the U.K. The ghost of the name "Yellow Pages" still haunts many a Unix box today in the names used for NIS commands and library calls (e.g., ypcat, ypmatch, yppush). All modern Unix variants support NIS. NT machines can be made to use NIS for authentication through the use of special home-brewed authentication libraries,[2] but I know of no NT-based NIS servers. I do not know of any Mac ports of NIS.

[2]One such library is NISGINA, which was originally developed by Nigel Williams; this library can be found at http://www.dcs.qmw.ac.uk/~williams/. Be sure to check the mailing list archives found off that page for information on the latest versions of this software.

In NIS, an administrator designates one or more machines as servers from which other machines will receive client services. One server is the master server, the others slave servers. The master server holds the master copies of the actual text files (e.g., /etc/hosts or /etc/passwd ) all machines normally use. Changes to these files take place on the master and are then propagated to the slave servers.

Any machine on the network that needs hostname-to-IP address mapping information can query a server instead of keeping a local copy of the information. A client can request this information from either the master or any of the slave servers. Client queries are looked up in the NIS maps, another name for the master's data files after they've been converted to the Unix DBM database format and propagated to the slave servers. The details of this conversion process (which involves makedbm and some other random munging) can be found in the Makefile located in /var/yp on most machines. A collection of NIS servers and clients that share the same maps is called an NIS domain.

With NIS, network administration becomes considerably easier. For instance, if oog.org purchases more machines for their network, it is no problem to integrate them into the network. The network manager simply edits the host file on the master NIS server and pushes the new version out to the slave servers. Every client in the NIS domain now "knows" about the new machine. NIS offers one-touch administration ease coupled with some redundancy (if one server goes down, a client can ask another) and load sharing (not all of the clients in a network have to rely on a single server).

With this theory in mind, let's see how Perl can help us with NIS-related tasks. We can start with the process of getting data into NIS. You may be surprised to know that we've already done the work for this task. The host files we created in the previous section can be imported into NIS by just dropping them into place in the NIS master server's source file directory, and activating the usual push mechanisms (usually by typing make in /var/yp). By default, the Makefile in /var/yp uses the contents of the master server's configuration files as the source for the NIS maps.

TIP

It is usually a good idea to set up a separate directory for your NIS map source files, changing the Makefile accordingly. This allows you to keep separate data for your NIS master server and other members of your NIS domain. For example, you might not want to have the /etc/passwd file for your NIS master as the password map for the entire domain, and vice versa.

A more interesting task is getting data out of NIS by querying an NIS server. The easiest way to do this is via Rik Harris' Net::NIS module. This particular module has been in alpha release state since 1995, but it is still quite functional.[3]

[3]There's only one true bug in the a2 version that I know of. The documentation suggests you compare the return status of this module's calls against a set of predefined constants like $Net::NIS::ERR_KEY and $Net::NIS::ERR_MAP. Unfortunately, the module never actually defines these constants. The simplest way to test for a successful query is to examine the returned data's length.

Here's an example of how to grab and print the entire contents of the host map with a single function call using Net::NIS, similar to the NIS command ypcat:

use Net::NIS;
# get our default NIS domain name
$domain = Net::NIS::yp_get_default_domain(  ); 
# grab the map
($status, $info) = Net::NIS::yp_all($domain,"hosts.byname"); 
foreach my $name (sort keys %{$info}){
    print "$name => $info->{$name}\n";
}

First we query the local host for its default domain name. With this info, we can call Net::NIS::yp_all() to retrieve the entire hosts map. The function call returns a status variable (bogus, as mentioned in the footnote) and a reference to a hash table containing the contents of that map. We print this information using Perl's usual dereference syntax.

If we want to look up the IP address of a single host, it is more efficient to query the server specifically for that value:

use Net::NIS;
$hostname = "olaf.oog.org";
$domain = Net::NIS::yp_get_default_domain(  ); 
($status,$info) = Net::NIS::yp_match($domain,"hosts.byname",$hostname);
print $info,"\n";

Net::NIS::yp_match() returns another bogus status variable and the appropriate value (as a scalar) for the info being queried.

If the Net::NIS module does not compile or work for you, there's always the "call an external program method." For example:

@hosts='<path to>/ypcat hosts'

or:

open(YPCAT,"<path to>/ypcat hosts|");
while (<YPCAT>){...}

Let's wind up this section with a useful example of both this technique and Net::NIS in action. This small but handy piece of code will query NIS for the list of NIS servers currently running and query each one of them in turn using the yppoll program. If any of the servers fails to respond properly, it complains loudly:

use Net::NIS;

$yppollex = "/usr/etc/yp/yppoll"; # full path to the yppoll executable

$domain = Net::NIS::yp_get_default_domain(  ); 

($status,$info) = Net::NIS::yp_all($domain,"ypservers");

foreach my $name (sort keys %{$info}) {
    $answer = '$yppollex -h $name hosts.byname';
    if ($answer !~ /has order number/) {
        warn "$name is not responding properly!\n";
    }
}

5.2.1. NIS+

Sun included the next version of NIS, called NIS+, with the Solaris operating system. NIS+ addresses many of the most serious problems of NIS, such as security. Unfortunately (or fortunately, since NIS+ can be a bit difficult to administer), NIS+ has not caught on in the Unix world nearly as well NIS did. Until recently, there was virtually no support for it on machines not manufactured by Sun. It is slowly making its way into standard Linux distributions thanks to the work of Thorsten Kukuk (see http://www.suse.de/~kukuk/nisplus/index.html), but it is far from prevalent in the Unix world and nonexistent in the NT and MacOS world.

Given its marginal status, we're not going to look any deeper into NIS+ in this book. If you need to work with NIS+ from Perl, Harris also has a Net::NISPlus module up to the task.

5.2.2. Windows Internet Name Server ( WINS)

When Microsoft began to run its proprietary networking protocol NetBIOS over TCP/IP (NetBT), it also found a need to handle the name-to-IP address mapping question. The first shot was the lmhosts file, modeled after the standard host file. This was quickly supplemented with an NIS-like mechanism. As of NT Version 3.5, Microsoft has offered a centralized scheme called Windows Internet Name Server (WINS). WINS differs in several ways from NIS:

WINS, like NIS, offers the ability to have multiple servers available for reliability and load sharing through the use of a push-pull partner model. As of Windows 2000, WINS is deprecated (read "killed off") in favor of Dynamic Domain Name Service, an extension to the basic DNS system we're just about to discuss.

Given that WINS is not long for this earth, we're not going to explore Perl code to work with it. There is currently very little support for working directly with WINS from Perl. I know of no Perl modules designed specifically to interact with WINS. Your best bet may be to call some of the command-line utilities found in the Windows NT Server Resource Kit, such as WINSCHK and WINSCL.



Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.