Cover V12, I08

Article

aug2003.tar

Questions and Answers

Amy Rich

Q The sendmail documentation seems very incomplete in explaining the difference between an MSP and an MSA. Can you tell me what these are (besides just expanding the abbreviations)?

A A bit of history will probably best help explain what an MSA (mail submission agent) actually is. SMTP was originally designed as a way to route and deliver complete mail messages between machines. Mail transfer agents (MTAs) were meant to handle SMTP transactions and not meant to modify the message beyond adding a few headers. Because many mail user agents (MUAs) like Outlook, Netscape, and others try to inject mail directly to the MTA, it now has to examine the message and possibly perform header and body modifications. The "program" that modifies the message is now known as the MSA. In sendmail, the MTA and the MSA are part of the same binary (sendmail). The MTA runs on port 25 while the MSA generally runs on port 587. For more detailed information about the MSA protocol, see RFC 2476:

http://www.faqs.org/rfcs/rfc2476.html
Confusingly, the sendmail binary once again does double duty as the MSP (mail submission program) binary. When called as an MSP, sendmail reads the configuration file submit.cf instead of the configuration file sendmail.cf. The MSP evolved from the security-motivated desire to remove the SUID bit from the sendmail binary. Instead of needing to be root to write to /var/spool/mqueue, the sendmail binary is now SGID smmsp, and the local clientmqueue directory (/var/spool/clientmqueue by default) is owned by the smmsp user and group. The MSP is invoked by programs or users on the local machine in order to inject email to this local queue directory. The MSP does not run as a daemon and cannot accept connections from remote machines, unlike the MTA and MSA.

Q I'm trying to use the shell command join. It has an option (-t), which accepts a character as field delimiter. I'd like the data to be tab delimited, but my shell interprets the tab key as file completion. I tried the following ways to specify a tab on the command line:

join -t '\t' file1 file2
join -t 'echo '\t'' file1 file2
These don't seem to work here, even though I've had success with this syntax using other shell commands. How do you specify the tab character?

A It sounds like your version of join (you don't mention your OS) does not use \t to represent a tab character. I suggest you output the tab character by using the terminal's lnext key followed by the tab key. To find out what your lnext key is mapped to, use stty -a (generally it's control-v, as shown in the output below):

stty -a
speed 38400 baud; 56 rows; 80 columns;
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
   -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
   -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -ignbrk
   brkint -inpck -ignpar -parmrk
oflags: opost onlcr -ocrnl -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
   -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = <undef>; eof = ^D; eol = <undef>;
   eol2 = <undef>; erase = ^H; erase2 = ^H; intr = ^C; kill = ^U;
   lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q;
   status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W;
So you'd get the embedded tab by doing:

join -t'^V<tab>' file1 file2
If you want a portable method for a script, you can also use tr to set a variable called TAB and then use that as the argument to join -t:

TAB=$(echo x|tr x '\9')
join -t"${TAB}" file1 file2
Q I am running BIND 9.2.2 on a Linux machine. I would like to know how to restrict forwarding only to those servers explicitly listed as forwarders. I don't want my server querying the root servers if its forwarders cannot resolve a name.

A You need to specify "forward only" in the options section of your named.conf file, and then specify your forwarders:

options {
  forward only;
  forwarders { ip1; ip2; ip3; };
}
Q I've been trying to get mod_rewite to work with my Apache 1.3.27 setup without much success. I have the following .htaccess file in the root of my document tree:

RewriteEngine On
RewriteBase /
RewriteRule ^(.*)$ info.php?s=$1
The last rule is supposed to send all requests to the info.php script. http://www.my.domain/root/dir2/dir3/ should be rewritten as http://www.my.domain/info.php?s=root/dir2/dir3, for example. But instead, I get:

http://www.my.domain/info.php?s=info.php
I've read http://httpd.apache.org/docs/mod/mod_rewrite.html and I think I have things right, but obviously I've munged the rewrite rule somehow. I'm not sure what the correct syntax is or why mine fails. Can you help me with the right syntax?

A Your syntax is indeed incorrect. You need to specify the full path (relative to your docroot) to info.php in your RewriteRule. Making sure that /full/path/to matches whatever is right for your system, change your rule to:

RewriteRule ^(.*)$ /full/path/to/info.php?s=$1
In your case, it looks like you want:

RewriteRule ^(.*)$ /info.php?s=$1
Set the the RewriteLogLevel to 9 in httpd.conf for more log information to show why this is necessary:

RewriteLog "/tmp/rewrite.log"
RewriteLogLevel 9
Without the full path to info.php, you'll see:

<client IP> - - [05/May/2003:17:17:38 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (2) 
  init rewrite engine with requested uri /foo
<client IP> - - [05/May/2003:17:17:38 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (3) 
  applying pattern '^(.*)$' to uri '/foo'
<client IP> - - [05/May/2003:17:17:38 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (2) 
  rewrite /foo -> /info.php?s=/foo
<client IP> - - [05/May/2003:17:17:38 -0400]
  [www.my.domain/sid#8162160][rid#815c038/initial] (3) 
  split uri=/info.php?s=/foo -> uri=/info.php, args=s=/foo
<client IP> - - [05/May/2003:17:17:38 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (2) 
  local path result: /info.php
Contrast that with the rewrite rule changed to use /info.php:

<client IP> - - [05/May/2003:17:17:50 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (2) 
  init rewrite engine with requested uri /bar
<client IP> - - [05/May/2003:17:17:50 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (3) 
  applying pattern '^(.*)$' to uri '/bar'
<client IP> - - [05/May/2003:17:17:50 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (2) 
  rewrite /bar -> /info.php?s=/bar
<client IP> - - [05/May/2003:17:17:50 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (3) 
  split uri=/info.php?s=/bar -> uri=/info.php, args=s=/bar
<client IP> - - [05/May/2003:17:17:50 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (2) 
  local path result: /info.php
<client IP> - - [05/May/2003:17:17:50 -0400] 
  [www.my.domain/sid#8162160][rid#815c038/initial] (1) 
  go-ahead with /info.php [OK]
Q I'm writing a new system where a Perl script processes mail and changes the From: address to bounce-<something>@my.domain, where <something> is a folder name. I then want to create a bounce user and have each message directed to the appropriate folder. For example, bounce-foo will go to the folder foo. This means that I will need to have sendmail be able to handle user-foo@address-style entries. How would I accomplish this?

A Since you're writing this from scratch, I highly recommend using bounce+<something>@my.domain instead, since sendmail and local delivery agents like cyrus and procmail have built-in support for user+detail handling. Using sendmail with procmail or cyrus as the local delivery agent then makes your task trivial. Take a look at the sendmail features file for more information:

http://www.sendmail.org/m4/features.html
Q I'm using bash 2.05b.0(8) on a FreeBSD 4.8-STABLE machine. The commands executed from my .bashrc (set -o, complete, etc.) are written to my .bash_history. This is annoying because using the cursor keys to look at entries stored in the history includes these commands from my .bashrc. I can't believe that this is common practice, so what am I doing wrong? Here's my .bashrc:

  LOGNAME=$USER
  MAIL="/var/mail/$USER"

  EDITOR=/usr/local/bin/vim
  VISUAL=/usr/local/bin/vim
  HISTFILESIZE=1000
  HISTSIZE=1000
  PAGER=/usr/bin/less
  MANPATH=/usr/man:/usr/X11R6/man:/usr/local/man:/usr/share/man
  PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/ \
  local/bin:/usr/X11R6/bin:/usr/local/bin

  export USER SHELL LOGNAME MAIL EDITOR VISUAL HISTFILESIZE HISTSIZE
  export PAGER MANPATH PATH

  export HOSTNAME='/bin/hostname'
  export ARCH='/usr/bin/uname -p'
  export OSREV='/usr/bin/uname -r'

  export PS1="[\u@\h \w]\\$ "

  umask 022
  set -o history
  set -o notify
  set -o vi
  set -o noclobber

  if [ "${BASH_VERSION%.*}" \> "2.04" ]; then
    complete -A shopt shopt
    complete -A directory  mkdir rmdir
    complete -A directory -o default cd
    complete -f -o default -X '!*.gz'  gunzip
    complete -f -o default -X '!*.bz2' bunzip2
    complete -f -o default -X '!*.pl'  perl perl5
    complete -f -o default -X '!*.ps'  gs ghostview ps2pdf ps2ascii
    complete -f -o default -X '!*.dvi' dvips dvipdf xdvi dviselect dvitype
    complete -f -o default -X '!*.pdf' acroread pdf2ps
    complete -f -o default -X '!*.+(pdf|ps)' gv
    complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf
    complete -f -o default -X '!*.tex' tex latex slitex
    complete -f -o default -X '!*.lyx' lyx
    complete -f -o default -X '!*.+(jpg|gif|xpm|png|bmp)' xv gimp
    complete -f -o default -X '!*.mp3' mpg123
    complete -f -o default -X '!*.ogg' ogg123
  fi
A Your problem lies in the fact that you have set -o history in a sourced file. By default, sourcing a file turns off history, but you've manually overridden that behavior. Any commands you run in your .bashrc after that line will be copied into your .bash_history file. Having that line in your .bashrc also doesn't do what you want. It only turns on history for the duration of the sourcing, not for the calling shell. History is on by default in bash, so if you just remove that line from your .bashrc, things should work as you expect.

Q I'm running BIND 8.2.3-REL on Solaris 2.5, and I'm seeing a lot of these error messages in /var/adm/messages:

Jun 18 11:27:29 myhost named[1302]: denied update from [IP].4126 for "my.domain"
How can I stop these messages from being logged? I have tried turning off logging this category in my named.conf, but without any success. Is this a known bug of 8.2.3? Is it fixed in 8.3.4? Here's what I have in /etc/named.conf:

logging {
  category statistics { null; };
  category maintenance { null; };
  category update { null; };
  category lame-servers { null; };
};

options {
  datasize default;
  stacksize default;
  coresize default;
  files unlimited;
  transfer-format one-answer;
  directory "/etc/named";
  pid-file "/var/run/named.pid";
  interface-interval 0;
  listen-on {
    127.0.0.1;
    192.168.1.1;
  };
  allow-recursion { 192.168.1.1/24; };
};

zone "0.0.127.IN-ADDR.ARPA" {
  type master;
  file "local";
};

zone "1.168.192.IN-ADDR.ARPA" {
  type master;
  file "192.168.1";
  allow-transfer {
    192.168.1.2;
  };
};

zone "my.domain" {
  type master;
  file "my.domain";
  allow-transfer {
    192.168.1.2;
  };
};
A First, I would strongly recommend upgrading your version of BIND due to security reasons. The latest version is 8.4.0. Failed updates are logged to the security category, which you don't mention in your named.conf. Instead of tossing all of the security notifications away, you may want to log them to a different file. If so, you can add the following to your logging section:

channel securitylog {
  file "/var/log/named.security";
  severity info;
};

category security { securitylog; };
If you just want to ignore them, you can route them to null, like you did with your other categories:

category security { null; };
Q I have sendmail running on a Solaris 9 machine. It is configured to use MIMEDefang 2.29 (for virus scanning) on a remote Linux machine, also running sendmail. Everything works when I'm just using IPv4 addresses, but when I try to use IPv6 addresses, I get an error:

May  19 00:19:09 linux-box mimedefang[PID]: MIMEDefang: connect[ID]: unknown family 54
May  19 00:19:09 solaris-box sendmail[PID]: [mail.error] <ID>: 
  milter_read(mimedefang): cmd read returned 0, expecting 5
Sendmail was compiled with the default settings for ENVDEF from the OS file, so it should have IPv6 support built in. Just in case, though, here's the file I used:

define('confCC', 'gcc')
define('confLDOPTS_SO', '-G')
define('confBEFORE', 'sysexits.h')
define('confMAPDEF', '-DNDBM -DMAP_REGEX')
define('confENVDEF', '-DSOLARIS=20900 -DNETINET6')
define('confSM_OS_HEADER', 'sm_os_sunos')
define('confLIBS', '-lsocket -lnsl')
define('confMTCCOPTS', '-D_REENTRANT')
define('confMTLDOPTS', '-lpthread')
define('confMBINDIR', '/usr/lib')
define('confEBINDIR', '/usr/lib')
define('confSBINGRP', 'sys')
define('confINSTALL', '${BUILDBIN}/install.sh')
define('confDEPEND_TYPE', 'CC-M')
PUSHDIVERT(3)
sysexits.h:
 if [ -r /usr/include/sysexits.h ]; \
 then \
   ln -s /usr/include/sysexits.h; \
 fi
POPDIVERT
I have the following line in the sendmail.mc file on the Solaris machine:

INPUT_MAIL_FILTER('mimedefang', 'S=inet:port@linux-box.my.domain, <options>')
DAEMON_OPTIONS('Name=MTA-v6, Family=inet6')       
If I take out the DAEMON_OPTIONS line above and replace it with:

DAEMON_OPTIONS('Name=MTA-v4, Family=inet')
things seem to work fine, but I'm no longer using IPv6.

If I comment out the INPUT_MAIL_FILTER but leave the DAEMON_OPTIONS('Name=MTA-v6, Family=inet6') line in, then mail gets delivered over IPv6, but it's not running MIMEDefang. Obviously, I don't have the right sequence of declarations in here, or I've managed to mess up the compile somehow. Any help would be appreciated.

A Your version of MIMEDefang does not support IPv6. IPv6 support was added to mimedefang.c's mfconnect in version 2.31. If you grab a new source distribution, read the accompanying docs and recompile, you should be able to use the IPv6 addresses as well as the IPv4 ones. You can get the latest source from:

http://www.roaringpenguin.com/mimedefang/
Also, you say that you used the OS file to compile sendmail, but that's not the default (you've removed the NIS information). You should never edit the OS file directly. Any changes you make should instead go into devtools/Site/site.config.m4.

Amy Rich, president of the Boston-based Oceanwave Consulting, Inc. (http://www.oceanwave.com), has been a UNIX systems administrator for more than 10 years. She received a BSCS at Worcester Polytechnic Institute, and can be reached at: qna@oceanwave.com.