Distributing Local Information with NIS
R. King Ables
NIS (Network Information Service, formerly known as
Yellow Pages)
is a mechanism for distributing information to other
machines on your
local network. Originally developed by Sun Microsystems,
it has been
included in many popular versions of UNIX. It is normally
used to
distribute local system information found in files like
/etc/passwd,
/etc/group, and /etc/hosts (among others). The programs
that access these files have been modified to also access
the information
via NIS when available.
However, any file that contains independent lines of
information with
a unique key can be distributed via NIS. NIS does not
guarantee the
order of the data being distributed to a client, so
files like /etc/printcap
or /etc/sendmail.cf cannot easily be distributed this
way.
However, a file such as a local phone list is well suited
for use
with NIS.
Some sites use rdist(1) (see "rdist to the Rescue,"
Sys Admin, Nov./Dec. 1992) to copy these kinds of files
to
each host or even copy the files manually. While these
methods work,
they create a "window of vulnerability" between
the time the
information is updated and the time all hosts receive
an updated copy
of the file. If the data is maintained on the NIS master
server, all
other hosts will have access to the updated information
as soon as
the NIS maps are updated.
Others sites put such information in directories that
are mounted
via NFS (or other network distributed filesystems) and
simply read
the file. This, too, will work, but does not scale well
in a large
network. The larger a local network, the more redundant
copies of
such a directory you will need to maintain (since 1,000
users accessing
the same files on a server will severely impact the
performance).
Once you have more than one copy of this file around,
you're doing
more work than is necessary to make an update. In reality,
NIS maintains
multiple copies of the information as well, but it is
taken care of
for you.
One of the most common pieces of local information maintained
on-line
by organizations is a company phone list. Keeping the
phone list up
to date is trouble enough -- having to copy it out to
all of the
other machines on your local network each time it is
changed just
adds to the complexity. By creating an NIS map containing
this information,
you can provide it to all hosts on the local network.
You can then
write a shell script to access the information. Then
when the phone
list is updated, only the master copy need be edited.
When the NIS
map is updated, all hosts will have access to the updated
information.
You will not have to modify any other files on any of
the other hosts
on your network.
How NIS Works
NIS maintains a directory of files in ndbm(3) format.
This
is a database file format which provides efficient access
to the data.
A daemon called ypserv runs on the NIS server and services
requests for information (the fact that all NIS daemons
start with
yp is historical -- NIS was originally called Yellow
Pages).
Each NIS client and server is part of an NIS domain
(not to be confused
with an Internet domain, which is something completely
different).
The name of the domain is a string set with the domainname(8)
command on each system. It is usually set by boot scripts
when the
system is started.
A daemon called ypbind runs on each NIS client host.
This daemon
binds itself to an NIS server for the same domain. The
client will
then query that NIS server whenever a request for information
is generated
on the client. While it is possible to run more than
one NIS domain
on a local network, in practice, it is rarely necessary.
NIS also has a secondary level of server called a slave
server. Slave
servers have copies of the maps from the master server,
but the maps
cannot be updated anywhere but on the master server.
When the maps
are updated on the master server, they are pushed (with
yppush(8))
to all slave servers. With multiple slave servers available,
the clients
have more than one host to which they can bind (providing
redundancy
in case one or more servers fails). Most sites use at
least one slave
server in case the master server fails. If the master
server is unavailable,
no NIS maps can be modified, but the slave servers still
provide the
current information to the clients from their own copies.
As an example, let's say you want to add an entry to
the passwd
file. After modifying the information in /etc/passwd
on the
NIS master server (the NIS master passwd file may be
called
something else if you choose), you would next go to
the NIS directory
and "do a make." The file called Makefile
in the /var/yp
directory on the master server rebuilds any NIS maps
that have been
changed.
% vipw # BSD command used to edit
# /etc/passwd
% cd /var/yp
% make
updated passwd
<blank line>
<blank line>
pushed passwd
%
The passwd file is run through makedbm(8)
(after a few modifications) to create the NIS map files
in /var/yp/domainname
(whatever that domainname is). Then /var/yp/passwd.time
is touched (with touch(1) to update the access time)
so
that unless the passwd file is updated again, another
make
command will not rebuild the map. Last, the updated
maps are pushed
out to the slave server(s). The yppush command prints
a blank
line each time a map is pushed (and the passwd file
is actually
in two maps indexed on different keys).
Each of the "normal" maps distributed by NIS
has a slightly
different format and key, so each section of commands
in the Makefile
is slightly different. Studying the Makefile is an excellent
way of
learning how each NIS map is built and which part of
the information
are used as the key.
Creating a New NIS Map
To distribute files other than regular system files,
you must create
a new NIS map. The example distributes an on-line phone
list and names
the NIS map phonelist (pretty original, huh?). Let's
say I
already have a file of phone numbers that looks like
this:
Ables, King Austin #3494
Letterman, David New York #2187
King, Stephen Bangor #1313
I can construct an NIS map using the telephone extension
as a unique key and using the entire line as the value.
The steps
to create this map are:
1. Create the data file on the NIS master server.
2. Modify the Makefile to build a map from it.
3. Do a make.
I first create /etc/phonelist on the NIS master server
with
this file just as it looks now. This will be the master
source copy
of the phone list.
Next, I modify the Makefile in /var/yp and add the information
to build the new map. If you are not familiar with the
use of make(1),
this part might be a challenge -- I suggest enlisting
the help
of someone who is experienced in the use of make. The
Nutshell
book on the make command (listed at the end of this
article)
is also an excellent source of information.
Near the top of the NIS Makefile is a definition for
the target
"all" (which is invoked when you type make
all or just
make). This target has each map name listed as a dependency.
The new map name (phonelist) is added to this list so
that
it will be built along with the other maps.
At the end of the Makefile are the targets for each
map name.
Each map depends on a time marker file (so that a map
is not rebuilt
unless its source file has been modified). For example,
the passwd
map has passwd.time as a dependency. For this new map
I would
add:
phonelist: phonelist.time
in this section.
In the middle of the Makefile are the commands used
to build
and push each NIS map. This is where I include the commands
necessary
to build (or rebuild) the phonelist map:
phonelist.time: /etc/phonelist
@(awk 'BEGIN { FS="#"; } { print $$2, $$0 }' /etc/phonelist \
$(CHKPIPE) ) | $(MAKEDBM) - $(YPDBDIR)/$(DOM)/phonelist
@touch phonelist.time;
@echo "updated phonelist";
@if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOM) phonelist; fi
@if [ ! $(NOPUSH) ]; then echo "pushed phonelist"; fi
The first line causes the phonelist.time target
to depend on the existence of /etc/phonelist so that
the phonelist
map will be rebuilt if the modification time of /etc/phonelist
is later than that of phonelist.time in /var/yp (i.e.
if /etc/phonelist has been modified since phonelist.time
was touched the last time the phonelist map was built).
Each command begins with "@" so that it won't
be echoed by
the make command. The first line of the command runs
the awk(1)
program to add the phone extension as a key and pipe
the phonelist
into the makedbm(8) command and put the resulting ndbm(3)
format files in /var/yp/domainname. Depending on the
format
of your phone list, this command could vary somewhat.
In the Sun distribution
of /var/yp/Makefile, the MAKEDBM symbol is set to the
path of the makedbm command, YPDBDIR is /var/yp,
and DOM is set to the domain name. The CHKPIPE symbol
is set to a command that lets the Makefile terminate
with an
error message if the part of the pipe preceding it terminates
with
an error code. If your NIS Makefile doesn't do this
(it isn't
critical), just leave that symbol out (do not, however,
leave out
the second right parenthesis which closes the open parenthesis
just
before awk).
The next step is to touch phonelist.time to update the
modification
time and print that it was updated. The last two commands
check to
see if the maps should be pushed and do so if they should.
The NOPUSH
symbol is generally set to a null string so that the
maps are pushed
and the YPPUSH symbol is set to the path of the yppush(8)
command.
Now it's time to build the new map.
% cd /var/yp
% make phonelist
updated phonelist
<blank line>
pushed phonelist
%
The new map is propagated to all slave servers and is
now available to the clients. On any NIS client in the
local domain,
a user can type:
% ypcat phonelist
and get an unsorted copy of the entire phone list.
The shell script below, called phone, accesses this
information
for a user in response to text provided on the command
line:
#!/bin/sh
#
# phone - search for text in the on-line phone list
#
if [ "$1" = "" ]; then
echo "usage: $0 text"
exit 1
fi
#
ypcat phonelist | grep -i "$1" | sort
# case insensitive search
This allows the user to ask for and receive information
in the following format:
% phone dav
Letterman, David New York #2187
% phone king
Ables, King Austin #3494
King, Stephen Bangor #1313
%
I added the sort command after the search because
NIS does not deliver the entries in order. In case the
string typed
by the user caused more than one entry to be returned,
the multiple
entries will appear in sorted order. The sort might
need to be different
if the last name does not appear at the beginning of
the line in your
phone list. Any text used as an argument to the phone
script will
be used as the search string. You can type "phone
1313" if
you want to find out who has that extension.
In order to modify the phone list now, all that is necessary
are the
following steps:
% vi /etc/phonelist # change the
# Letterman entry
% cd /var/yp
% make
update phonelist
pushed phonelist
then on any host on the network:
% phone dav
will return
Letterman, David New York #1138
%
References
The man pages for the commands ypbind, ypserv,
yppush, makedbm, ypinit, ypxfer, and domainname
will explain these parts of NIS for your local version
of UNIX. Your
local man page for the make command and the O'Reilly
Nutshell
book on make will also help you understand the NIS Makefile:
Oram, Andrew, and Steve Talbott. Managing Projects
with Make. Sebastopol, CA: O'Reilly & Associates,
1991. ISBN 0-937175-18-8.
About the Author
R. King Ables has been a UNIX user since 1980 and has
been managing systems
or developing system management and networking tools
since 1983. He is
currently doing system and network management development
for HaL Computer
Systems in Austin, TX.
|