[comp.unix.admin] Getting SunOS 4.1 to use DNS -and- /etc/hosts

rg@msel.unh.edu (Roger Gonzalez) (03/10/91)

Sun, for some strange reason, ships their host resolver routines linked
to routines that -only- use /etc/hosts.  I wrestled with this for a
while, until a helpful soul at Boeing sent me a recipe that walked me
through unarchiving some shared object libraries, and rebuilding them
with a different version of a particular routine that uses -only- DNS
instead of /etc/hosts.  This works fine, except that someone in charge
of the name server has removed 'localhost', so that I keep getting
"localhost != 127.0.0.1" messages in the error logs.  Not horrible, but
certainly irritating.  Also, there are a few host addresses that the
nameserver doesn't know that I used to have in /etc/hosts. 

I just thought of an idea that I'd like to bounce off the more experienced.
Keep in mind that I have no source, just the .so files:
- slurp the DNS lookup routine and the /etc/hosts routine out of the .so files
- hack the object files so that the two versions have unique names
- write my own routine that first calls the DNS version, and then /etc/hosts
- make my routine's name and interface look the same as the originals
- rearchive them into their .so's

If this would work, I suspect that there would be a lot of happy SunOS 4.1
sysadmins out there.  In fact, I'm surprised that it hasn't been done
already!  

Am I overlooking something?

-Roger



I've enclosed the recipe here for your viewing pleasure:


	Building the SunOS 4.1 resolver library to access DNS

1. Ensure that the resolver library is built "PIC" by doing the
   following:

		% su root
		% cd /usr/lib/shlib.etc
	        % mkdir tmp
		% cd tmp
		% ar xv /usr/lib/shlib.etc/libresolv.a
		% ls -assert pure-text *.o

	The last command will tell you if there are non-PIC constructs.
	Evidently, there shouldn't be or the resolver can't be made to
	work.

2. Extract contents of libc_pic.a  and /usr/lib/libresolv.a 

	% cd  tmp
	% ar x /usr/lib/shlib.etc/libc_pic.a
	% ar x /usr/lib/libresolv.a

3. Remove the __.SYMDEF file and restore filenames truncated by "ar"

	% rm __.SYMDEF         (note: name begins with 2 underscore char's)
	% mv rpc_dtablesize. rpc_dtablesize.o
	% mv rpc_commondata. rpc_commondata.o
	% mv xccs.multibyte. xccs.multibyte.o

4. Remove the old routine to do the hostname/addr resolution

	% rm gethostent.o

5. Move the libresolv module that contains the redundant 'strncasecmp'

	% rm strncasecmp.o

6. Edit the 'lorder-sparc'

	% cd ..      (assuming you are still in the tmp)
	% cp lorder-sparc lorder-sparc.orig
	% vi lorder-sparc
           ....
	   gethostent.o	      		<< delete this line >>
           ....
           getnetgrent.o
           gethostnamadr.o		<< add this line >>
	   sethostent.o			<<         "   "       >>
           res_query.o			<<         "   "       >>
	   res_mkquero.o		<<         "   "       >>
	   res_send.o			<<         "   "       >>
	   res_debug.o			<<         "   "       >>
	   res_comp.o			<<         "   "       >>
	   res_init.o			<<         "   "       >>

7. Create the new library.

	% make libc.so

8. Test the library before final installation.

	% setenv LD_LIBRARY_PATH `pwd`
   	% your_favorite_test_cmd  (e.g.  telnet, ftp)
	
	If everything appears normal, do the installation.

	% cp libc.so.x.y.z.  /usr/lib      # ensure that libc.so.x.y.z will be
					   # the highest version and does not
					   #  overwrite any existing version
	% /usr/etc/ldconfig
	% unsetenv LD_LIBRARY_PATH

9. Verify that you running with the new library.

	% trace date

 	the first line of output should read:
   			
	open ("usr/lib/ld.so",  ........
 
-- 
"The question of whether a computer can think is no more interesting
 than the question of whether a submarine can swim" - Edsgar W. Dijkstra 
rg@[msel|unhd].unh.edu        |  UNH Marine Systems Engineering Laboratory
r_gonzalez@unhh.bitnet        |  Durham, NH  03824-3525

rob@wdl50.wdl.loral.com (Rob Riepel) (03/11/91)

rg@msel.unh.edu (Roger Gonzalez) writes:

>Sun, for some strange reason, ships their host resolver routines linked
>to routines that -only- use /etc/hosts.  I wrestled with this for a
>while, until a helpful soul at Boeing sent me a recipe that walked me
>through unarchiving some shared object libraries, and rebuilding them
>with a different version of a particular routine that uses -only- DNS
>instead of /etc/hosts.  This works fine, except that someone in charge
>of the name server has removed 'localhost', so that I keep getting
>"localhost != 127.0.0.1" messages in the error logs.  Not horrible, but
>certainly irritating.  Also, there are a few host addresses that the
>nameserver doesn't know that I used to have in /etc/hosts. 

>I just thought of an idea that I'd like to bounce off the more experienced.
>Keep in mind that I have no source, just the .so files:
>- slurp the DNS lookup routine and the /etc/hosts routine out of the .so files
>- hack the object files so that the two versions have unique names
>- write my own routine that first calls the DNS version, and then /etc/hosts
>- make my routine's name and interface look the same as the originals
>- rearchive them into their .so's

>If this would work, I suspect that there would be a lot of happy SunOS 4.1
>sysadmins out there.  In fact, I'm surprised that it hasn't been done
>already!  

>Am I overlooking something?

>-Roger

Well Roger (et. al.) here's some answers to this problem!


Recently, there have been a lot of requests for information on how to get the
network programs (telnet, ftp, etc.) on SunOS to use DNS.  In the past there
have been posts on exactly how to do this.  I've worked with several of these
previously posted methods on SunOS 4.1 in various configurations, and this is
a summary of what I've found.

First of all, if you're using NIS (yellow pages), you're in luck!  See page 449
in the "System and Networking Administration" manual.  All you have to do is
change one line in /var/yp/Makefile on the master NIS server and you're in
business.

Now if you're not using NIS (yellow pages), you'll have to do a little work to
use DNS.  The amount of work you'll have to do depends on whether you want DNS
lookups to "do the right thing."  Now an aside to define "the right thing"

       Everything you need to use DNS is supplied with SunOS 4.1.x. 
       It's simply a matter of rebuilding one shared library.  However,
       the version of DNS supplied uses the name server exclusively,
       i.e., it completely ignores the /etc/hosts file once it is
       started.  Consequently, it goes out on the network to resolve
       names like "localhost" and "loghost", names that are used
       extensively by a lot of software, including window systems.  This
       means that if the network or name server is down, stuff like Open
       Windows won't work.

       I think that applications that don't require a network should not
       be crippled by dependencies on a resolver that does.  The
       resolver should "do the right thing" - use the /etc/hosts file as
       a backup!  That is, first try to resolve the name using the name
       server, and if that fails, check for the entry in /etc/hosts. 
       (It could be argued that the check on /etc/hosts should be made
       first, either way is fine with me).  Following are 2 (basically
       the same) methods for enabling the DNS resolver on SunOS.  The
       second includes hacks for "doing the right thing".

To use DNS under SunOS, you need to rebuild the libc shared library.  Here is a
post from some time ago that shows exactly how to do that.  I have used it, and
it does work on SunOS 4.1.  However, it generates a resolver that doesn't "do
the right thing."

===============  Begin included post  =========================================
>From: adrian@accucx.cc.ruu.nl (Adrian P. van Bloois)
>Newsgroups: comp.unix.admin
>Subject: named and SUNOS 4.1
>Keywords: Using named without NIS on SUNOS 4.1
>Date: 19 Dec 90 15:46:46 GMT


This is a procedure you can use to substitute or add 
a module in your shared libc C library. 

Note! If you are interested in a System V libc, please substitute
	libc_pic.a for libcs5_pic.a in step 3, 
	libc.so.x.y.z for libcs5.so.x.y.z in step 8.

-------------------------------------------------------------------------
0. From the directory /usr/lib/shlib.etc

1. Become super user
	% su

2. Make a temporary directory
	# mkdir tmp

3. Change to the "tmp" directory just made, extract the pic .o from 
   libc_pic.a and rm the file __.SYMDEF. The reason you need to do 
   the 2 (or 3) "mv" commands is because "ar" truncated filenames over 
   16 characters.
	# cd tmp
	# ar x ../libc_pic.a
	# rm __.SYMDEF
	# mv rpc_dtablesize. rpc_dtablesize.o
	# mv rpc_commondata. rpc_commondata.o
   If on a Sun-4, perform this additional `mv' command:
	# mv xccs.multibyte. xccs.multibyte.o

Here are some extra instructions for building a shared libc.so that uses the
resolver for hostname/addr resolution:

3a. Extract the contents of libc_pic.a and /usr/lib/libresolv.a into the
    tmp directory:
	# ar x /usr/lib/libresolv.a

    The libresolv.a contains object modules that are position independant, so
    they can be added to the libc_pic modules.

    *Note*  If you have your own copy of the resolver library sources,
    (perhaps from a post-4.8 BIND distribution) you can compile each of these
    modules yourself using `cc -pic' and the resulting object modules *should*
    be usable in this schema as well.  To test that the custom resolver
    modules will be usable, cd to the directory containing the custom resolver
    sources and object modules and perform this test:

	# ld -assert pure-text *.o

    If `ld' issues no complaints, then you can assume that the object modules
    are safe to use.

3b. Remove the old routine to do the hostname/addr resolution:
	# rm gethostent.o

3c. Remove the libresolv module that contains `strncasecmp' (which is now
    in the main C library, so it is redundant):
	# rm strcasecmp.o

3d. As mentioned in step 5 below, edit the file `lorder-sparc' in the ..
    directory.  Remove the reference to `gethostent.o' and add the
    references to the resolver library routines by applying this patch:

	*** lorder-sparc.orig	Thu Feb  8 05:27:46 1990
	--- lorder-sparc	Mon Apr  9 12:58:59 1990
	***************
	*** 150,154 ****
	  getwd.o
	  getnetgrent.o
	! gethostent.o
	  ypxdr.o
	  ttyname.o
	--- 150,161 ----
	  getwd.o
	  getnetgrent.o
	! gethostnamadr.o
	! sethostent.o
	! res_query.o
	! res_mkquery.o
	! res_send.o
	! res_debug.o
	! res_comp.o
	! res_init.o
	  ypxdr.o
	  ttyname.o

3e. Continue on, from steps 6 to 9 (i.e., skip steps 4 and 5 immediately below).

------------------------------------------------------------------------------

4. Replace or add the .o that you wanted by doing a copy. Please
   note here that you are advised to create your object with
   the following compiler option, i.e "cc -c -pic yourprogram.c" to make
   it shareable.
	# cp your.o .

5. If you add a new module then you need to do this step.
   You need to edit the file "lorder-sparc" and add the name of the file
   you have copied from step 4 at the end of this file. 
	# vi ../lorder-sparc

6. 	# cd ..

7. 	# make libc.so

8. Now you should have some libc.so.x.y.z built in the current directory.
   It is recommended that you tested out this library at this point 
   before installing it. You can do so by setting the environment
   LD_LIBRARY_PATH  to the current directory for example:
   	# setenv LD_LIBRARY_PATH `pwd`
	# your_favorite_test_cmd
   Once you are satisfied that the new library worked, you can proceed
   to install it with the following commands:
	# cp libc.so.x.y.z /usr/lib
	# ldconfig
	# unsetenv LD_LIBRARY_PATH

9. 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.
===============  End of included post  ========================================


Of course, following the above directions yields a resolver that ignores the
/etc/hosts file.  A more recent post references a procedure available via FTP.


===============  Begin included post  =========================================
>From: andys@ulysses.att.com (Andy Sherman)
>Newsgroups: comp.sys.sun
>Subject: Re: SunOS 4.1 Name Resolution Libraries
>Date: 25 Jan 91 15:09:27 GMT
>Approved: Sun-Spots@rice.edu
>X-Refs:  Original: v10n15
>X-Sun-Spots-Digest: Volume 10, Issue 26, message 10
>X-Note: Submissions: sun-spots@rice.edu, Admin: sun-spots-request@rice.edu

In article <1236@brchh104.bnr.ca> lofaso@titan.tsd.arlut.utexas.edu
 (Bernie Lofaso) writes:

>It appears as though the name resolution libraries on uunet do not work
>under SunOS 4.1, although we have used them successfully under 4.0.3. Can
>anyone confirm this? Are resolver libraries available for 4.1?

They're not needed for 4.1, since the release contains the tools to
customize the shared C library.  Greg Earle, Sun's on-site support person
at JPL has posted instructions for how to do the resolver to the
sun-managers list, and possibly to this list.  Perhaps the moderator will
add an archive reference to this.  If not, send me mail and I'll see if I
can find it to repost it.

[[Ed's Note: I think I have the right reference although it doesn't appear
to be from Greg Earle (might have inherited someone's name that reposted
it) -bdg]]

FTP:	Hostname : titan.rice.edu
	Directory: sun-source
	Filename : bindon41.shar

Archive Server Address: archive-server@rice.edu
Archive Server Command: send sun-source bindon41.shar

Andy Sherman/AT&T Bell Laboratories/Murray Hill, NJ
AUDIBLE:  (201) 582-5928
READABLE: andys@ulysses.att.com  or att!ulysses!andys
===============  End of included post  ========================================

I retrieved bindon41.shar, hoping it would eventually produce a smarter
resolver.  It includes instructions for FTPing the BIND source from
ucbarpa.berkeley.edu and applying a few (included) patches.  When I followed
the instructions, I got a working version of DNS, but it still ignored the
/etc/hosts file!  However, I had the source, so all was not lost.

The routine used by the network programs (telnet, ftp, etc.) to translate from
a host name to a host address is gethostbyname().  I found this entry in the
BIND source file gethostnamadr.c.  At then end of gethostbyname(), it does
check the /etc/hosts file if connection to the name server was refused.  I
broadened this behavior to check /etc/host if the name wasn't resolved for any
reason.  Here's the diff output for my modification.

diff gethostnamadr.c gethostnamadr.c.patched.orig

264,265c264,267
< 		/*  couldn't get it from name server, try hosts file  */
< 		return (_gethtbyname(name));
---
> 		if (errno == ECONNREFUSED)
> 			return (_gethtbyname(name));
> 		else
> 			return ((struct hostent *) NULL);
294,295c296,298
< 		/*  couldn't get it from name server, try hosts file  */
< 		return (_gethtbyaddr(addr, len, type));
---
> 		if (errno == ECONNREFUSED)
> 			return (_gethtbyaddr(addr, len, type));
> 		return ((struct hostent *) NULL);

The resulting resolver works just fine.  It uses the name server first, and if
that fails it checks it's /etc/hosts file.  I am using it on several systems
now, and haven't experienced any problems.

One last point, (from bindon41.shar), to use DNS as described above,

       You will require SunOS 4.1, and you must have the "Shlib_Custom"
       option installed.  If you didn't select the "Shlib_Custom" option
       when you installed your system, use the SunOS add_services(8)
       command to load it from the distribution tapes.

That's it.  I hope this post helps you as much as the originals have helped me
(thanks all!).  I welcome any questions and will answer as time permits (I get
REALLY busy sometimes (don't we all)).

Finally, <minor flame on>

Attention SUN!!!

I hope you will work on your implementation of the resolver to make these kind
of calestenics unnecessary!

<flame off>

..rob (rob@ssvax1.dnet.loral.com>

a2824ak@sunmanager.lrz-muenchen.de (Thomas Kaiser) (03/13/91)

>I retrieved bindon41.shar, hoping it would eventually produce a smarter
>resolver.  It includes instructions for FTPing the BIND source from
>ucbarpa.berkeley.edu and applying a few (included) patches.  When I followed
>the instructions, I got a working version of DNS, but it still ignored the
>/etc/hosts file!  However, I had the source, so all was not lost.

>The routine used by the network programs (telnet, ftp, etc.) to translate from
>a host name to a host address is gethostbyname().  I found this entry in the
>BIND source file gethostnamadr.c.  At then end of gethostbyname(), it does
>check the /etc/hosts file if connection to the name server was refused.  I
>broadened this behavior to check /etc/host if the name wasn't resolved for any
>reason.  Here's the diff output for my modification.

I also modified the original bind4.8.2 resolver routines. In mine i use
first /etc/hosts and then the resolver. I've done for both gethostbyname
and gethostbyaddr.

The problem with the other way round, is that the resolver routines have
to wait for timeout, if there is no information or nameserver. You
can also put shortnames in your /etc/hosts-file

Thomas Kaiser
Leibniz Computing Centre Munich
smtp =kaiser@sunmanager.lrz-muenchen.de
X.400=kaiser@lrz.lrz-muenchen.dbp.de
--
-------------------------------------------------------------------------
Thomas Kaiser         Internet:	kaiser@sunmanager.lrz-muenchen.de
LRZ-Muenchen          X400:	C=DE;A=DBP;P=LRZ-MUENCHEN;OU=LRZ;S=Kaiser
-------------------------------------------------------------------------

Kimmo.Suominen@lut.fi (Kimmo Suominen) (03/15/91)

>>>>> On 12 Mar 91 18:44:16 GMT, a2824ak@sunmanager.lrz-muenchen.de (Thomas Kaiser) said:

Thomas> I also modified the original bind4.8.2 resolver routines. In
Thomas> mine i use first /etc/hosts and then the resolver. I've done
Thomas> for both gethostbyname and gethostbyaddr.

The problem here is, that you'll get wrong information, if you don't
update your /etc/hosts.  I'd prefer having the file as a backup.

Thomas> The problem with the other way round, is that the resolver
Thomas> routines have to wait for timeout, if there is no information
Thomas> or nameserver. You can also put shortnames in your
Thomas> /etc/hosts-file

Well, why don't you use CNAME entries in the DNS and benefit
everyone in your domain?
--
Kim                      /  Internet: Kimmo.Suominen@lut.fi
"That's what I think."  /   Bitnet:   KIM@FINFILES

jkramer@molbio.med.miami.edu (Jack Kramer) (03/15/91)

I am not a big fan of ULTRIX but this is one case where DEC has done it
right.  The attached man page from an ULTRIX machine describes the
svcorder file which allows specification of which methods to use to
resolve name->address resolution and the specific order in which to 
use /etc/hosts or BIND or YP.  Perhaps the other BSD folks (Sun?)
could swallow a little pride and provide the same elegant solution.
It still allows the use of YP without shoving it down our throats.


---------------------------------------------------------------------

NAME
     svcorder - designate the order and selection of services

SYNTAX
     /etc/svcorder

DESCRIPTION
     The svcorder file designates the order and selection of name
     services that will be queried to resolve host names and
     addresses.  The queries to the services are made through the
     gethostent interface.

     The svcorder file must exist if your system accesses host
     names and addresses by database lookup services such as Yel-
     low Pages (YP) or BIND.  You do not need the svcorder file
     if you only have local access, that is, if you are using
     only the local /etc/hosts file to obtain host name and
     address information.

     The service names are defined in the /usr/include/netdb.h
     file.

     The order in which the service names are placed in the
     svcorder file indicates the order that they are queried to
     resolve a given name or address.  The following example
     shows the contents of the svcorder file if YP will be
     queried first, then BIND, and then the local service, if YP
     cannot resolve the data:

          yp
          bind
          local

     The svcorder file must have an entry for local. Otherwise,
     your system cannot resolve any queries in the event that the
     lookup services, other than local, are down.

     If you set up a database lookup service such as YP or BIND,
     be sure that the svcorder file exists.  Create the file if
     it does not.  The ypsetup and bindsetup commands do this
     automatically.

FILES
     /etc/hosts
     /usr/include/netdb.h
     /etc/svcorder

SEE ALSO
     gethostent(3n), hosts(5), bindsetup(8), ypsetup(8yp)
     Guide to the BIND Service
     Guide to the Yellow Pages Service




                                                                1