SUMMARY:making DNS hostname resolving work without running NIS
Please remember to read the "Caveats" and "Parting comments" sections at the end of this, though.
Problem:
For whatever reason(s), you're not using NIS on your Sun.
You're relying on a properly configured /etc/resolv.conf(5) (and,
therefore, DNS) to resolve hostnames. However, while utilities such as
nslookup(8c) can resolve hostnames successfully, any programs that
are dynamically linked (ping, telnet, ftp, etc) will only resolve
hostnames if the names are in the /etc/hosts(5) file. This is not
clearly mentioned in the Sun manuals, in my opinion.
Quick answer:
As provided by Sun, the resolving routines in /usr/lib/libc.so
don't use DNS to resolve hostnames; they use NIS. If you aren't running
NIS, then they will use only /etc/hosts to resolve names and fail if the
name isn't there.
More detailed answer:
Sun's default resolving routines in /usr/lib/libc.so use a two-step process to resolve names:
- See if the hostname exists in /etc/hosts.
- If that fails, then give the hostname to the NIS server, and let it resolve it.
The NIS server then performs these steps:
- 1. See if the name exists in /etc/NIS/hosts (or wherever the NIS master hosts file is)
- 2. If that fails, and the "B=-b" option was set in /var/yp/Makefile,
the NIS server will attempt to use DNS to attempt to resolve the
name. This option requires an /etc/resolv.conf file for DNS to
use.
Future answer:
Solaris 2.0 will feature NIS+, a version of NIS which allows the
administrator to decide whether to use NIS, DNS, /etc/hosts or any
combination of the above, in any order. Furthermore, different applications
can have different assignments (e.g., syslogd can use hosts-DNS, while
ftpd uses DNS-hosts and noone need use NIS unless they want to). Installing
and setting the configurations will be much easier, as well.
Partial solutions:
1. Give in to Sun's belief that everyone loooooves and uses NIS;
install NIS; set up an NIS server.
For a lot of people, this is not a practical solution. Some
of us have only a few (or one) machines, and DNS is the perfect way
to let others handle the headaches of name servers. For others, their
organizations are working towards a distributed network, in which each
machine depends on as few as other machines as possible (AFS and DFS
are two prime examples.) In this case, installing NIS and having all
of your machines depending on one NIS server for resolving hostnames
is taking a step backwards instead of forwards.
In addition, unless the domain name server is also the NIS
server, for hostnames that are not known locally, this makes more work
for the NIS master server, and more network traffic. (In other words,
hostname resolve requests not known locally would be handled like
this:
localhost -> NIS server -> nameserver
By setting up each machine to use DNS on its own, you
eliminate the middle man (so to speak), and get this:
localhost -> nameserver
2. Replace the resolving routines in /usr/lib/libc.so with the ones
located in /usr/lib/libresolv.a. In the instructions below, skip
steps 2, 3, 4 and 19. In step 6, when it refers to /resolv+/libresolv.a
use /usr/lib/libresolv.a instead. In step 17, skip the first three
actions (storing the old libresolv.a and moving in the new one) as
there is no new libresolv.a to move.
This is a commonly recommended option, since it is detailed in
the original /usr/lib/shlib.etc/README.DNS. In addition, some users are
required to do this because of site restrictions. Unfortunately, it will make
things so that *ALL* hostname resolves will go directly to DNS, ignoring
/etc/hosts altogether.
Normally, hostname resolves check /etc/hosts first, then NIS, then
DNS (if you chose to add that option). By making a new library, you are
not *replacing* NIS so much as tricking the machine into thinking that NIS
has already been checked. Therefore, Sun's logic is that if you are
attempting to resolve via DNS, you must have already check /etc/hosts (and
NIS).
A few programs won't like the fact that /etc/hosts isn't looked
at. In particular, syslogd will fail to recognize the machine "loghost"
because this is defined in the /etc/hosts file. This can be overcome by
making your machine the third name lookup in resolv.conf. That way, when
DNS fails, /etc/hosts will be consulted after all.
The real (tm) solution:
-----------------------
Throw away Sun's libresolv.a and build a *real* one. Then
merge those routines into your existing C libraries. Here's how you
can do this.
a. Ensure that the "Shlib Custom" optional software category was
loaded from your SunOS 4.1.x media.
b. cd to /usr/lib/shlib.etc
c. su [become the superuser or login as 'root']
d. Copy the file included below to README.DNS in this directory.
This is a good idea because others will tell you to look at
that file in the future when you have DNS questions.
8<----------/usr/lib/shlib.etc/README.DNS----------cut-here---------->8
This is how to get intelligent DNS resolving in your shared
libc library.
* Note! If you are interested in a System V libc, please substitute *
* libcs5_pic.a for libc_pic.a in step 6, *
* libcs5.so.x.y.z for libc.so.x.y.z in step 17. *
1. cd to /usr/lib/shlib.etc and become super user, if you haven't
already.
$ cd /usr/lib/shlib.etc
$ su
2. Obtain and unpack the resolv+ package, written by Bill Wisner.
(This package is available on the same server as this file,
uesama.tjp.washington.edu as /pub/Sun_Software/resolve+-2.0.tar.Z).
Move into the resolv+ directory
# ftp uesama.tjp.washington.edu
# uncompress resolv+-2.0.tar.Z
# tar xvf resolv+-2.0.tar
# cd resolv+-2.0
3. Add the -pic flag to the CFLAGS line in the Makefile for resolv+.
**** SPECIAL NOTE!!!
If, in step 14, you get this error (while compiling) from ld
concerning tmp/gethostnamadr.o:
base relative static symbol(__gethtbyname) botch
you may have to eliminate the ${DEFS} and -O flags
and remove the additional ld and mv steps.
Try it first without changing these additional things. This problem
appears with some versions of resolv+, but shouldn't with v2.0.
If you run into problems, then go ahead and change them according
to this diff:
*** Makefile.orig Fri Jul 17 03:12:40 1992 <--- file to make
--- Makefile Fri Jul 17 03:13:16 1992 <--- change in
***************
*** 19,23 ****
mktemp.o strcasecmp.o strpbrk.o strerror.o
DEFS= -DDEBUG
! CFLAGS= -O ${DEFS} -Iinclude <--- change this line
libresolv.a: ${OBJS}
--- 19,23 ----
mktemp.o strcasecmp.o strpbrk.o strerror.o
DEFS= -DDEBUG
! CFLAGS= -pic -Iinclude <--- change it to this
libresolv.a: ${OBJS} <--- next file to make change in
***************
*** 31,46 ****
.c.o:
${CC} ${CFLAGS} -c $*.c
- -ld -x -r $*.o <--- remove this line
- mv a.out $*.o <--- remove this line
gethostnamadr.o: named/gethostnamadr.c
${CC} -c ${CFLAGS} named/gethostnamadr.c
- -ld -x -r gethostnamadr.o <--- remove this line
- mv a.out gethostnamadr.o <--- remove this line
sethostent.o: named/sethostent.c
${CC} -c ${CFLAGS} named/sethostent.c
- -ld -x -r sethostent.o <--- remove this line
- mv a.out sethostent.o <--- remove this line
clean: FRC
--- 31,40 ----
**** END OF SPECIAL NOTE
4. Run `make` in the resolv+ directory. This should give you
libresolv.a.
# make
5. Change back to /usr/lib/shlib.etc, and make a temporary directory.
# cd ..
# mkdir tmp
6. Change to the "tmp" directory just made, extract the contents of
the libresolv you just built and the pic .o from libc_pic.a (in
that order!), and rm the file __.SYMDEF. Note that there are TWO
underscores in that name!
# cd tmp
# ar x ../resolv+/libresolv.a
# ar x ../libc_pic.a
# rm __.SYMDEF
7. Rename any files that "ar" truncated (grrrrr) to 16 characters to
their original, proper names. The original README file neglects
to mention the xccs.multibyte.o file; if you use any
Internationalization features and need to handle multi-byte
character sets, do not forget this step.
# mv rpc_commondata. rpc_commondata.o
# mv rpc_dtablesize. rpc_dtablesize.o
# mv xccs.multibyte. xccs.multibyte.o
8. Remove the old routine to do the hostname/addr resolution:
# rm gethostent.o
9. Remove the libresolv module that contains `strncasecmp' (which is
now in the main C library, so it is redundant):
# rm strcasecmp.o
10. Go back up to the /usr/lib/shlib.etc directory.
# cd ..
11. Edit the lorder-sparc file. You need to remove the reference to
gethostent.o and add the references to the new resolver library
routines. Use this patch to guide you:
*** lorder-sparc.orig Fri Jul 17 14:16:19 1992
--- lorder-sparc Fri Jul 17 14:17:39 1992
***************
*** 150,154 ****
getwd.o
getnetgrent.o
! gethostent.o <--- change starting at this line
ypxdr.o
ttyname.o
--- 150,161 ----
getwd.o
getnetgrent.o
! gethostnamadr.o <--- replace the above line with
! sethostent.o <--- all of these
! res_query.o <---
! res_mkquery.o <---
! res_send.o <---
! res_debug.o <---
! res_comp.o <---
! res_init.o <---
ypxdr.o
ttyname.o
12. If you are running under SunOS 4.1.2, you will want to add the
entry "mblib.o" to the very end of lorder-sparc. (If you aren't
running SunOS 4.1.2, don't worry about this step.)
Besides adding mblib.o to the very end of lorder-sparc, you will
need to patch the Makefile by adding a "-ldl" to the end of the ld
commands, as follows:
*** Makefile.orig Fri Jul 17 14:32:45 1992
--- Makefile Fri Jul 17 14:33:41 1992
***************
*** 9,13 ****
libc.so:
! ld -assert pure-text `${OBJSORT} lorder-sparc tmp` <--- change this
/bin/ls /usr/lib/libc.so.* > TMP_FILE
mv a.out libc.so.`cat TMP_FILE | awk -f ${AWKFILE}`
--- 9,13 ----
libc.so:
! ld -assert pure-text `${OBJSORT} lorder-sparc tmp` -ldl <--- to this
/bin/ls /usr/lib/libc.so.* > TMP_FILE
mv a.out libc.so.`cat TMP_FILE | awk -f ${AWKFILE}`
***************
*** 15,19 ****
libcs5.so:
! ld -assert pure-text `${OBJSORT} lorder-sparc tmp` <--- change this
/bin/ls /usr/5lib/libc.so.* > TMP_FILE
mv a.out libc.so.`cat TMP_FILE | awk -f ${AWKFILE}`
--- 15,19 ----
libcs5.so:
! ld -assert pure-text `${OBJSORT} lorder-sparc tmp` -ldl <--- to this
/bin/ls /usr/5lib/libc.so.* > TMP_FILE
mv a.out libc.so.`cat TMP_FILE | awk -f ${AWKFILE}`
13. If you don't have the cwd in root's path (as you shouldn't), then
change the "OBJSORT=objsort" line in the Makefile to
"OBJSORT=./objsort". If you don't know what that means, you
probably need to make the change.
14. Make the new libc.so.
# make libc.so
Now you should have some libc.so.x.y.z built in the current
directory.
15. Make sure your /etc/resolv.conf file contains the correct entries
for your domain. Also (as resolv+'s README file entails) create
/etc/hosts.conf, and set it to your liking. Ours is:
hosts
bind
This means that in attempt to resolve a hostname, first /etc/hosts
will be checked, and then, if that fails, DNS will be used. If
that fails, then an "unknown host" will be returned. (If you are
using /usr/lib/libresolv.a, you don't use the /etc/hosts.conf file.)
Note that the default if no hosts.conf is found is to use DNS
only; the exact same thing as the routines in /usr/lib/libresolv.a.
16. Test out your new libc.so at this point before installing it. You
can do so by setting the environment variable LD_LIBRARY_PATH to
the /usr/lib/shlib.etc directory. Make sure that the hostname
resolves work, and are being handled as you specified with the
"order" line in /etc/resolv.conf.
17. If you're satisfied that the new library works, you can install
it, and the new libresolv.a, with the following commands:
# mv /usr/lib/libresolv.a /usr/lib/libresolv.a.OLD
# cp resolv+/libresolv.a /usr/lib/
# ranlib /usr/lib/libresolv.a
# cp libc.so.x.y.z /usr/lib/
# ldconfig
18. You are now running with the new library. You can verify this by
doing a trace command of, let's say, "date".
# trace date
The output should informed you that the new library is being used.
19. For completeness, you should rebuild libc.a so that people
compiling with static linking get the name server routines as
well. This entails removing the gethostent.o routine, and adding
the object files from resolv+.
# cd resolv+
# cp -p /usr/lib/libc.a /usr/lib/libc.a.OLD
# ar dv /usr/lib/libc.a gethostent.o
d - gethostent.o
# ar uv /usr/lib/libc.a *.o
r - mktemp.o
r - strpbrk.o
a - gethostnamadr.o
a - herror.o
a - res_comp.o
a - res_debug.o
a - res_init.o
a - res_mkquery.o
a - res_query.o
a - res_send.o
a - sethostent.o
a - strcasecmp.o
a - strerror.o
# ranlib /usr/lib/libc.a
20. Clean up.
# cd ..
# rm -rf TMP_FILE libc.so.* resolv+ tmp
8<----------/usr/lib/shlib.etc/README.DNS----------cut-here---------->8
-----------------------------------------------------------------------
Caveats:
Note that existing programs that have been compiled with
static libraries (and not dynamic) will still be as drain-bamaged as
ever. (The `mount` command, for example.) Look in the Programming
Utilities and Libraries manual for a list of all of the statically
linked commands.
If you have the source, then you can recompile these programs.
(Prime example: As the PROBLEMS file with GNU Emacs states, you can
now relink emacs and have hostname resolving work properly.) If,
however, you don't have the source for the statically linked program,
then you can add an entry to /etc/hosts as a workaround.
This procedure has only been tested on vanilla 4.1.x installations.
I don't know if it will work on patched systems, or what patches might
affect it (if any). Please send me a note if you detect any problems
along these lines.
The following patches apply to similar problems:
100465-01 : patch for libresolv.a - DNS res_send() bug
100170-08 : jumbo patch to fix various ld problems
100257-04 : jumbo patch for ld.so, ldd, and ldconfig
100531-02 : libc jumbo patch - Domestic Version (US) 4.1.2
100532-02 : libc jumbo patch - International Version 4.1.2
100266-07 : libc jumbo patch - Domestic Version (US) 4.1.1
100267-07 : libc jumbo patch - International Version 4.1.1
Parting Comments:
Generous thanks to these people for providing the leads, tips,
and hints in this document:
Bill Unruh
Karsten Leipold
Douglas E James
Don Pace
Greg Earle
Christopher Davis
Jon Peatfield
James Ralston Crawford
Haakon Styri
John Tillema
Rich J. Auletta
--
"I never think of the future. It comes soon enough." - Albert Einstein