Cover V10, I09

Article

sep2001.tar


Questions and Answers

Amy Rich

In last month's issue, we had a question regarding the differences between SAN and NAS. The answer given had the explanations of the two reversed. NAS (like NetApp) are storage devices attached to the network and SAN (like EMC) are storage devices attached to a computer via fiber/SCSI. We regret any confusion resulting from this error -- the editors.

Q I'm trying to put a Perl script into my .forward to handle a bunch of spam that I get. My .forward looks like the following:

|/home/jr/scripts/spamcull.pl
When I get mail, I receive a message stating "Service Unavailable". Is there some other way I should be calling the script from my .forward? I'm using Red Hat Linux 6.2.

A You may want to consider something like Procmail (http://www.procmail.org/) to do spam culling for you instead of trying to roll your own script. procmail is a powerful recipe-based filter that you can stick in as the LDA or call from .forward. As to why you're getting "Service Unavailable", this sounds like it may be a smrsh problem. Are you using smrsh in conjunction with Sendmail? If so, you may need to symlink your script into your smrsh directory (often /etc/smrsh or /etc/mail/smrsh).

Q I want to write a quick Perl script that takes a bunch of file names, reads them in, and stores them. I know how to do this sequentially, but it seems like this would be the right place to put in a function. Is there a quick "read and assign" function to which you can point me?

A You'll want to iterate through a loop of file names and perhaps do an array of arrays for the actual assignments in the main loop. Your read/assign function will probably look something like the following, however:

sub readfile {
  my ($fname) = shift;  # name of the file, passed from the main loop
  local (*FILEH);       # the file handle

  open (FILEH, $fname) || die "Can't open $fname: $!\n"; # open or die
  my (@filea) = <FILEH>;      # read in the file to an array
  close (FILEH);              # close the file
  return @filea;              # return the array
}
Q What does rc stand for in a UNIX context? Does it stand for run-level command or run command, or something like that? Is there any authoritative documentation?

A I'd consider Brian Kernighan and Dennis Ritchie fairly authoritative, and the UNIX FAQ (http://www.faqs.org/faqs/unix-faq/faq/part1/) has the following to say:

rc (as in ".cshrc" or "/etc/rc") = "RunCom"

"rc" derives from "runcom", from the MIT CTSS system, ca. 1965.

"There was a facility that would execute a bunch of commands stored in a file; it was called "runcom" for "run commands", and the file began to be called "a runcom."

"rc" in Unix is a fossil from that usage."

Brian Kernighan & Dennis Ritchie, as told to Vicki Brown

Q We are using jumpstart to automate our Solaris installs. At the end, the jumpstart finish script installs a script that runs after reboot to install the custom software packages via executing pkgadd commands. These pkgadd commands in turn have pre- and post-install scripts and want to interact with the installer. When trying to install, the pkgadd has errors and fail because the pre- and post-install scripts don't get that user interaction. Do you know how I could automate this?

A You can have pkgadd use an alternate administrative file and do installs without manual intervention. Your pkgadd command will look something like the following:

pkgadd -n -a $adminfile $package
$adminfile will be another file in your jumpstart setup that contains the following text (or you can tailor to taste):

mail=
instance=quit
partial=nocheck
runlevel=nocheck
idepend=nocheck
rdepend=nocheck
space=ask
setuid=nocheck
conflict=nocheck
action=nocheck
basedir=default
This gives the pkgadd command all the answers it needs to do the installation without intervention, unless you don't have enough space. The default administration file is located in /var/sadm/install/admin/default, and specifies ask for most of the above questions:

mail=
instance=unique
partial=ask
runlevel=ask
idepend=ask
rdepend=ask
space=ask
setuid=ask
conflict=ask
action=ask
basedir=default
See the man page for pkgadd(1M) for more information on the available flags, and admin(4) for more information on the parameters in the admin file.

Q I have a script that I want to run unattended, but occasionally it may prompt the user for input. I'm never sure how many times it will prompt (it changes based on the OS it's running on), but the answer should always be "yes". Is there an easy way to automate this so that no one has to sit at the window and input "yes" at random times?

A If your answer should always be yes, it sounds like you may just be better off removing the conditions from the script. However, there are a couple ways you can automate this. For flexibility's sake (in case you ever want to answer "no" or something else), you could wrap your script with expect. If you're sure you're always going to say "yes", you can just pipe the output of the yes program to your script:

yes yes | ./script
The yes program takes an argument that it will continuously print out. If you don't give it an argument, it will continuously print out the letter "y".

Q How can I tell which Perl modules I have installed with my Perl distribution?

A You can get a complete listing of the third-party modules installed by doing a:

perldoc perllocal
The output should list the module name, where it was installed, the linktype, the version, and any executable files. Here's an example for CPAN:

  Mon Apr  2 13:33:21 2001: 'Module' the CPAN manpage

o   `installed into: /usr/local/lib/perl5/5.6.0'

o   `LINKTYPE: dynamic'

o   `VERSION: 1.59'


o   `EXE_FILES: cpan'
Q I'm trying to set up fetchmail to retrieve mail from an ISP account via IMAP, but it seems to want Sendmail running on the local machine. I don't really want to open up Sendmail to the outside world because it's an unnecessary security risk (since I'm just pulling down mail from other places and not actually accepting SMTP requests from the outside world). Is there a way to use fetchmail without enabling an MTA?

A fetchmail must have an MTA to connect to in order to deliver your mail. What you can do is bind Sendmail to the loopback interface only, and not your public (or private) interface. In your fetchmailrc file, set the following so that fetchmail tries to connect to the loopback interface instead of another interface on your machine. It should try the loopback interface anyway if you're not using ETRN, ODMR, or Kerberos auth (where the domain name is added), but it doesn't hurt to explicitly set it here:

smtphost 127.0.0.1
In your Sendmail mc file, add the following lines:

FEATURE(`no_default_msa')dnl
DAEMON_OPTIONS(`Name=MTA',`Addr=127.0.0.1')dnl
This makes it so that the daemon will only answer on the loopback interface, and it deletes the default entry for MSA. Be sure to rebuild your cf file and test it before putting it into place.

Q On a Solaris 7 SPARC machine, how do I increase the security of the TCP random number generator?

A If you're talking about the way selected TCP ports are randomized, you want to change the file /etc/default/inetinit to be the following:

# @(#)inetinit.dfl 1.2 97/05/08
#
# TCP_STRONG_ISS sets the TCP initial sequence number generation 
# parameters.
# Set TCP_STRONG_ISS to be:
#     0 = Old-fashioned sequential initial sequence number generation.
#     1 = Improved sequential generation, with random variance in increment.
#     2 = RFC 1948 sequence number generation, unique-per-connection-ID.
#
TCP_STRONG_ISS=2
If you're talking about random number generation in general, 64-bit Solaris doesn't have a /dev/random or a /dev/urandom, so you would want to install something third party or freeware like egd (which I've had problems with because it doesn't generate enough entropy to run both OpenSSL and OpenSSH), prngd, or ANDIrand.

Q For security purposes, I want to track down all of the world-writable files on my AIX system. How would I go about this?

A The best tool for this is find. You can search for world-writable files with the following command (you should be root or you'll receive a lot of "permission denied" errors):

find / -type f -perm +0002 -print
If you want to look for group-writable files as well, you can do:

find / -type f -perm +0022 -print
You may also want to look for SUID and SGID executables while you're at it. Take a look at the man page for more information on find.

Q I have an Ultra 10 running Solaris 8. When I take a look at the routing table, I see a lot of routes that are seemingly useless. If I flush the routing table, most of them disappear but then come back again later. There's obviously something messing with the routing table. What is it, and how do I stop it?

A There are two likely candidates for your problem. Solaris comes with two binaries that may start at boot time and will edit your routing table on the fly -- in.routed and in.rdisc. You can shut off routed by giving your machine an explicit default route in /etc/defaultrouter. The router discovery daemon (rdisc) is started if you have multiple interfaces not configured by DHCP. You can turn it off by touching the file /etc/notrouter. Both of these processes are started as part of /etc/init.d/inetinit (hard-linked to by /etc/rc2.d/S69inet). Take a look at the man pages for in.rdisc, in.routed, and defaultrouter and the /etc/init.d/inetinit script for more information.

Q I'm running Sendmail 8.11.3, and I'm seeing a huge number of Sendmail processes sending mail outbound. Is there some way I can cut down on the number of processes Sendmail forks? This is killing my poor machine.

A You can limit the number of daemon children with MaxDaemonChildren. You'll probably also want to queue all outgoing mail and then run the queue to deliver mail. This will order your processes sequentially instead of forking for every new outbound mail delivery. Add the following to your mc file and rebuild your cf file (adjust the maximum number of processes and the minimum queue age to suit your machine):

define(`confMAX_DAEMON_CHILDREN',`10')dnl
define(`confDELIVERY_MODE',`queueonly')dnl
define(`confMIN_QUEUE_AGE',`10m')dnl
The MinQueueAge macro defines the time between delivery attempts of any one message. So, if your message can't be delivered the first time around, it waits another 10 minutes in this case (default is 30 minutes). Tweak this variable to taste, depending on whether you have a lot of transient delivery issues.

When you start Sendmail, you'll want to run the queue at some frequent interval (say every 10 minutes), so your mail doesn't sit on your machine for too long:

sendmail -q10m -bd
The -bd is optional if you're not running a daemon (e.g., you're only sending mail out, not accepting mail).

Q I'm running a 4.3-Release FreeBSD machine. Hooked to it is an Overland Data Loader Express DLT Tape Library. I can access whatever tape I happen to load manually. Is there any way to have it automatically load a specific tape?

A You'll want to take a look at the man page for chio. This should handle most generic loaders. For example, you can move slot 2 to drive 0, do a dump of /, /usr, /var, and /home, and then move the tape back out to its original slot with the following commands:

chio move slot 2 drive 0
dump 0auf /dev/nrsa0 /
dump 0auf /dev/nrsa0 /usr
dump 0auf /dev/nrsa0 /var
dump 0auf /dev/nrsa0 /home
mt -f /dev/nrsa0 offline
chio move drive 0 slot 2
You may need to add the ch device (SCSI media changer) to your kernel config and remake your kernel. Take a look at /usr/src/sys/i386/conf/LINT for all kernel options and the FreeBSD handbook on how to configure your kernel:

http://www.freebsd.org/doc/en_US.ISO_8859-1/books/handbook/kernelconfig.html
Q Does Sun have an area on their site that lets you determine what hardware corresponds to what part number? I have a CPU board and a memory module, and I'm trying to figure out if I have the right bits to scavenge for another machine.

A You can take a look at Sun's spare parts list, located at:

http://www.sun.com/ibb/spares/parts-list/TOC.html
If you have some idea of what you're looking for, they have listings of current spare parts for various types of hardware. So, if you have a CPU board that you want to put in an E3500, you can select the E3500 spare parts list and see if what you have matches. If you have spare parts and have no idea what they came from, you can also try a search for the part number on:

http://store.sun.com/
Q I have a FreeBSD 4.2 PC, and I want to rip out Sendmail and run postfix instead. How do I completely remove Sendmail and install postfix in its place?

A You don't actually have to remove Sendmail. Later versions of FreeBSD have a config file called /etc/mail/mailer.conf that determines what binary gets called when the following programs are run:

sendmail
send-mail
mailq
newaliases
Install postfix from the ports collection as root and configure to your liking:

cd /usr/ports/mail/postfix
make install
If you aren't familiar with the ports collection, take a look at the packages and ports section of the FreeBSD Handbook:

http://www.freebsd.org/doc/en_US.ISO_8859-1/books/handbook/ports.html
Once you have postfix working the way you want, change /etc/mail/mailer.conf to point to your postfix binary (usually installed in /usr/libexec/postfix) instead of the Sendmail binary. You may also want to edit /etc/make.conf so that future upgrades of FreeBSD do not upgrade Sendmail as well:

NO_SENDMAIL=yes
You may also want to take Sendmail out of /etc/rc.conf, depending on how you plan on running postfix (or at least change the Sendmail options):

sendmail_enable="NO"
Q I have an old Sun IPX running Solaris 2.5.1 with the recommended patch set from 05/04/2001. I'm seeing some weirdness when I do an ls or a ps. An ls shows no files at all (as if the filesystem is completely invisible), and ps claims it can't execute. Here's some real output:

$ echo "this is a test" > foo
$ ls foo
$
$ cat foo
this is a test
$ mv foo bar
$ ls bar
$
So, I did a ps to see what was going on, and I got:

$ ps -elf
/usr/local/bin/bash: ps: cannot execute
However, /usr/ucb/ps works just fine. Have you seen anything like this before? Did the system somehow manage to get corrupted?

A It looks as though you've been hacked and someone has installed an improperly implemented rootkit. Instead of just hiding some files with ls, it's hiding them all, and instead of hiding some processes with ps, it's just refusing to execute (probably installed with the wrong permissions). You'll want to find out how they broke in, when they broke in, and restore from known backups and patch from there. I hope you've been doing some sort of security monitoring all along, or it's going to be very difficult to track down the hole and fix it. You may just be better off upgrading to Solaris 7 (the IPX isn't supported for Solaris 8) and restoring only your data.

Q I'm trying to script some jumpstart stuff to comment out lines in a Solaris startup file. The text of the file looks something like:

echo "Setting default...
<some other lines>
    -netmask 240
I want to comment out all the lines in between those two lines. I can't use Perl because the jumpstart stuff all has to be done in bourne shell. Any clues?

A You can use sed to do this if you have unique begin and end strings in the file. Try the following (where $file is the file you want to modify):

sed -e '/^echo "Setting default/,/^    -netmask 240/ s/^/#/' \
 < $file > /tmp/newfile
cp /tmp/newfile $file
rm -f /tmp/newfile
If you'd rather just delete the lines instead of commenting them out, you can do:

sed -e '/^echo "Setting default/,/^ -netmask 240/d' \
 < $file > /tmp/newfile cp /tmp/newfile $file rm -f /tmp/newfile
 
Amy Rich, president of the Boston-based Oceanwave Consulting, Inc. (http://www.oceanwave.com), has been a UNIX systems administrator for more than five years. She received a BSCS at Worcester Polytechnic Institute, and can be reached at: arr@oceanwave.com.