474 lines
20 KiB
HTML
474 lines
20 KiB
HTML
<!--startcut ======================================================= -->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
|
<html>
|
|
<head>
|
|
<META NAME="generator" CONTENT="lgazmail v1.2J.g">
|
|
<TITLE>The Answer Guy 42: PAM chroot</TITLE>
|
|
</HEAD><BODY BGCOLOR="#FFFFFF" TEXT="#000000"
|
|
LINK="#3366FF" VLINK="#A000A0">
|
|
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
<H4>"The Linux Gazette...<I>making Linux just a little more fun!</I>"</H4>
|
|
<P> <hr> <P>
|
|
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
<center>
|
|
<H1><A NAME="answer">
|
|
<img src="../../gx/dennis/qbubble.gif" alt="(?)"
|
|
border="0" align="middle">
|
|
<font color="#B03060">The Answer Guy</font>
|
|
<img src="../../gx/dennis/bbubble.gif" alt="(!)"
|
|
border="0" align="middle">
|
|
</A></H1>
|
|
<BR>
|
|
<H4>By James T. Dennis,
|
|
<a href="mailto:linux-questions-only@ssc.com">linux-questions-only@ssc.com</a><BR>
|
|
LinuxCare,
|
|
<A HREF="http://www.linuxcare.com/">http://www.linuxcare.com/</A>
|
|
</H4>
|
|
</center>
|
|
|
|
<p><hr><p>
|
|
<!-- endcut ======================================================= -->
|
|
<!-- begin 4 -->
|
|
<H3 align="left"><img src="../../gx/dennis/qbubble.gif"
|
|
height="50" width="60" alt="(?) " border="0"
|
|
>PAM chroot</H3>
|
|
<H4 ALIGN="center">
|
|
Wherein Jim rants about PAM</H4>
|
|
|
|
|
|
<p><strong>From Terrell larson on Sun, 02 May 1999
|
|
</strong></p>
|
|
<!-- ::
|
|
PAM chroot
|
|
~~~~~~~~~~
|
|
Wherein Jim rants about PAM
|
|
:: -->
|
|
<P><STRONG><IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
|
|
HEIGHT="28" WIDTH="50" BORDER="0"
|
|
>
|
|
I'm interested in a CHROOT option probably in pam-pwdb and I've
|
|
been unable to find it. If it does not exist I may be willing to
|
|
implement it IF I can find the current source tree and IF I can
|
|
find out where to forward it for general use.
|
|
</STRONG></P>
|
|
<P><STRONG>
|
|
Info will be appreciated...
|
|
</STRONG></P>
|
|
<P><STRONG>
|
|
Thanx
|
|
Terrell Larson
|
|
</STRONG></P>
|
|
<BLOCKQUOTE><IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
|
|
HEIGHT="28" WIDTH="50" BORDER="0"
|
|
>
|
|
Terrell,
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
It's an interesting question. I presume you're talking
|
|
about implementing/re-implementing PAM support for an old
|
|
convention among SVR4 UNIX implementations where
|
|
specific accounts can be marked for special chroot
|
|
handling by giving them a '<tt>*</tt>' as the "login shell"
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
This is described in O'Reilly & Associates'
|
|
<em><a href="http://www.oreilly.com/catalog/puis/noframes.html"
|
|
>Practical Internet and Unix Security</a></em>, p232, Garfinkel and Spafford
|
|
and most other books on UNIX security.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
(For our readers that are unfamiliar with the trick: the
|
|
login program; upon seeing that the login shell for a given
|
|
account is set to '<tt>*</tt>' does a <tt>chroot()</tt> system call to the
|
|
directory that's listed as that account's "home" directory.
|
|
Therein '<tt>login</tt>' <tt>exec()</tt>'s the appropriate copy of
|
|
'<tt>login</tt>' thereunder. This normally would then <tt>exec()</tt>
|
|
a normal shell, as listed in the /...(chroot top)...<tt>/etc/passwd</tt> file.)
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
I was doing some research on a paper (that I still plan on
|
|
submitting to USENIX, one of these days) when I first
|
|
read about this convention. My paper was on a completely
|
|
different use of <tt>chroot()</tt>, but I was doing a literature
|
|
search.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
Naturally I tried this particular trick on one of my Linux
|
|
systems. It worked fine. In fact I just tested it, as I
|
|
write this, on a new <A HREF="http://www.debian.org/">Debian</A>
|
|
2.1 installation that I've been playing with and it works there.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
However on PAM based systems (using pluggable authentication
|
|
modules) --- notably on <A HREF="http://www.redhat.com/">Red Hat</A>
|
|
4.x, 5.x and presumably the new 6.0 system as well as any where the
|
|
admins have added Linux PAM after-the-fact --- it doesn't work.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
I mentioned this in e-mail to Andrew Morgan, the maintainer
|
|
and co-ordinator of the PAM development project. There is,
|
|
of course a listing for a pam_chroot module in the PAM
|
|
administrator's guide. However, that doesn't do the same
|
|
sort of thing --- and there's no example of how you'd
|
|
use it to accomplish the same job. It's also listed as
|
|
"unwritten." I did run across a file at the following URL
|
|
that you might want to look at:
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE><BLOCKQUOTE><CODE>
|
|
<A HREF="http://www.us.kernel.org/pub/linux/libs/pam/pre/forgotten/changeroot.tar.gz"
|
|
>http://www.us.kernel.org/pub/linux/libs/pam/pre/forgotten/changeroot.tar.gz</A>
|
|
</CODE></BLOCKQUOTE></BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
It's from late 1997 and is only about 3K. All it contains
|
|
is source to a simple command, a man page and a sample
|
|
configuration file. It seems to be an alternative
|
|
implementation of the chrootuid program that Weitse Venema
|
|
wrote years ago (part of his '<tt>logdaemon</tt>' package).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
This particular program (changeroot) seems to have nothing
|
|
to do with PAM. I'd also guess (from the parent directory
|
|
name) that the code is not under active development.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
Obviously, you could use something like chrootuid, or this
|
|
changeroot program or you could write a simple C program (or
|
|
even a PERL script) that would implement this procedure and
|
|
use a reference to that in lieu of the '<tt>*</tt>' that I've been
|
|
talking about. In other words instead of an entry like:
|
|
</BLOCKQUOTE>
|
|
|
|
<blockquote><pre>guest:x:65533:65534:Jailed Guest:/usr/local/jail:*
|
|
</pre></blockquote>
|
|
<BLOCKQUOTE>
|
|
... where '<tt>login</tt>' spots the the '<tt>*</tt>', performs the
|
|
<tt>chroot()</tt> to <TT>/usr/local/jail</TT>, and <tt>exec()</tt>'s
|
|
the copy of <TT>/bin/login</TT> thereunder; we'd see something like:
|
|
</BLOCKQUOTE>
|
|
|
|
<blockquote><pre>guest:x:65533:65534:Jailed Guest:/usr/local/jail:/usr/local/sbin/jailsh
|
|
</pre></blockquote>
|
|
<BLOCKQUOTE>
|
|
... where <tt>jailsh</tt> is a hypothetical SUID root program that
|
|
performs these same steps.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
This approach will work with any version of UNIX (so its
|
|
more portable). Another advantage for Linux under a 2.2
|
|
kernel is that this hypothetical jailsh program could be
|
|
written to use the new "privileges" model (which are listed
|
|
in the sources under the "capabilities" misnomer --- but
|
|
let's not get into that peeve).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
The disadvantage of this approach is that we have to write a
|
|
custom program (which I'm calling <tt>jailsh</tt>). It has to run as
|
|
'root' (or with several rootly privileges, <tt>setuid()</tt>, and
|
|
<tt>chroot()</tt> at least). I might toss together something for use
|
|
on one of my systems (I have in the past) --- but I'd be
|
|
very reluctant to publish those as solutions that anyone
|
|
else would trust. I simply don't consider myself a
|
|
sufficiently experienced and skilled programmer to be
|
|
writing SUID root code for public consumption.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
So, this brings us back to your message. <tt>chroot()</tt> jails are
|
|
not used much. You'd expect them to see more widespread
|
|
use, but they they are a bit of a hassle to initially
|
|
configure (creating a suitable skeleton tree under the
|
|
target chroot point, getting the requisite shared libraries
|
|
and device nodes in place for your applications, etc.). In
|
|
addition there are ongoing concerns that chroot jails are
|
|
too easy to break out of. In cases where you want to
|
|
isolate a root/privileged program --- it's too easy for them
|
|
to chroot back out of the jail. This concern may be
|
|
addressed by clever use of the new "privileges" features in
|
|
the 2.2 kernels. However, since you're asking, I presume
|
|
you already have your application well considered.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
It sounds like you are willing to contribute some code to
|
|
this. So you might start with a small standalone program
|
|
(based on <tt>chrootuid</tt> or the <tt>changelog</tt> program listed above,
|
|
if their licenses are amenable to your needs).
|
|
</BLOCKQUOTE>
|
|
|
|
<BLOCKQUOTE><dl>
|
|
<dt>You can find chrootuid at:
|
|
<dd><code><A HREF="ftp://ftp.porcupine.org/pub/security/index.html"
|
|
>ftp://ftp.porcupine.org/pub/security/index.html</A></code>
|
|
<dt>... and there's some some of GNU package called <tt>g2s</tt>
|
|
<dd><code><A HREF="http://freshmeat.net/appindex/1998/05/11/894932721.html"
|
|
>http://freshmeat.net/appindex/1998/05/11/894932721.html</A></code>
|
|
<br>... that's listed as "an interesting alternative to
|
|
inetd/tcpwrapper/chrootuid/relay/tcp-env/antispam/etc."
|
|
</dl>
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
PAM pwdb is maintained by Christian Gafton. The canonical
|
|
forum for discussions relating to PAM development is the
|
|
pam-list (<A HREF="mailto:pam-list@redhat.com"
|
|
>pam-list@redhat.com</A>). The canonical web site is
|
|
at:
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE><BlockQuote><code>
|
|
<A HREF="http://www.kernel.org/pub/libs/pam"
|
|
>http://www.kernel.org/pub/libs/pam</A>
|
|
</code></BlockQuote></BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
... which is generally inaccessible (as kernel.org is the
|
|
master site for the Linux kernel --- which gets too much
|
|
traffic for a reasonable Internet connection). So it
|
|
should be accessed through one of the mirrors. The Linux
|
|
kernel crowd use a relatively simple and innovative
|
|
DNS trick to maintain a list of mirrors that we can use
|
|
without having to strain our memories. Basically you can
|
|
use URLs of the form:
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE><BlockQuote><code>
|
|
<A HREF="http://www.us.kernel.org"
|
|
>http://www.us.kernel.org</A>
|
|
</code></BlockQuote></BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
... to access a DNS round-robin collection of U.S. mirrors.
|
|
There are mirrors in many other countries and regions, from
|
|
Afghanistan (<tt><A HREF="http://www.af.kernel.org"
|
|
>http://www.af.kernel.org</A></tt>) to Zimbabwe
|
|
(<tt><A HREF="http://www.zw.kernel.org"
|
|
>http://www.zw.kernel.org</A></tt>). (Yes, they just use the
|
|
ISO two letter country codes as a subdomain prefix). Most
|
|
of these sites mirror the whole kernel.org FTP and web
|
|
trees. If you have trouble connecting to one of the
|
|
sites, try again. A check with '<tt>dig</tt>' lists about a dozen
|
|
U.S. mirror sites for www.us.kernel.org. Any decent
|
|
resolver libraries will cycle through the available
|
|
addresses until one works (upon successive access attempts).
|
|
That's part of what allows the whole DNS round robin scheme to work).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
These carry sources and links to the many ongoing PAM module projects.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
But I digress. Getting back to PAM. Personally I'm somewhat
|
|
disappointed in the Linux PAM project. I've expressed this
|
|
to the list and I've discussed it with Christian Gafton in
|
|
person. He and Andrew will probably be irritated to see
|
|
this published in Linux Gazette --- and they are invited to
|
|
compose and submit a rebuttal, or anything they like, to
|
|
the editors here. (I've courtesy copied them on this e-mail).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
My principal complaint is that the PAM project seems to be
|
|
permanently stuck near version 0.6x. It was at 0.57 about
|
|
two years ago. The response on the mailing list (and
|
|
direction from Christian) when I raised this concern was:
|
|
"So what, it's just an arbitrary version number."
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
Of course I'm not a programmer or a distribution integrator;
|
|
I'm just a dumb user, admin and support guy <EM>and writer</EM> ---
|
|
so my opinion doesn't count for much. However, it does get
|
|
published, so others can beat up on me when they disagree.
|
|
It seems to be that a version number of 0.x still connotes
|
|
"beta" --- not ready for production use to most people. Red
|
|
Hat and <A HREF="http://www.caldera.com/">Caldera</A> are the
|
|
only distributions that include integrated PAM support. Many
|
|
authentication dependent packages, like <tt>ssh</tt>, don't include
|
|
PAM support "out-of-the-box" and it is non-trivial (read: "scary and
|
|
difficult") for an "average" Linux user or junior sysadmin
|
|
to install the PAM suite into an existing system.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
As one example if you'd been using Debian,
|
|
<A HREF="http://www.suse.com/">S.u.S.E.</A> or
|
|
<A HREF="http://www.slackware.org/">Slackware</A> for your application
|
|
(with the chroot'd users) and you installed PAM, you'd probably be pretty
|
|
distressed to find it suddenly broken. <em>[ hint: don't log out until
|
|
you've attempted to access all your desirable services via the localhost
|
|
interface and gotten them visible again, minimally telnet or ssh. Yes, I've
|
|
been there. -- Heather ]</em> Granted, this whole '<tt>*</tt>' shell
|
|
chroot business is pretty obscure to the "average" user
|
|
or the "junior" sysadmin. However, it is documented in
|
|
most books on Unix security (I reviewed about twenty books
|
|
at a couple of books stores with the words UNIX and security
|
|
in their titles --- over half of them described this
|
|
mechanism and several gave examples).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
Another complaint that I have is that the existing PAM
|
|
deployment doesn't include S/Key or OPIE support, and
|
|
doesn't even include clear examples of how to add-in and
|
|
configure any form of pluggable OTP. Given that network
|
|
password sniffing is one of the most common problems that
|
|
one might want to solve with PAM this seems like a pretty
|
|
significant omission.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
The response to this on the list and in personal discussion
|
|
amounted to:
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE><BlockQuote>
|
|
"that's crypto --- and the U.S. government black helicopters
|
|
are hovering over our heads ready to bomb Red Hat's offices
|
|
if they include anything like it."
|
|
</BlockQuote></BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
(Yes, I'm paraphrasing). Personally I think this is absurd.
|
|
Yes, the U.S. federal government's restrictions regarding
|
|
the "export" of cryptography software are an embarassment to
|
|
free people everywhere. I'm personally ashamed of our
|
|
entire political process as a result of the ways in which
|
|
"my" government was repeatedly thwarted the popular will of
|
|
the people vis a vis cryptography. However, S/Key and OPIE
|
|
are not cryptography. They use hashes, fancy checksums, as
|
|
the basis for their authentication. Specifically OPIE uses
|
|
MD5 by default. (I guess that the spec for S/Key -- OPIE
|
|
allows for one to use alternative hash algorithms, MD2,
|
|
maybe SHA-1, etc. I don't know the details on that).
|
|
Ironically the code for the standard UNIX password hashing
|
|
method, use your password and some "salt" as a 56-bit DES
|
|
key to "encrypt" a string of NULs, is far more easily
|
|
subverted into true cryptographic use than MD5. Of course
|
|
both the conventional DES hashing and the MD5 code are
|
|
already in every major Linux distribution, and always have
|
|
been!
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
One compromise would be to include DOCUMENTATION. Give
|
|
us a URL that points to a script. Have the script walk one
|
|
through the processing of fetching, installing, and
|
|
configuring pam_opie. Granted it's not THAT difficult. I
|
|
was able to perform the task by hand in about an hour.
|
|
However, it would probably take an "average" sysadmin about
|
|
twice that and it would probably take an "average" Linux
|
|
user about four times that. Consequently it probably won't
|
|
happen in any significant number of sites. So it just
|
|
doesn't get done at all.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
(The argument that OPIE and other OTP, one-time-password
|
|
schemes, is an incomplete solution is also well considered.
|
|
It doesn't secure the connection so sniffing will still
|
|
reveal other confidential data, etc. ssh IS a much better
|
|
solution. The new <A HREF="http://www.xs4all.nl/~freeswan/">FreeS/WAN</A>
|
|
ipsec implementation is also a much better approach. However,
|
|
there are enough people out there that can't or won't install
|
|
strong cryptographic support that some stop gap is indicated.
|
|
Providing smooth easy installation and configuration of OTP is
|
|
one thing that PAM could do to address this problem).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
By far my biggest complaint about PAM is that it hasn't
|
|
delivered on its most important promise. It doesn't put
|
|
Linux on par with <A HREF="http://www.freebsd.org/">FreeBSD</A>,
|
|
<A HREF="http://www.netbsd.org/">NetBSD</A>, and
|
|
<A HREF="http://www.openbsd.org/">OpenBSD</A> for authentication.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
FreeBSD has supported S/Key compatible OTP "out-of-the-box"
|
|
for YEARS. (Note: Walnut Creek, the largest distributor of
|
|
FreeBSD CDs and books and the major sponsor for FreeBSD
|
|
development hasn't been hit by the "black helicopters").
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
Beyond just this discussion of OTP, FreeBSD's libraries have
|
|
provided seams shadow and MD5 password hashing for years.
|
|
Regardless of PAM I still bump into Linux applications that
|
|
fail to authenticate because they don't properly handle some
|
|
aspect of shadowing and MD5 checksums. Just last week
|
|
one of my fellow techs at Linuxcare was fighting for a
|
|
couple of hours with that on a Yellow Dog (Linux for
|
|
PowerPC) installation at the office.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
That was the whole idea of the PAM project. However, PAM
|
|
can't deliver on that promise until it attracts widespread
|
|
support from the application/utility writers that perform
|
|
authentication. FreeBSD hides most of the details behind
|
|
their implemention of the standard library functions that
|
|
most programmers were already using to perform their
|
|
authentication (<tt>getpwent()</tt>, etc.). We can't do that with
|
|
PAM and glibc --- but we need to straighten out this
|
|
mess eventually.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
So, I would welcome any new blood that got involved in the
|
|
PAM project. I realize that Andrew will probably say:
|
|
"Quit your whining and turn in some code!" That's fair
|
|
enough. (However, as I've said before, you don't want to
|
|
see any C code from me, yet).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
PAM is an ambitious project. It goes beyond Linux (in
|
|
an effort to implement standards that have been proposed
|
|
to the IETF by Sun and other vendors). I realize that there
|
|
is some delay because these proposed standards are in draft
|
|
form and are still in flux (the XSSO, single-sign-on stuff
|
|
also seems to be languishing). However, I'd still like to
|
|
see it deliver more in the near term.
|
|
</BLOCKQUOTE>
|
|
<!-- sig -->
|
|
|
|
<!-- end 4 -->
|
|
|
|
<!--startcut ======================================================= -->
|
|
<P> <hr> <P>
|
|
<H5 align="center"><a href="http://www.linuxgazette.com/copying.html"
|
|
>Copyright ©</a> 1999, James T. Dennis
|
|
<BR>Published in <I>The Linux Gazette</I> Issue 42 June 1999</H5>
|
|
<H6 ALIGN="center">HTML transformation by
|
|
<A HREF="mailto:star@starshine.org">Heather Stern</a> of
|
|
Starshine Techinical Services,
|
|
<A HREF="http://www.starshine.org/">http://www.starshine.org/</A>
|
|
</H6>
|
|
<P> <hr> <P>
|
|
<!-- begin tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::-->
|
|
<TABLE WIDTH="97%"><TR VALIGN="center" ALIGN="center">
|
|
<TD ROWSPAN="4" COLSPAN="1" WIDTH="37%"><A
|
|
HREF="../lg_answer42.html"
|
|
><IMG SRC="../../gx/dennis/answernew.gif"
|
|
ALT="[ Answer Guy Index ]"></A></td>
|
|
<TD WIDTH="10%"><A HREF="1.html">1</A></TD>
|
|
<TD WIDTH="10%"><A HREF="2.html">2</A></TD>
|
|
<TD WIDTH="10%"><A HREF="3.html">3</A></TD>
|
|
<TD WIDTH="10%"><A HREF="4.html">4</A></TD>
|
|
<TD WIDTH="10%"><A HREF="5.html">5</A></TD>
|
|
<TD WIDTH="10%"><A HREF="6.html">6</A></TD>
|
|
</TR><TR VALIGN="center" ALIGN="center">
|
|
<TD><A HREF="7.html">7</A></TD>
|
|
<TD><A HREF="8.html">8</A></TD>
|
|
<TD><A HREF="9.html">9</A></TD>
|
|
<TD><A HREF="10.html">10</A></TD>
|
|
<TD><A HREF="11.html">11</A></TD>
|
|
<TD><A HREF="12.html">12</A></TD>
|
|
</TR><TR VALIGN="center" ALIGN="center">
|
|
<TD><A HREF="13.html">13</A></TD>
|
|
<TD><A HREF="14.html">14</A></TD>
|
|
<TD><A HREF="15.html">15</A></TD>
|
|
<TD><A HREF="16.html">16</A></TD>
|
|
<TD><A HREF="17.html">17</A></TD>
|
|
<TD><A HREF="18.html">18</A></TD>
|
|
</TR><TR VALIGN="center" ALIGN="center">
|
|
<TD><A HREF="19.html">19</A></TD>
|
|
<TD><A HREF="20.html">20</A></TD>
|
|
<TD><A HREF="21.html">21</A></TD>
|
|
<TD><A HREF="22.html">22</A></TD>
|
|
<TD><A HREF="23.html">23</A></TD>
|
|
<TD><A HREF="24.html">24</A></TD>
|
|
</TR></TABLE>
|
|
<!-- end tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::::-->
|
|
<P> <hr> <P>
|
|
<!-- begin lgnav ::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
<A HREF="../../index.html"
|
|
><IMG SRC="../../gx/indexnew.gif" ALT="[ Table Of Contents ]"></A>
|
|
<A HREF="/index.html"
|
|
><IMG SRC="../../gx/homenew.gif" ALT="[ Front Page ]"></A>
|
|
<A HREF="../lg_bytes42.html"
|
|
><IMG SRC="../../gx/back2.gif" ALT="[ Previous Section ]"></A>
|
|
<A HREF="../lg_tips42.html"
|
|
><IMG SRC="../../gx/fwd.gif" ALT="[ Next Section ]"></A>
|
|
<!-- end lgnav ::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
</BODY></HTML>
|
|
<!--endcut ========================================================= -->
|