diff options
author | Peter Wemm <peter@FreeBSD.org> | 1995-12-02 17:30:23 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 1995-12-02 17:30:23 +0000 |
commit | 58162a7314f7e4552e9585026529da1640363549 (patch) | |
tree | 8d6be8896a925b2043a5656b818313e358ae04d7 |
Notes
158 files changed, 76442 insertions, 0 deletions
diff --git a/usr.sbin/sendmail/FAQ b/usr.sbin/sendmail/FAQ new file mode 100644 index 000000000000..cc27e50805fd --- /dev/null +++ b/usr.sbin/sendmail/FAQ @@ -0,0 +1,731 @@ +Newsgroups: comp.mail.sendmail,comp.mail.misc,comp.mail.smail,comp.answers,news.answers +Subject: comp.mail.sendmail Frequently Asked Questions (FAQ) +From: brad@birch.ims.disa.mil (Brad Knowles) +Followup-to: comp.mail.sendmail +Summary: This posting contains a list of Frequently Asked Questions + (and their answers) about the program "sendmail", distributed + with many versions of Unix (and available for some other + operating systems). This FAQ is shared between + comp.mail.sendmail and the Sendmail V8 distribution. It should + be read by anyone who wishes to post to comp.mail.sendmail, or + anyone having questions about the newsgroup itself. + +Archive-name: mail/sendmail-faq +Posting-Frequency: monthly (first Monday) + + +[The most recent copy of this document can be obtained via anonymous +FTP from rtfm.mit.edu in /pub/usenet/news.answers/mail/sendmail-faq. +If you do not have access to anonymous FTP, you can retrieve it by +sending email to mail-server@rtfm.mit.edu with the command "send +usenet/news.answers/mail/sendmail-faq" in the message.] + + + + Sendmail Version 8 + Frequently Asked Questions + Last updated 9/17/95 + + +This FAQ is specific to Version 8.6.10 of sendmail. Other questions, +particularly regarding compilation and configuration, are answered in +src/READ_ME and cf/README (found in the V8 sendmail distribution). + +This is also the official FAQ for the Usenet newsgroup +comp.mail.sendmail. + +====================================================================== +BEFORE YOU GO ANY FURTHER +====================================================================== + + * What do you wish everyone would do before sending you mail or + posting to comp.mail.sendmail? + + Read this FAQ completely. Read src/READ_ME and cf/README + completely. Read the books written to help with common + problems such as compilation and installation, configuration, + security issues, etc.... Ask themselves if their question + hasn't already been answered. +---------------------------------------------------------------------- + * How can I be sure if this is the right place to look for answers + to my questions? + + 1. Do you know, for a fact, that the question is related to + sendmail V8? + + 2. Do you know, for a fact, that the question is related to an + older version of sendmail? + + 3. Is the question about a sendmail-like program (e.g., Smail, + Zmailer, MMDF, etc...)? + + 4. Is the question about an SMTP Gateway product for a LAN + mail package (e.g., cc:Mail, MS-Mail, WordPerfect + Office/GroupWise, etc...)? + + If you answered "yes" to the question #1, then this is the + right place. + + If you answered "yes" to questions #2 or #3, then you should + seriously consider upgrading to the most recent version of + sendmail V8. + + For question #2, If you're going to continue using an older + version of sendmail, you may not find much help and will + probably get some responses that amount to "Get V8". + Otherwise, this is probably the best place to look for + answers. + + If you answered "yes" to question #3 and are not going to + upgrade to sendmail V8, then this is probably not the right + place to look. + + If you answered "yes" to question #4, then this is almost + certainly not the right place to look. + + For questions #3 and #4, try looking around elsewhere in the + "comp.mail.*" hierarchy for a more appropriate newsgroup. + For example, you might want to try posting to comp.mail.misc + or comp.mail.smail. + + If you couldn't answer "yes" to any of the above questions, + then you're DEFINITELY in the wrong place. For the sake of + your sanity and ego, not to mention avoiding the waste of + your time and ours, try asking your System or E-Mail + Administrator(s) before you post any questions publicly. +---------------------------------------------------------------------- + * Where can I find the latest version of this FAQ? + + It is included in the most recent Version 8 distribution of + sendmail (described below), as well as via anonymous FTP from + rtfm.mit.edu in /pub/usenet/news.answers/mail/sendmail-faq. + If you do not have access to anonymous FTP, you can retrieve + it by sending email to mail-server@rtfm.mit.edu with the + command "send usenet/news.answers/mail/sendmail-faq" in the + message. +---------------------------------------------------------------------- + * I don't have access to Usenet news. Can I still get access to + comp.mail.sendmail? + + Yes. Send email to mxt@dl.ac.uk with the command "sub + comp-news.comp.mail.sendmail <full-US-ordered-email-address>" + in the message. + + E-mail you want posted on comp.mail.sendmail should be sent + to comp-mail-sendmail@dl.ac.uk +---------------------------------------------------------------------- + * I have sendmail-related DNS questions. Where should I ask them? + + Depending on how deeply they get into the DNS, they can be + asked here. However, you'll probably be told that you should + send them to the Info-BIND mailing list (if the question is + specific to that program) or to the Usenet newsgroup + comp.protocols.tcp-ip.domains (DNS in general). +---------------------------------------------------------------------- + * How do I subscribe to either of these? + + For comp.protocols.tcp-ip.domains, you have to be on Usenet. + They don't have a news-to-mail gateway yet. + + For the Info-BIND mailing list, send email to + bind-request@uunet.uu.net with the command "subscribe" in the + message. Submissions should be sent to bind@uunet.uu.net + +====================================================================== +GENERAL QUESTIONS +====================================================================== + + * Where can I get Version 8? + + Via anonymous FTP from FTP.CS.Berkeley.EDU in /ucb/sendmail. +---------------------------------------------------------------------- + * What are the differences between Version 8 and other versions? + + See doc/changes/changes.me in the sendmail distribution. +---------------------------------------------------------------------- + * What happened to sendmail 6.x and 7.x? + + When a new (Alpha/Beta) version of sendmail was released, it + was changed to Release 6. Development continued in that tree + until 4.4BSD was released, when everything on the 4.4 tape + was set to be version 8.1. Version 7.x never existed. +---------------------------------------------------------------------- + * What books are available describing sendmail? + + There is one book available devoted to sendmail: + + Costales, Allman, and Rickert, _Sendmail_. O'Reilly & + Associates. + + Several books have sendmail chapters, for example: + + Nemeth, Snyder, and Seebass, _Unix System Administration + Handbook_. Prentice-Hall. + Carl-Mitchell and Quarterman, _Practical Internetworking with + TCP/IP and UNIX_. Addison-Wesley. + Hunt, _TCP/IP Network Administration_. O'Reilly & Associates. + + Another book about sendmail is due out "soon": + + Avolio & Vixie, _Sendmail Theory and Practice_. Digital + Press (release date unknown). + + For details on sendmail-related DNS issues, consult: + + Liu and Albitz, _DNS and BIND_. O'Reilly & Associates. + + For details on UUCP, see: + + O'Reilly and Todino, _Managing UUCP and Usenet_. + O'Reilly & Associates. + +====================================================================== +COMPILING AND INSTALLING SENDMAIL 8 +====================================================================== + + * Version 8 requires a new version of "make". Where can I get this? + + Actually, Version 8 does not require a new version of "make". + It includes a collection of Makefiles for different architectures, + only one or two of which require the new "make". For a supported + architecture, use ``sh makesendmail''. If you are porting to a + new architecture, start with Makefile.dist. + + If you really do want the new make, it is available on any of + the BSD Net2 or 4.4-Lite distribution sites. These include: + + ftp.uu.net /systems/unix/bsd-sources + gatekeeper.dec.com /.0/BSD/net2 + ucquais.cba.uc.edu /pub/net2 + ftp.luth.se /pub/unix/4.3bsd/net2 + + Diffs and instructions for building this version of make + under SunOS 4.1.x are available on ftp.css.itd.umich.edu in + /pub/systems/sun/Net2-make.sun4.diff.Z. A patchkit for + Ultrix is on ftp.vix.com in /pub/patches/pmake-for-ultrix.Z. + Patches for AIX 3.2.4 are available on ftp.uni-stuttgart.de + in /sw/src/patches/bsd-make-rus-patches. + + There is also a Linux version available on the main Linux + distribution sites as pmake; this version is included as + standard with the current Slackware distributions. +---------------------------------------------------------------------- + * What macro package do I use to format the V8 man pages? + + The BSD group switched over the the ``mandoc'' macros for the + 4.4 release. These include more hooks designed for hypertext + handling. However, new man pages won't format under the old + man macros. Fortunately, old man pages will format under the + new mandoc macros. + + Get the new macros with the BSD Net2 or 4.4-Lite release (see + above for locations; for example, on FTP.UU.NET the files + /system/unix/bsd-sources/share/tmac/me/strip/sed and + /system/unix/bsd-sources/share/tmac/* are what you need). + + This macro set is also included with newer versions of groff. +---------------------------------------------------------------------- + * What modes should be used when installing sendmail? + + The sendmail binary should be owned by root, mode 4755. + The queue directory should be owned by root, with a mode + between 700 and 755. Under no circumstances should + it be group or other writable! + The sendmail config file should be owned by root, mode 644. + The aliases file should generally be owned by one trusted + user and writable only by that user, although it is + not unreasonable to have it group writable by a + "sysadmin" group. It should not be world writable. + The aliases database files (aliases.db or aliases.{pag,dir} + depending on what database format you compile with) + should be owned by root, mode 644. + +====================================================================== +CONFIGURATION QUESTIONS +====================================================================== + + * How do I make all my addresses appear to be from a single host? + + Using the V8 configuration macros, use: + + MASQUERADE_AS(my.dom.ain) + + This will cause all addresses to be sent out as being from + the indicated domain. +---------------------------------------------------------------------- + * How do I rewrite my From: lines to read ``First_Last@My.Domain''? + + There are a couple of ways of doing this. This describes + using the "user database" code. This is still experimental, + and was intended for a different purpose -- however, it does + work with a bit of care. It does require that you have the + Berkeley "db" package installed (it won't work with DBM). + + First, create your input file. This should have lines like: + + loginname:mailname First_Last + First_Last:maildrop loginname + + Install it in (say) /etc/userdb. Create the database: + + makemap btree /etc/userdb.db < /etc/userdb + + You can then create a config file that uses this. You will + have to include the following in your .mc file: + + define(confUSERDB_SPEC, /etc/userdb.db) + FEATURE(notsticky) +---------------------------------------------------------------------- + * So what was the user database feature intended for? + + The intent was to have all information for a given user + (where the user is the unique login name, not an inherently + non-unique full name) in one place. This would include phone + numbers, addresses, and so forth. The "maildrop" feature is + because Berkeley does not use a centralized mail server + (there are a number of reasons for this that are mostly + historic), and so we need to know where each user gets his or + her mail delivered -- i.e., the mail drop. + + We are in the process of setting up our environment so that + mail sent to an unqualified "name" goes to that person's + preferred maildrop; mail sent to "name@host" goes to that + host. The purpose of "FEATURE(notsticky)" is to cause + "name@host" to be looked up in the user database for delivery + to the maildrop. +---------------------------------------------------------------------- + * Why are you so hostile to using full names for e-mail addresses? + + Because full names are not unique. For example, the computer + community has two Andy Tannenbaums and two Peter Deutsches. + At one time, Bell Labs had two Stephen R. Bournes with + offices a few doors apart. You can create alternative + addresses (e.g., Stephen_R_Bourne_2), but that's even worse + -- which one of them has to have their name desecrated in + this way? And you can bet that one of them will get most of + the other person's e-mail. + + So called "full names" are just an attempt to create longer + versions of unique names. Rather that lulling people into a + sense of security, I'd rather that it be clear that these + handles are arbitrary. People should use good user agents + that have alias mappings so that they can attach arbitrary + names for their personal use to those with whom they + correspond (such as the MH alias file). + + Even worse is fuzzy matching in e-mail -- this can make good + addresses turn bad. For example, Eric Allman is currently + (to the best of our knowledge) the only ``Allman'' at + Berkeley, so mail sent to "Allman@Berkeley.EDU" should get to + him. But if another Allman ever appears, this address could + suddenly become ambiguous. He's been the only Allman at + Berkeley for over fifteen years -- to suddenly have this + "good address" bounce mail because it is ambiguous would be a + heinous wrong. + + Finger services should be as fuzzy as possible (within + reason, of course). Mail services should be unique. +---------------------------------------------------------------------- + * Should I use a wildcard MX for my domain? + + If at all possible, no. + + Wildcard MX records have lots of semantic "gotcha"s. For + example, they will match a host "unknown.your.domain" -- if + you don't explicitly test for unknown hosts in your domain, + you will get "config error: mail loops back to myself" + errors. + + See RFCs 1535-1537 for more detail and other related (or + common) problems. +---------------------------------------------------------------------- + * How can I get sendmail to process messages sent to an account and + send the results back to the originator? + + This is a local mailer issue, not a sendmail issue. + Depending on what you're doing, look at procmail (mentioned + again below), ftpmail, or Majordomo. + + Check your local archie server to see what machine(s) nearest + you have the most recent versions of these programs. +---------------------------------------------------------------------- + * How can I get sendmail to deliver local mail to $HOME/.mail + instead of into /usr/spool/mail (or /usr/mail)? + + Again, this is a local mailer issue, not a sendmail issue. + Either modify your local mailer (source code will be + required) or change the program called in the "local" mailer + configuration description to be a new program that does this + local delivery. One program that is capable of doing this is + "procmail", although there are probably many others as well. + + You might be interested in reading the paper ``HLFSD: + Delivering Email to your $HOME'' available in the Proceedings + of the USENIX System Administration (LISA VII) Conference + (November 1993). This is also available via public FTP from + ftp.cs.columbia.edu in /pub/hlfsd/{README.hlfsd,hlfsd.ps}. +---------------------------------------------------------------------- + * I'm trying to to get my mail to go into queue only mode, and it + delivers the mail interactively anyway. (Or, I'm trying to use + the "don't deliver to expensive mailer" flag, and it delivers the + mail interactively anyway.) I can see it does it: here's the + output of "sendmail -v foo@somehost" (or Mail -v or equivalent). + + The -v flag to sendmail (which is implied by the -v flag to + Mail and other programs in that family) tells sendmail to + watch the transaction. Since you have explicitly asked to + see what's going on, it assumes that you do not want to to + auto-queue, and turns that feature off. Remove the -v flag + and use a "tail -f" of the log instead to see what's going + on. + + If you are trying to use the "don't deliver to expensive + mailer" flag (mailer flag "e"), be sure you also turn on + global option "c" -- otherwise it ignores the mailer flag. +---------------------------------------------------------------------- + * There are four UUCP mailers listed in the configuration files. + Which one should I use? + + The choice is partly a matter of local preferences and what + is running at the other end of your UUCP connection. Unlike + good protocols that define what will go over the wire, UUCP + uses the policy that you should do what is right for the + other end; if they change, you have to change. This makes it + hard to do the right thing, and discourages people from + updating their software. In general, if you can avoid UUCP, + please do. + + If you can't avoid it, you'll have to find the version that + is closest to what the other end accepts. Following is a + summary of the UUCP mailers available. + + uucp-old (obsolete name: "uucp") + This is the oldest, the worst (but the closest to UUCP) way + of sending messages across UUCP connections. It does + bangify everything and prepends $U (your UUCP name) to the + sender's address (which can already be a bang path + itself). It can only send to one address at a time, so it + spends a lot of time copying duplicates of messages. Avoid + this if at all possible. + + uucp-new (obsolete name: "suucp") + The same as above, except that it assumes that in one rmail + command you can specify several recipients. It still has a + lot of other problems. + + uucp-dom + This UUCP mailer keeps everything as domain addresses. + Basically, it uses the SMTP mailer rewriting rules. + + Unfortunately, a lot of UUCP mailer transport agents + require bangified addresses in the envelope, although you + can use domain-based addresses in the message header. (The + envelope shows up as the From_ line on UNIX mail.) So.... + + uucp-uudom + This is a cross between uucp-new (for the envelope + addresses) and uucp-dom (for the header addresses). It + bangifies the envelope sender (From_ line in messages) + without adding the local hostname, unless there is no host + name on the address at all (e.g., "wolf") or the host + component is a UUCP host name instead of a domain name + ("somehost!wolf" instead of "some.dom.ain!wolf"). + + Examples: + + We are on host grasp.insa-lyon.fr (UUCP host name "grasp"). + The following summarizes the sender rewriting for various + mailers. + + Mailer sender rewriting in the envelope + ------ ------ ------------------------- + uucp-{old,new} wolf grasp!wolf + uucp-dom wolf wolf@grasp.insa-lyon.fr + uucp-uudom wolf grasp.insa-lyon.fr!wolf + + uucp-{old,new} wolf@fr.net grasp!fr.net!wolf + uucp-dom wolf@fr.net wolf@fr.net + uucp-uudom wolf@fr.net fr.net!wolf + + uucp-{old,new} somehost!wolf grasp!somehost!wolf + uucp-dom somehost!wolf somehost!wolf@grasp.insa-lyon.fr + uucp-uudom somehost!wolf grasp.insa-lyon.fr!somehost!wolf + +====================================================================== +RESOLVING PROBLEMS +====================================================================== + + * When I compile, I get "undefined symbol inet_aton" messages. + + You've probably replaced your resolver with the version from + BIND 4.9.3. You need to compile with -l44bsd in order to get + the additional routines. +---------------------------------------------------------------------- + * I'm getting "Local configuration error" messages, such as: + + 553 relay.domain.net config error: mail loops back to myself + 554 <user@domain.net>... Local configuration error + + How can I solve this problem? + + You have asked mail to the domain (e.g., domain.net) to be + forwarded to a specific host (in this case, relay.domain.net) + by using an MX record, but the relay machine doesn't + recognize itself as domain.net. Add domain.net to + /etc/sendmail.cw (if you are using FEATURE(use_cw_file)) or + add "Cw domain.net" to your configuration file. + + IMPORTANT: Be sure you kill and restart the sendmail daemon + after you change the configuration file (for ANY change in + the configuration, not just this one): + + kill `head -1 /etc/sendmail.pid` + sh -c "`tail -1 /etc/sendmail.pid`" + + NOTA BENE: kill -1 does not work! +---------------------------------------------------------------------- + * When I use sendmail V8 with a Sun config file I get lines like: + + /etc/sendmail.cf: line 273: replacement $3 out of bounds + + the line in question reads: + + R$*<@$%y>$* $1<@$2.LOCAL>$3 user@ether + + what does this mean? How do I fix it? + + V8 doesn't recognize the Sun "$%y" syntax, so as far as it is + concerned, there is only a $1 and a $2 (but no $3) in this + line. Read Rick McCarty's paper on "Converting Standard Sun + Config Files to Sendmail Version 8", in the contrib directory + (file "converting.sun.configs") on the sendmail distribution + for a full discussion of how to do this. +---------------------------------------------------------------------- + * When I use sendmail V8 on a Sun, I sometimes get lines like: + + /etc/sendmail.cf: line 445: bad ruleset 96 (50 max) + + what does this mean? How do I fix it? + + You're somehow trying to start up the old Sun sendmail (or + sendmail.mx) with a sendmail V8 config file, which Sun's + sendmail doesn't like. Check your /etc/rc.local, any + procedures that have been created to stop and re-start the + sendmail processes, etc.... Make sure that you've switched + everything over to using the new sendmail. To keep this + problem from ever happening again, try the following: + + mv /usr/lib/sendmail /usr/lib/sendmail.old + ln -s /usr/local/lib/sendmail.v8 /usr/lib/sendmail + mv /usr/lib/sendmail.mx /usr/lib/sendmail.mx.old + ln -s /usr/local/lib/sendmail.v8 /usr/lib/sendmail.mx + chmod 0000 /usr/lib/sendmail.old + chmod 0000 /usr/lib/sendmail.mx.old + + Assuming you have installed sendmail V8 in /usr/local/lib. +---------------------------------------------------------------------- + * When I use sendmail V8 on an IBM RS/6000 running AIX, the system + resource controller always reports sendmail as "inoperative" even + though it is running. What's wrong? + + IBM's system resource controller is one of their "value + added" features to AIX -- it's not a Unix standard. You'll + need to either redefine the subsystem to use signals (see + chssys(1)) or dump the entire subsystem and invoke sendmail + in /etc/rc.tcpip or some other boot script. +---------------------------------------------------------------------- + * When I use sendmail V8 on an Intel x86 machine running Linux, I + have some problems. Specifically, I have.... + + The current versions of Linux are generally considered to be + great for hobbyists and anyone else who wants to learn Unix + inside and out, or wants to always have something to do, or + wants a machine for light-duty mostly personal use and not + high-volume multi-user purposes. + + However, for those who want a system that will just sit in + the background and work without a fuss handling thousands of + mail messages a day for lots of different users, it's not + (yet) stable enough to fit the bill. + + Unfortunately, there are no known shareware/freeware + implementations of any operating system that provides the + level of stability necessary to handle that kind of load + (i.e., there are no free lunches). + + If you're wedded to the Intel x86 platform and want to run + sendmail, we suggest you look at commercial implementations + of Unix such as Interactive, UnixWare, Solaris, or BSD/386 + (just a sample of the dozens of different versions of Unix + for Intel x86). + + Of all known vendor supported versions of Unix for Intel x86, + BSDI's BSD/386 is least expensive and the only one known to + currently ship with sendmail V8 pre-installed. Since sendmail + V8 is continuing to be developed at UC Berkeley, and BSD/386 + is a full BSD 4.4 implementation, this is obviously be the most + "native" sendmail V8 environment. +---------------------------------------------------------------------- + * When I use sendmail on an Intel x86 machine running OS/2, I have + some problems. Specifically, I have.... + + The OS/2 port of sendmail is known to have left out huge + chunks of the code and functionality of even much older + versions of sendmail, in large part because the underlying OS + just doesn't have the necessary hooks to make it happen. + This port is so broken that we make no attempt to provide any + kind of support for it. Try BSDI's BSD/386 instead. +---------------------------------------------------------------------- + * I'm connected to the network via a SLIP/PPP link. Sometimes my + sendmail process hangs (although it looks like part of the + message has been transfered). Everything else works. What's + wrong? + + Most likely, the problem isn't sendmail at all, but the low + level network connection. It's important that the MTU + (Maximum Transfer Unit) for the SLIP connection be set + properly at both ends. If they disagree, large packets will + be trashed and the connection will hang. +---------------------------------------------------------------------- + * I just upgraded to 8.x and suddenly I'm getting messages in my + syslog of the form "collect: I/O error on connection". What is + going wrong? + + Nothing. This is just a diagnosis of a condition that had + not been diagnosed before. If you are getting a lot of these + from a single host, there is probably some incompatibility + between 8.x and that host. If you get a lot of them in + general, you may have network problems that are causing + connections to get reset. +---------------------------------------------------------------------- + * I just upgraded to 8.x and now when my users try to forward their + mail to a program they get an "illegal shell" message and their + mail is not delivered. What's wrong? + + In order for people to be able to run a program from their + .forward file, 8.x insists that their shell (that is, the + shell listed for that user in the passwd entry) be a "valid" + shell, meaning a shell listed in /etc/shells. If /etc/shells + does not exist, a default list is used, typically consisting + of /bin/sh and /bin/csh. + + This is to support environments that may have NFS-shared + directories mounted on machines on which users do not have + login permission. For example, many people make their + file server inaccessible for performance or security + reasons; although users have directories, their shell on + the server is /usr/local/etc/nologin or some such. If you + allowed them to run programs anyway you might as well let + them log in. + + If you are willing to let users run programs from their + .forward file even though they cannot telnet or rsh in (as + might be reasonable if you run smrsh to control the list of + programs they can run) then add the line + + /SENDMAIL/ANY/SHELL/ + + to /etc/shells. This must be typed exactly as indicated, + in caps, with the trailing slash. NOTA BENE: DO NOT + list /usr/local/etc/nologin in /etc/shells -- this will + open up other security problems. +---------------------------------------------------------------------- + * I just upgraded to 8.x and suddenly connections to the SMTP port + take a long time. What is going wrong? + + It's probably something weird in your TCP implementation that + makes the IDENT code act oddly. On most systems V8 tries to + do a ``callback'' to the connecting host to get a validated + user name (see RFC 1413 for detail). If the connecting host + does not support such a service it will normally fail quickly + with "Connection refused", but certain kinds of packet + filters and certain TCP implementations just time out. + + To test this, set the IDENT timeout to zero using + ``OrIdent=0'' in the configuration file. This will + completely disable all use of the IDENT protocol. + + Another possible problem is that you have your name server + and/or resolver configured improperly. Make sure that all + "nameserver" entries in /etc/resolv.conf point to functional + servers. If you are running your own server make certain + that all the servers listed in your root cache (usually + called something like "/var/namedb/root.cache"; see your + /etc/named.boot file to get your value) are up to date. + Either of these can cause long delays. +---------------------------------------------------------------------- + * I just upgraded to 8.x and suddenly I get errors such as ``unknown + mailer error 5 -- mail: options MUST PRECEDE recipients.'' What is + going wrong? + + You need OSTYPE(systype) in your .mc file -- otherwise the + configurations use a default that probably disagrees with + your local mail system. See cf/README for details. +---------------------------------------------------------------------- + * Under V8, the "From " header gets mysteriously munged when I send + to an alias. + + ``It's not a bug, it's a feature.'' This happens when you + have a "owner-list" alias and you send to "list". V8 + propagates the owner information into the envelope sender + field (which appears as the "From " header on UNIX mail or as + the Return-Path: header) so that downstream errors are + properly returned to the mailing list owner instead of to the + sender. In order to make this appear as sensible as possible + to end users, I recommend making the owner point to a + "request" address -- for example: + + list: :include:/path/name/list.list + owner-list: list-request + list-request: eric + + This will make message sent to "list" come out as being "From + list-request" instead of "From eric". +---------------------------------------------------------------------- + * I am trying to use MASQUERADE_AS (or the user database) to + rewrite from addresses, and although it works in the From: header + line, it doesn't work in the envelope (e.g., the "From " line). + + Believe it or not, this is intentional. The interpretation + of the standards by the V8 development group was that this + was an inappropriate rewriting, and that if the rewriting + were incorrect at least the envelope would contain a valid + return address. Other people have since described scenarios + where the envelope cannot be correct without this rewriting, + so 8.7 will have an option to rewrite both header and + envelope. +---------------------------------------------------------------------- + * I want to run Sendmail version 8 on my DEC system, but you don't + have MAIL11V3 support in sendmail. How do I handle this? + + Get Paul Vixie's reimplementation of the mail11 protocol from + gatekeeper.dec.com in /pub/DEC/gwtools. + + Rumour has it that he will be fully integrating into sendmail + V8 what little is left of IDA sendmail that is not handled + (or handled as well) by V8. No additional information on + this project is currently available. +---------------------------------------------------------------------- + * Messages seem to disappear from my queue unsent. When I look in + the queue directory I see that they have been renamed from qf* to + Qf*, and sendmail doesn't see these. + + If you look closely you should find that the Qf files are + owned by users other than root. Since sendmail runs as root + it refuses to believe information in non-root-owned qf files, + and it renames them to Qf to get them out of the way and make + it easy for you to find. The usual cause of this is + twofold: first, you have the queue directory world writable + (which is probably a mistake -- this opens up other security + problems) and someone is calling sendmail with an "unsafe" + flag, usually a -o flag that sets an option that could + compromise security. When sendmail sees this it gives up + setuid root permissions. + + The usual solution is to not use the problematic flags. If + you must use them, you have to write a special queue + directory and have them processed by the same uid that + submitted the job in the first place. +---------------------------------------------------------------------- +@(#)FAQ 8.16 (Berkeley) 9/17/95 +Send updates to sendmail@sendmail.ORG. diff --git a/usr.sbin/sendmail/KNOWNBUGS b/usr.sbin/sendmail/KNOWNBUGS new file mode 100644 index 000000000000..f9020e7fb75e --- /dev/null +++ b/usr.sbin/sendmail/KNOWNBUGS @@ -0,0 +1,119 @@ + + + K N O W N B U G S I N S E N D M A I L + (for 8.7) + + +The following are bugs or deficiencies in sendmail that I am aware of +but which have not been fixed in the current release. You probably +want to get the most up to date version of this from FTP.CS.Berkeley.EDU +in /ucb/sendmail/KNOWNBUGS. For descriptions of bugs that have been +fixed, see the file RELEASE_NOTES (in the root directory of the sendmail +distribution). + +This list is not guaranteed to be complete. + + +* Null bytes are not handled properly in headers. + + Sendmail should handle full binary data. As it stands, it handles + all values in the body, but only 0x01-0x80 and 0xA0-0xFF in + the header. Notably missing is 0x00, which would require a major + restructuring of the code -- for example, almost no C library support + could be used to handle strings. + +* Duplicate error messages. + + Sometimes identical, duplicate error messages can be generated. As + near as I can tell, this is rare and relatively innocuous. + +* $c (hop count) macro improperly set. + + The $c macro is supposed to contain the current hop count, for use + when calling a mailer. This macro is initialized too early, and + is always zero (or the value of the -c command line flag, if any). + This macro will probably be removed entirely in a future release; + I don't believe there are any mailers left that require it. + +* If you EXPN a list or user that has a program mailer, the output of + EXPN will include ``@local.host.name''. You can't actually mail to + this address. It's not clear what the right behaviour is in this + circumstance. + +* MX records that point at non-existent hosts work strangly. + + Consider the DNS records: + + hostH MX 1 hostA + MX 2 hostB + hostA A 128.32.8.9 + + (note that there is no A record for hostB). If hostA is down, + an attempt to send to hostH gives "host unknown" -- that is, it + reflects out the status on the last host it tries, which in this + case is hostB, which is unknown. It probably ought to eliminate + hostB early in processing. + +* \231 considered harmful. + + Header addresses that have the \231 character (and possibly others + in the range \201 - \237) behave in odd and usually unexpected ways. + +* accept() problem on SVR4. + + Apparently, the sendmail daemon loop (doing accept()s on the network) + can get into a wierd state on SVR4; it starts logging ``SYSERR: + getrequests: accept: Protocol Error''. The workaround is to kill + and restart the sendmail daemon. We don't have an SVR4 system at + Berkeley that carries more than token mail load, so I can't validate + this. It is likely to be a glitch in the sockets emulation, since + "Protocol Error" is not possible error code with Berkeley TCP/IP. + + I've also had someone report the message ``sendmail: accept: + SIOCGPGRP failed errno 22'' on an SVR4 system. This message is + not in the sendmail source code, so I assume it is also a bug + in the sockets emulation. (Errno 22 is EINVAL "Invalid Argument" + on all the systems I have available, including Solaris 2.x.) + +* Sending user deletion not done properly in :include: lists. + + If you don't have the "m" (me too) option set, then a person + sending to a list that contains themselves should not get a copy + of the message. However, if that list points to a :include: file + that has one address per line, this will break, and the sender + will always get a copy of their own message, just as though the + "m" option were set. + + You can eliminate this by adding commas at the end of each line + of the :include: file. + +* Excessive mailing list nesting can run out of file descriptors. + + If you have a mailing list that includes lots of other mailing + lists, each of which has a separate owner, you can run out of + file descriptors. Each mailing list with a separate owner uses + one open file descriptor (prior to 8.6.6 it was three open + file descriptors per list). This is particularly egregious if + you have your connection cache set to be large. + +* Connection caching breaks if you pass the port number as an argument. + + If you have a definition such as: + + Mport, P=[IPC], F=kmDFMuX, S=11/31, R=21, + M=2100000, T=DNS/RFC822/SMTP, + A=IPC [127.0.0.1] $h + + (i.e., where $h is the port number instead of the host name) the + connection caching code will break because it won't notice that + two messages addressed to different ports should use different + connections. + +* ESMTP SIZE underestimates the size of a message + + Sendmail makes no allowance for headers that it adds, nor does it + account for the SMTP on-the-wire \r\n expansion. It probably doesn't + allow for 8->7 bit MIME conversions either. + + +(Version 8.21, last updated 8/27/95) diff --git a/usr.sbin/sendmail/Makefile b/usr.sbin/sendmail/Makefile new file mode 100644 index 000000000000..2dc0b0fd7b50 --- /dev/null +++ b/usr.sbin/sendmail/Makefile @@ -0,0 +1,45 @@ +# @(#)Makefile 8.12 (Berkeley) 5/29/95 + +VER= XX +SUBDIR= src mailstats makemap praliases cf/cf +FTPDIR= mastodon:/disks/barad-dur/ftp/sendmail/. +DISTFILES=sendmail.${VER}.tar.Z sendmail.${VER}.tar.gz \ + RELEASE_NOTES FAQ KNOWNBUGS +FILES= Files.base Files.cf Files.misc Files.xdoc + +tar: sccs-check compile-world run-pax + +sccs-check: + sccs check + (cd src; sccs check) + (cd doc/op; sccs check) + (cd doc/intro; sccs check) + (cd doc/usenix; sccs check) + (cd cf; sccs check) + (cd cf/m4; sccs check) + (cd cf/mailer; sccs check) + (cd cf/feature; sccs check) + (cd cf/cf; sccs check) + (cd cf/ostype; sccs check) + (cd cf/domain; sccs check) + +compile-world: + (cd src; ${MAKE}) + (cd doc; PRINTER=ps ${MAKE}) + (cd doc; chmod 444 op/op.ps intro/intro.ps usenix/usenix.ps) + (cd cf/cf; ${MAKE}) + +run-pax: Files.base Files.cf Files.misc Files.xdoc + chmod +x src/makesendmail + pax -w -x tar -L \ + -s ",cf/domain/unspecified-domain,sendmail-${VER}/cf/domain/berkeley-only,p" \ + -s ",^,sendmail-${VER}/," \ + -f sendmail.${VER}.tar \ + `cat ${FILES} | grep -v ^#` + gzip -c sendmail.${VER}.tar > sendmail.${VER}.tar.gz + compress sendmail.${VER}.tar + +ftp: sendmail.${VER}.tar.Z + rcp ${DISTFILES} ${FTPDIR} + +.include <bsd.subdir.mk> diff --git a/usr.sbin/sendmail/READ_ME b/usr.sbin/sendmail/READ_ME new file mode 100644 index 000000000000..2e50d085ecad --- /dev/null +++ b/usr.sbin/sendmail/READ_ME @@ -0,0 +1,288 @@ +/*- + * @(#)READ_ME 8.25 (Berkeley) 11/19/95 + */ + + SENDMAIL RELEASE 8 + +This directory has the latest sendmail software from Berkeley. See +doc/changes/changes.me for a summary of changes since 5.67. + +Report any bugs to sendmail-bugs@sendmail.ORG + +****************************************************************** +** DO NOT USE MAKE to compile sendmail. Instead, cd src and ** +** use the "makesendmail" shell script. On many environments ** +** this will do everything for you, no fuss, no muss. See ** +** src/READ_ME for more details of compilation. See cf/README ** +** for details about building a runtime configuration file. ** +****************************************************************** + + ++--------------+ +| MANUAL PAGES | ++--------------+ + +The sendmail manual pages use contemporary Berkeley troff macros. If +your system does not process these manual pages, you can pick up the +new macros in a BSD Net/2 FTP site (e.g. on FTP.UU.NET, the files +/systems/unix/bsd-sources/share/tmac/me/strip.sed and +/systems/unix/bsd-sources/share/tmac/*). + +The strip.sed file is only used in installation. + +After installation, edit tmac.doc and tmac.andoc to reflect the +installation path of the tmac files. Those files contain pointers to +/usr/share/tmac/, and those pointers are not changed by the `make +install` process. There's also a bug in those files -- make the +following patch: + +*** tmac.an~ Tue Jul 12 14:29:09 1994 +--- tmac.an Fri Jul 15 13:17:54 1994 +*************** +*** 50,55 **** + .de TH + .rn TH xX + .so /usr/share/lib/tmac/tmac.an.old +! .TH \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 + .rm xX + .. +--- 50,55 ---- + .de TH + .rn TH xX + .so /usr/share/lib/tmac/tmac.an.old +! .TH "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" + .rm xX + .. + +Rename the existing tmac.an to be tmac.an.old, and rename tmac.andoc +to be tmac.an. + +tmac.an will choose between tmac.an.old, your old macros, or tmac.doc, +which are the new macros, so that both the new man pages and the +existing man pages will be translated properly. + +I'm also told that the groff distribution from MIT has a tmac.doc +macro set that is compatible with these macros. + + ++-----------------------+ +| RELATED DOCUMENTATION | ++-----------------------+ + +There are other files you should read. Rooted in this directory are: + + CHANGES-R5-R8 + Describes changes between Release 5 and Release 8 of sendmail. + There are some things that may behave somewhat differently. + For example, the rules governing when :include: files will + be read have been tightened up for security reasons. + FAQ + Answers to Frequently Asked Questions. + KNOWNBUGS + Known bugs in the current release. I try to keep this up + to date -- get the latest version from FTP.CS.Berkeley.EDU + in /ucb/sendmail/KNOWNBUGS. + RELEASE_NOTES + A detailed description of the changes in each version. This + is quite long, but informative. + src/READ_ME + Details on compiling and installing sendmail. + cf/README + Details on configuring sendmail. + doc/op/op.me + The sendmail Installation & Operations Guide. Be warned: if + you are running this off on SunOS or some other system with an + old version of -me, you need to add the following macro to the + macros: + + .de sm + \s-1\\$1\\s0\\$2 + .. + + This sets a word in a smaller pointsize. + + ++--------------+ +| RELATED RFCS | ++--------------+ + +There are several related RFCs that you may wish to read -- they are +available via anonymous FTP to several sites, including nic.ddn.mil +(directory rfc), ftp.nisc.sri.com (rfc), nis.nsf.net (RFC), +nisc.jvnc.net (rfc), venera.isi.edu (in-notes), and wuarchive.wustl.edu +(info/rfc). They can also be retrieved via electronic mail by sending +email to one of: + + mail-server@nisc.sri.com + Put "send rfcNNN" in message body + nis-info@nis.nsf.net + Put "send RFCnnn.TXT-1" in message body + sendrfc@jvnc.net + Put "RFCnnn" as Subject: line + +Important RFCs for electronic mail are: + + RFC821 SMTP protocol + RFC822 Mail header format + RFC974 MX routing + RFC976 UUCP mail format + RFC1123 Host requirements (modifies 821, 822, and 974) + RFC1413 Identification server + RFC1425 SMTP Service Extensions (ESMTP spec) + RFC1426 SMTP Service Extension for 8bit-MIMEtransport + RFC1427 SMTP Service Extension for Message Size Declaration + RFC1521 MIME: Multipurpose Internet Mail Extensions + RFC1344 Implications of MIME for Internet Mail Gateways + RFC1428 Transition of Internet Mail from Just-Send-8 to + 8-bit SMTP/MIME + +Other standards that may be of interest (but which are less directly +relevant to sendmail) are: + + RFC987 Mapping between RFC822 and X.400 + RFC1049 Content-Type header field (extension to RFC822) + +Warning to AIX users: this version of sendmail does not implement +MB, MR, or MG DNS resource records, as defined (as experiments) in +RFC1035. + + ++-------------------+ +| DATABASE ROUTINES | ++-------------------+ + +IF YOU WANT TO RUN THE NEW BERKELEY DB SOFTWARE: **** DO NOT **** +use the version that was on the Net2 tape -- it has a number of +nefarious bugs that were bad enough when I got them; you shouldn't have +to go through the same thing. Instead, get a new version via public +FTP from ftp.CS.Berkeley.EDU, file ucb/4bsd/db.tar.Z. This software +is highly recommended; it gets rid of several stupid limits, it's much +faster, and the interface is nicer to animals and plants. You will +also probably find that you have to add -I/where/you/put/db/include +to the sendmail makefile to get db.h to work properly. + +Be sure you remove ndbm.h and ndbm.o from the db distribution. These +will cause problems with sendmail because sendmail already understands +about NEWDB and NDBM coexisting. + + ++--------------------+ +| HOST NAME SERVICES | ++--------------------+ + +If you are using NIS or /etc/hosts, it is critical that you +list the long (fully qualified) name somewhere (preferably first) in +the /etc/hosts file used to build the NIS database. For example, the +line should read + + 128.32.149.68 mastodon.CS.Berkeley.EDU mastodon + +**** NOT **** + + 128.32.149.68 mastodon + +If you do not include the long name, sendmail will complain loudly +about ``unable to qualify my own domain name (mastodon) -- using +short name'' and conclude that your canonical name is the short +version and use that in messages. The name "mastodon" doesn't mean +much outside of Berkeley, and so this creates incorrect and unreplyable +messages. + + ++-------------+ +| USE WITH MH | ++-------------+ + +This version of sendmail notices and reports certain kinds of SMTP +protocol violations that were ignored by older versions. If you +are running MH you may wish to install the patch in contrib/mh.patch +that will prevent these warning reports. This patch also works +with the old version of sendmail, so it's safe to go ahead and +install it. + + ++----------------+ +| USE WITH IDENT | ++----------------+ + +Sendmail 8 supports the IDENT protocol, as defined by RFC 1413. +No ident server is included with this distribution. I have found +copies available on: + + ftp.lysator.liu.se /pub/ident/servers + romulus.ucs.uoknor.edu /networking/ident/servers + ftp.cyf-kr.edu.pl /agh/uciagh/network/ident + +If you want to run an IDENT server, I suggest getting a copy from +one of those sites. Versions are available for several different +systems, including Apollo, BSD, NeXT, AIX, TOPS20, and VMS. + + ++-----------+ +| MAKEFILES | ++-----------+ + +The Makefiles in this release use the new Berkeley "make" that is +available in BSD Net/2 and 4.4BSD. If you are using this version +of make, you may notice one or two places where the Makefile includes +"../../Makefile.inc". This file is not included with the sendmail +distribution because it's not part of sendmail. However, it is, +in toto: + + # @(#)Makefile.inc 8.1 (Berkeley) 6/6/93 + + BINDIR?= /usr/sbin + +The other directories should all have Makefile.dist files that work +on the old make, albeit without all the niceties included. + +You can also get a new Berkeley make from the Net2 release (available +on many public FTP archives). This version should also interpret old +Makefiles, so you could drop it in as your default make. + +For more details, see src/READ_ME. + + ++---------------------+ +| DIRECTORY STRUCTURE | ++---------------------+ + +The structure of this directory tree is: + +cf Source for Berkeley configuration files. These are + different than what you've seen before. They are a + fairly dramatic rewrite, requiring the new sendmail + (since they use new features). +contrib Some contributed tools to help with sendmail. THESE + ARE NOT SUPPORTED by Berkeley -- contact the original + authors if you have problems. (This directory is not + on the 4.4BSD tape.) +doc Documentation. If you are getting source, read + op.me -- it's long, but worth it. +mail.local The source for the local delivery agent used for 4.4BSD. + THIS IS NOT PART OF SENDMAIL! and may not compile + everywhere, since it depends on some 4.4-isms. Warning: + it does mailbox locking differently than other systems. +mailstats Statistics printing program. It has the pathname of + sendmail.st compiled in, so if you've changed that, + beware. This isn't all that useful. +makemap A program that creates the keyed maps used by the $( ... $) + construct in sendmail. It is primitive but effective. + It takes a very simple input format, so you will probably + expect to preprocess must human-convenient formats + using sed scripts before this program will like them. + But it should be functionally complete. +praliases A program to print the DBM or NEWDB version of the + aliases file. +rmail Source for rmail(8). This is used as a delivery + agent for for UUCP, and could presumably be used by + other non-socket oriented mailers. Older versions of + rmail are probably deficient. RMAIL IS NOT PART OF + SENDMAIL!!! The 4.4BSD source is included for you to + look at or try to port to your system. I know it doesn't + compile on {SunOS, HP-UX, OSF/1, other} (pick one). +smrsh The "sendmail restricted shell", which can be used as + a replacement for /bin/sh in the prog mailer to provide + increased security control. NOT PART OF SENDMAIL! +src Source for the sendmail program itself. +test Some test scripts (currently only for compilation aids). diff --git a/usr.sbin/sendmail/RELEASE_NOTES b/usr.sbin/sendmail/RELEASE_NOTES new file mode 100644 index 000000000000..42931dad88d3 --- /dev/null +++ b/usr.sbin/sendmail/RELEASE_NOTES @@ -0,0 +1,4003 @@ + SENDMAIL RELEASE NOTES + @(#)RELEASE_NOTES 8.7.2.1 (Berkeley) 11/19/95 + + +This listing shows the version of the sendmail binary, the version +of the sendmail configuration files, the date of release, and a +summary of the changes in that release. + +8.7.2/8.7.2 95/11/19 + REALLY fix the backslash escapes in SmtpGreetingMessage, + OperatorChars, and UnixFromLine options. They were not + properly repaired in 8.7.1. + Completely delete the Bcc: header if and only if there are other + valid recipient headers (To:, Cc: or Apparently-To:, the + last being a historic botch, of course). If Bcc: is the + only recipient header in the message, it's value is tossed, + but the header name is kept. The old behaviour (always keep + the header name and toss the value) allowed primary recipients + to see that a Bcc: went to _someone_. + Include queue id on ``Authentication-Warning: <host>: <user> set + sender to <addresss> using -f'' syslog messages. Suggested + by Kari Hurtta. + If a sequence or switch map lookup entry gets a tempfail but then + continues on to another map type, but the name is not found, + return a temporary failure from the sequence or switch map. + For example, if hosts search ``dns files'' and DNS fails + with a tempfail, the hosts map will go on and search files, + but if it fails the whole thing should be a tempfail, not + a permanent (host unknown) failure, even though that is the + failure in the hosts.files map. This error caused hard + bounces when it should have requeued. + Aliases to files such as /users/bar/foo/inbox, with /users/bar/foo + owned by bar mode 700 and inbox being setuid bar stopped + working properly due to excessive paranoia. Pointed out by + John Hawkinson of Panix. + An SMTP RCPT command referencing a host that gave a nameserver + timeout would return a 451 command (8.6 accepted it and + queued it locally). Revert to the 8.6 behaviour in order + to simplify queue management for clustered systems. Suggested + by Gregory Neil Shapiro of WPI. The same problem could break + MH, which assumes that the SMTP session will succeed (tsk, tsk + -- mail gets lost!); this was pointe dout by Stuart Pook of + Infobiogen. + Fix possible buffer overflow in munchstring(). This was not a security + problem because you couldn't specify any argument to this + without first giving up root privileges, but it is still a + good idea to avoid future problems. Problem noted by John + Hawkinson and Sam Hartman of MIT. + ``452 Out of disk space for temp file'' messages weren't being + printed. Fix from David Perlin of Nanosoft. + Don't advertise the ESMTP DSN extension if the SendMIMEErrors option + is not set, since this is required to get the actual DSNs + created. Problem pointed out by John Gardiner Myers of CMU. + Log permission problems that cause .forward and :include: files to + be untrusted or ignored on log level 12 and higher. Suggestted + by Randy Martin of Clemson University. + Allow user ids in U= clauses of M lines to have hyphens and + underscores. + Fix overcounting of recipients -- only happened when sending to an + alias. Pointed out by Mark Andrews of SGI and Jack Woolley + of Systems and Computer Technology Corporation. + If a message is sent to an address that fails, the error message that + is returned could show some extraneous "success" information + included even if the user did not request success notification, + which was confusing. Pointed out by Allan Johannesen of WPI. + Config files that had no AliasFile definition were defaulting to + using /etc/aliases; this caused problems with nullclient + configurations. Change it back to the 8.6 semantics of + having no local alias file unless it is declared. Problem + noted by Charles Karney of Princeton University. + Fix compile problem if NOTUNIX is defined. Pointed out by Bryan + Costales of ICSI. + Map lookups of class "userdb" maps were always case sensitive; they + should be controlled by the -f flag like other maps. Pointed + out by Bjart Kvarme <bjart.kvarme@usit.uio.no>. + Fix problem that caused some addresses to be passed through ruleset 5 + even when they were tagged as "sticky" by prefixing the + address with an "@". Patch from Thomas Dwyer III of Michigan + Technological University. + When converting a message to Quoted-Printable, prevent any lines with + dots alone on a line by themselves. This is because of the + preponderence of broken mailers that still get this wrong. + Code contributed by Per Hedeland of Ericsson. + Fix F{macro}/file construct -- it previously did nothing. Pointed + out by Bjart Kvarme of USIT/UiO (Norway). + Announce whether a cached connection is SMTP or ESMTP (in -v mode). + Requested by Allan Johannesen. + Delete check for text format of alias files -- it should be legal + to have the database format of the alias files without the + text version. Problem pointed out by Joe Rhett of Navigist, + Inc. + If "Ot" was specified with no value, the TZ variable was not properly + imported from the environment. Pointed out by Frank Crawford + <frank@ansto.gov.au>. + Some architectures core dumped on "program" maps that didn't have + extra arguments. Patch from Booker C. Bense of Stanford + University. + Queue run processes would re-spawn daemons when given a SIGHUP; only + the parent should do this. Fix from Brian Coan of the + Association for Progressive Communications. + If MinQueueAge was set and a message was considered but not run + during a queue run and the Timeout.queuereturn interval was + reached, a "timed out" error message would be returned that + didn't include the failed address (and claimed to be a warning + even though it was fatal). The fix is to not return such + messages until they are actually tried, i.e., in the next + MinQueueAge interval. Problem noted by Rein Tollevik of + SINTEF RUNIT, Oslo. + Add HES_GETMAILHOST compile flag to support MIT Hesiod distributions + that have the hes_getmailhost() routine. DEC Hesiod + distributions do not have this routine. Based on a patch + from Betty Lee of Stanford University. + PORTABILITY FIXES: + Solaris: Change location of newaliases and mailq from + /usr/ucb to /usr/bin to match Sun settings. From + James B. Davis of TCI. + DomainOS: Makefile.DomainOS doesn't require -ldbm. From + Don Lewis of Silicon Systems. + HP-UX 10: rename Makefile.HP-UX.10 => Makefile.HP-UX.10.x + so that the makesendmail script will find it. Pointed + out by Richard Allen of the University of Iceland. + Also, use -Aa -D_HPUX_SOURCE instead of -Ae, which + isn't supported on all compilers. + UXPDS: compilation fixes from Diego R. Lopez. + CONFIG: FAX mailer wasn't setting .FAX as a pseudo-domain unless + you also had a FAX_RELAY. From Thomas.Tornblom@Hax.SE. + CONFIG: Minor glitch in S21 -- attachment of local domain name + didn't have trailing dot. From Jim Hickstein of Teradyne. + CONFIG: Fix best_mx_is_local feature to allow nested addresses such as + user%host@thishost. From Claude Scarpelli of Infobiogen + (France). + CONFIG: OSTYPE(hpux10) failed to define the location of the help file. + Pointed out by Hannu Martikka of Nokia Telecommunications. + CONFIG: Diagnose some inappropriate ordering in configuration files, + such as FEATURE(smrsh) listed after MAILER(local). Based on + a bug report submitted by Paul Hoffman of Proper Publishing. + CONFIG: Make OSTYPE files consistently not override settings that + have already been set. Previously it worked differently + for different files. + CONFIG: Change relay mailer to do masquerading like 8.6 did. My take + is that this is wrong, but the change was causing problems + for some people. From Per Hedeland of Ericsson. + CONTRIB: bitdomain.c patch from John Gardiner Myers <jgm+@CMU.EDU>; + portability changes for Posix environments (no functional + changes). + +8.7.1/8.7.1 95/10/01 + Old macros that have become options (SmtpGreetingMessage, + OperatorChars, and UnixFromLine) didn't allow backslash + escapes in the options, where they previously had. Bug + pointed out by John Hawkinson of MIT. + Fix strange case of an executable called by a program map that + returns a value but also a non-zero exit status; this + would give contradictory results in the higher level; in + particular, the default clause in the map lookup would be + ignored. Change to ignore the value if the program returns + non-zero exit status. From Tom Moore of AT&T GIS. + Shorten parameters passed to syslog() in some contexts to avoid a + bug in many vendors' implementations of that routine. Although + this isn't really a bug in sendmail per se, and my solution + has to assume that syslog() has at least a 1K buffer size + internally (I know some vendors have shortened this + dramatically -- they're on their own), sendmail is a popular + target. Also, limit the size of %s arguments in sprintf. + These both have possible security implications. Solutions + suggested by Casper Dik of Sun's Network Security Group + (Holland), Mark Seiden, and others. + Fix a problem that might cause a non-standard -B (body type) + parameter to be passed to the next server with undefined + results. This could have security implications. + If a filesystem was at > 100% utilization, the freediskspace() + routine incorrectly returned an error rather than zero. + Problem noted by G. Paul Ziemba of Alantec. + Change MX sort order so that local hostnames (those in $=w) always + sort first within a given preference. This forces the bestmx + map to always return the local host first, if it is included + in the list of highest priority MX records. From K. Robert + Elz. + Avoid some possible null pointer dereferences. Fixes from Randy + Martin <WOLF@CLEMSON.EDU> + When sendmail starts up on systems that have no fully qualified + domain name (FQDN) anywhere in the first matching host map + (e.g., /etc/hosts if the hosts service searches "files dns"), + sendmail would sleep to try to find a FQDN, which it really + really needs. This has been changed to fall through to the + next map type if it can't find a FQDN -- i.e., if the hosts + file doesn't have a FQDN, it will try dns even though the + short name was found in /etc/hosts. This is probably a crock, + but many people have hosts files without FQDNs. Remember: + domain names are your friends. + Log a high-priority message if you can't find your FQDN during startup. + Suggested by Simon Barnes of Schlumberger Limited. + When using Hesiod, initialize it early to improve error reporting. + Patch from Don Lewis of Silicon Systems, Inc. + Apparently at least some versions of Linux have a 90 !minute! TCP + connection timeout in the kernel. Add a new "connect" timeout + to limit this time. Defaults to zero (use whatever the + kernel provides). Based on code contributed by J.R. Oldroyd + of TerraNet. + Under some circumstances, a failed message would not be properly + removed from the queue, causing tons of bogus error messages. + (This fix eliminates the problematic EF_KEEPQUEUE flag.) + Problem noted by Allan E Johannesen and Gregory Neil Shapiro + of WPI. + PORTABILITY FIXES: + On IRIX 5.x, there was an inconsistency in the setting + of sendmail.st location. Change the Makefile to + install it in /var/sendmail.st to match the OSTYPE + file and SGI standards. From Andre + <andre@curry.zfe.siemens.de>. + Support for Fujitsu/ICL UXP/DS (For the DS/90 Series) + from Diego R. Lopez <drlopez@cica.es>. + Linux compilation patches from J.R. Oldroyd of TerraNet, Inc. + LUNA 2 Mach patches from Motonori Nakamura. + SunOS Makefile was including -ldbm, which is for the old + dbm library. The ndbm library is part of libc. + CONFIG: avoid bouncing ``user@host.'' (note trailing dot) with + ``local configuration error'' in nullclient configuration. + Patch from Gregory Neil Shapiro of WPI. + CONFIG: don't allow an alias file in nullclient configurations -- + since all addresses are relayed, they give errors during + rebuild. Suggested by Per Hedeland of Ericsson. + CONFIG: local mailer on Solaris 2 should always get a -f flag because + otherwise the F=S causes the From_ line to imply that root is + the sender. Problem pointed out by Claude Scarpelli of + Infobiogen (France). + NEW FILES: + cf/feature/use_ct_file.m4 (omitted from 8.7 by mistake) + src/Makefiles/Makefile.KSR (omitted from 8.7 by mistake) + src/Makefiles/Makefile.UXPDS + +8.7/8.7 95/09/16 + Fix a problem that could cause sendmail to run out of file + descriptors due to a trashed data structure after a + vfork. Fix from Brian Coan of the Institute for + Global Communications. + Change the VRFY response if you have disabled VRFY -- some + people seemed to think that it was too rude. + Avoid reference to uninitialized file descriptor if HASFLOCK + was not defined. This was used "safely" in the sense + that it only did a stat, but it would have set the + map modification time improperly. Problem pointed out + by Roy Mongiovi of Georgia Tech. + Clean up the Subject: line on warning messages and return + receipts so that they don't say "Returned mail:"; this + can be confusing. + Move ruleset entry/exit debugging from 21.2 to 21.1 -- this is + useful enough to make it worthwhile printing on "-d". + Avoid logging alias statistics every time you read the alias + file on systems with no database method compiled in. + If you have a name with a trailing dot, and you try looking it + up using gethostbyname without the dot (for /etc/hosts + compatibility), be sure to turn off RES_DEFNAMES and + RES_DNSRCH to avoid finding the wrong name accidently. + Problem noted by Charles Amos of the University of + Maryland. + Don't do timeouts in collect if you are not running SMTP. + There is nothing that says you can't have a long + running program piped into sendmail (possibly via + /bin/mail, which just execs sendmail). Problem reported + by Don "Truck" Lewis of Silicon Systems. + Try gethostbyname() even if the DNS lookup fails iff option I + is not set. This allows you to have hosts listed in + NIS or /etc/hosts that are not known to DNS. It's normally + a bad idea, but can be useful on firewall machines. This + should really be broken out on a separate flag, I suppose. + Avoid compile warnings against BIND 4.9.3, which uses function + prototypes. From Don Lewis of Silicon Systems. + Avoid possible incorrect diagnosis of DNS-related errors caused + by things like attempts to resolve uucp names using + $[ ... $] -- the fix is to clear h_errno at appropriate + times. From Kyle Jones of UUNET. + SECURITY: avoid denial-of-service attacks possible by destroying + the alias database file by setting resource limits low. + This involves adding two new compile-time options: + HASSETRLIMIT (indicating that setrlimit(2) support is + available) and HASULIMIT (indicating that ulimit(2) support + is available -- the Release 3 form is used). The former + is assumed on BSD-based systems, the latter on System + V-based systems. Attack noted by Phil Brandenberger of + Swarthmore University. + New syntaxes in test (-bt) mode: + ``.Dmvalue'' will define macro "m" to "value". + ``.Ccvalue'' will add "value" to class "c". + ``=Sruleset'' will dump the contents of the indicated + ruleset. + ``=M'' will display the known mailers. + ``-ddebug-spec'' is equivalent to the command-line + -d debug flag. + ``$m'' will print the value of macro $m. + ``$=c'' will print the contents of class $=c. + ``/mx host'' returns the MX records for ``host''. + ``/parse address'' will parse address, returning the value of + crackaddr (essentially, the comment information) + and the parsed address (the same as -bv). + ``/try mailer address'' will rewrite address into the form + it will have when presented to the indicated mailer. + ``/tryflags flags'' will set flags used by parsing. The + flags can be `H' for header or `E' for envelope, + and `S' for sender or `R' for recipient. These + can be combined, so `HR' sets flags for header + recipients. + ``/canon hostname'' will try to canonify hostname and + return the result. + ``/map mapname key'' will look up `key' in the indicated + `mapname' and return the result. + Somewhat better handling of UNIX-domain socket addresses -- it + should show the pathname rather than hex bytes. + Restore ``-ba'' mode -- this reads a file from stdin and parses + the header for envelope sender information and uses + CR-LF as message terminators. It was thought to be + obsolete (used only for Arpanet NCP protocols), but it + turns out that the UK ``Grey Book'' protocols require + that functionality. + Fix a fix in previous release -- if gethostname and gethostbyname + return a name without dots, and if an attempt to canonify + that name fails, wait one minute and try again. This can + result in an extra 60 second delay on startup if your system + hostname (as returned by hostname(1)) has no dot and no names + listed in /etc/hosts or your NIS map have a dot. + Check for proper domain name on HELO and EHLO commands per + RFC 1123 section 5.2.5. Problem noted by Thomas Dwyer III + of Michigan Technological University. + Relax chownsafe rules slightly -- old version said that if you + can't tell if _POSIX_CHOWN_RESTRICTED is set (that is, + if fpathconf returned EINVAL or ENOSYS), assume that + chown is not safe. The new version falls back to whether + you are on a BSD system or not. This is important for + SunOS, which apparently always returns one of those + error codes. This impacts whether you can mail to files + or not. + Syntax errors such as unbalanced parentheses in the configuration + file could be omitted if you had "Oem" prior to the + syntax error in the config file. Change to always print + the error message. It was especially wierd because it + would cause a "warning" message to be sent to the Postmaster + for every message sent (but with no transcript). Problem + noted by Gregory Paris of Motorola. + Rewrite collect and putbody to handle full 8-bit data, including + zero bytes. These changes are internally extensive, but + should have minimal impact on external function. + Allow full words for option names -- if the option letter is + (apparently) a space, then take the word following -- e.g., + O MatchGECOS=TRUE + The full list of old and new names is as follows: + 7 SevenBitInput + 8 EightBitMode + A AliasFile + a AliasWait + B BlankSub + b MinFreeBlocks/MaxMessageSize + C CheckpointInterval + c HoldExpensive + D AutoRebuildAliases + d DeliveryMode + E ErrorHeader + e ErrorMode + f SaveFromLine + F TempFileMode + G MatchGECOS + H HelpFile + h MaxHopCount + i IgnoreDots + I ResolverOptions + J ForwardPath + j SendMimeErrors + k ConnectionCacheSize + K ConnectionCacheTimeout + L LogLevel + l UseErrorsTo + m MeToo + n CheckAliases + O DaemonPortOptions + o OldStyleHeaders + P PostmasterCopy + p PrivacyOptions + Q QueueDirectory + q QueueFactor + R DontPruneRoutes + r, T Timeout + S StatusFile + s SuperSafe + t TimeZoneSpec + u DefaultUser + U UserDatabaseSpec + V FallbackMXhost + v Verbose + w TryNullMXList + x QueueLA + X RefuseLA + Y ForkEachJob + y RecipientFactor + z ClassFactor + Z RetryFactor + The old macros that passed information into sendmail have + been changed to options; those correspondences are: + $e SmtpGreetingMessage + $l UnixFromLine + $o OperatorChars + $q (deleted -- not necessary) + To avoid possible problems with an older sendmail, + configuration level 6 is accepted by this version of + sendmail; any config file using the new names should + specify "V6" in the configuration. + Change address parsing to properly note that a phrase before a + colon and a trailing semicolon are essentially the same + as text outside of angle brackets (i.e., sendmail should + treat them as comments). This is to handle the + ``group name: addr1, addr2, ..., addrN;'' syntax (it will + assume that ``group name:'' is a comment on the first + address and the ``;'' is a comment on the last address). + This requires config file support to get right. It does + understand that :: is NOT this syntax, and can be turned + off completely by setting the ColonOkInAddresses option. + Level 6 config files added with new mailer flags: + A Addresses are aliasable. + i Do udb rewriting on envelope as well as header + sender lines. Applies to the from address mailer + flags rather than the recipient mailer flags. + j Do udb rewriting on header recipient addresses. + Applies to the sender mailer flags rather than the + recipient mailer flags. + k Disable check for loops when doing HELO command. + o Always run as the mail recipient, even on local + delivery. + w Check for an /etc/passwd entry for this user. + 5 Pass addresses through ruleset 5. + : Check for :include: on this address. + | Check for |program on this address. + / Check for /file on this address. + @ Look up sender header addresses in the user + database. Applies to the mailer flags for the + mailer corresponding to the envelope sender + address, rather than to recipient mailer flags. + Pre-level 6 configuration files set A, w, 5, :, |, /, and @ + on the "local" mailer, the o flag on the "prog" and "*file*" + mailers, and the ColonOkInAddresses option. + Eight-to-seven bit MIME conversions. This borrows ideas from + John Beck of Hewlett-Packard, who generously contributed + their implementation to me, which I then didn't use (see + mime.c for an explanation of why). This adds the + EightBitMode option (a.k.a. `8') and an F=8 mailer flag + to control handling of 8-bit data. These have to cope with + two types of 8-bit data: unlabelled 8-bit data (that is, + 8-bit data that is entered without declaring it as 8-bit + MIME -- technically this is illegal according to the + specs) and labelled 8-bit data (that is, it was declared + as 8BITMIME in the ESMTP session or by using the + -B8BITMIME command line flag). If the F=8 mailer flag is + set then 8-bit data is sent to non-8BITMIME machines + instead of converting to 7 bit (essentially using + just-send-8 semantics). The values for EightBitMode are: + m convert unlabelled 8-bit input to 8BITMIME, and do + any necessary conversion of 8BITMIME to 7BIT + (essentially, the full MIME option). + p pass unlabelled 8-bit input, but convert labelled + 8BITMIME input to 7BIT as required (default). + s strict adherence: reject unlabelled 8-bit input, + convert 8BITMIME to 7BIT as required. The F=8 + flag is ignored. + Unlabelled 8-bit data is rejected in mode `s' regardless of + the setting of F=8. + Add new internal class 'n', which is the set of MIME Content-Types + which can not be 8 to 7 bit encoded because of other + considerations. Types "multipart/*" and "message/*" are + never directly encoded (although their components can be). + Add new internal class 's', which is the set of subtypes of the + MIME message/* content type that can be treated as though + they are an RFC822 message. It is predefined to have + "rfc822". Suggested By Kari Hurtta. + Add new internal class 'e'. This is the set of MIME + Content-Transfer-Encodings that can be converted to + a seven bit format (Quoted-Printable or Base64). It is + preinitialized to contain "7bit", "8bit", and "binary". + Add C=charset mailer parameter and the the DefaultCharSet option (no + short name) to set the default character set to use in the + Content-Type: header when doing encoding of an 8-bit message + which isn't marked as MIME into MIME format. If the C= + parameter is set on the Envelope From address, use that as + the default encoding; else use the DefaultCharSet option. + If neither is set, it defaults to "unknown-8bit" as + suggested by RFC 1428 section 3. + Allow ``U=user:group'' field in mailer definition to set a default + user and group that a mailer will be executed as. This + overrides the 'u' and 'g' options, and if the `F=S' flag is + also set, it is the uid/gid that will always be used (that + is, the controlling address is ignored). The values may be + numeric or symbolic; if only a symbolic user is given (no + group) that user's default group in the passwd file is used + as the group. Based on code donated by Chip Rosenthal of + Unicom. + Allow `u' option to also accept user:group as a value, in the same + fashion as the U= mailer option. + Add the symbolic time zone name in the Arpanet format dates (as + a comment). This adds a new compile-time configuration + flag: TZ_TYPE can be set to TZ_TM_NAME (use the value + of (struct tm *)->tm_name), TZ_TM_ZONE (use the value + of (struct tm *)->tm_zone), TZ_TZNAME (use extern char + *tzname[(struct tm *)->tm_isdst]), TZ_TIMEZONE (use + timezone()), or TZ_NONE (don't include the comment). Code + from Chip Rosenthal. + The "Timeout" option (formerly "r") is extended to allow suboptions. + For example, + O Timeout.helo = 2m + There are also two new suboptions "queuereturn" and + "queuewarn"; these subsume the old T option. Thus, to + set them both the preferred new syntax is + O Timeout.queuereturn = 5d + O Timeout.queuewarn = 4h + Sort queue by host name instead of by message priority if the + QueueSortOrder option (no short name) is set is set to + ``host''. This makes better use of the connection cache, + but may delay more ``interactive'' messages behind large + backlogs under some circumstances. This is probably a + good option if you have high speed links or don't do lots + of ``batch'' messages, but less good if you are using + something like PPP on a 14.4 modem. Based on code + contributed by Roy Mongiovi of Georgia Tech (my main + contribution was to make it configurable). + Save i-number of df file in qf file to simplify rebuilding of queue + after disasterous disk crash. Suggested by Kyle Jones of + UUNET; closely based on code from KJS DECWRL code written + by Paul Vixie. NOTA BENE: The qf files produced by 8.7 + are NOT back compatible with 8.6 -- that is, you can convert + from 8.6 to 8.7, but not the other direction. + Add ``F=d'' mailer flag to disable all use of angle brackets in + route-addrs in envelopes; this is because in some cases + they can be sent to the shell, which interprets them as + I/O redirection. + Don't include error file (option E) with return-receipts; this + can be confusing. + Don't send "Warning: cannot send" messages to owner-* or + *-request addresses. Suggested by Christophe Wolfhugel + of the Institut Pasteur, Paris. + Allow -O command line flag to set long form options. + Add "MinQueueAge" option to set the minimum time between attempts + to run the queue. For example, if the queue interval + (-q value) is five minutes, but the minimum queue age + is fifteen minutes, jobs won't be tried more often than + once every fifteen minutes. This can be used to give + you more responsiveness if your delivery mode is set to + queue-only. + Allow "fileopen" timeout (default: 60 seconds) for opening + :include: and .forward files. + Add "-k", "-v", and "-z" flags to map definitions; these set the + key field name, the value field name, and the field + delimiter. The field delimiter can be a single character + or the sequence "\t" or "\n" for tab or newline. + These are for use by NIS+ and similar access methods. + Change maps to always strip quotes before lookups; the -q flag + turns off this behaviour. Suggested by Motonori Nakamura. + Add "nisplus" map class. Takes -k and -v flags to choose the + key and value field names respectively. Code donated by + Sun Microsystems. + Add "hesiod" map class. The "file name" is used as the + "HesiodNameType" parameter to hes_resolve(3). Returns the + first value found for the match. Code donated by Scott + Hutton of Indiana University. + Add "netinfo" (NeXT NetInfo) map class. Maps can have a -k flag to + specify the name of the property that is searched as the + key and a -v flag to specify the name of the property that + is returned as the value (defaults to "members"). The + default map is "/aliases". Some code based on code + contributed by Robert La Ferla of Hot Software. + Add "text" map class. This does slow, linear searches through + text files. The -z flag specifies a column delimiter + (defaults to any sequence of white space), the -k flag + sets the key column number, and the -v flag sets the + value column number. Lines beginning with `#' are treated + as comments. + Add "program" map class to execute arbitrary programs. The search + key is presented as the last argument; the output is one + line read from the programs standard output. Exit statuses + are from sysexits.h. + Add "sequence" map class -- searches maps in sequence until it + finds a match. For example, the declarations: + Kmap1 ... + Kmap2 ... + Kmapseq sequence map1 map2 + defines a map "mapseq" that first searches map1; if the + value is found it is returned immediately, otherwise + map2 is searched and the value returned. + Add "switch" map class. This is much like "sequence" except that + the ordering is fetched from an external file, usually + the system service switch. The parameter is the name of + the service to switch on, and the maps that it will use + are the name of the switch map followed by ".service_type". + For example, if the declaration of the map is + Ksample switch hosts + and the system service switch specifies that hosts are + looked up using dns and nis in that order, then this is + equivalent to + Ksample sequence sample.dns sample.nis + The subordinate maps (sample.*) must already be defined. + Add "user" map class -- looks up users using getpwnam. Takes a + "-v field" flag on the definition that tells what passwd + entry to return -- legal values are name, passwd, uid, gid, + gecos, dir, and shell. Generally expected to be used with + the -m (matchonly) flag. + Add "bestmx" map class -- returns the best MX value for the host + listed as the value. If there are several "best" MX records + for this host, one will be chosen at random. + Add "userdb" map class -- looks up entries in the user database. + The "file name" is actually the tag that will be used, + typically "mailname". If there are multiple entries + matching the name, the one chosen is undefined. + Add multiple queue timeouts (both return and warning). These are + set by the Precedence: or Priority: header fields to one of + three values. If a Priority: is set and has value "normal", + "urgent", or "non-urgent" the corresponding timeouts are + used. If no priority is set, the Precedence: is consulted; + if negative, non-urgent timeouts are used; if greater than + zero, urgent timeouts are used. Otherwise, normal timeouts + are used. The timeouts are set by setting the six timeouts + queue{warn,return}.{urgent,normal,non-urgent}. + Fix problem when a mail address is resolved to a $#error mailer + with a temporary failure indication; it works in SMTP, + but when delivering locally the mail is silently discarded. + This patch, from Kyle Jones of UUNET, bounces it instead + of queueing it (queueing is very hard). + When using /etc/hosts or NIS-style lookups, don't assume that + the first name in the list is the best one -- instead, + search for the first one with a dot. For example, if + an /etc/hosts entry reads + 128.32.149.68 mammoth mammoth.CS.Berkeley.EDU + this change will use the second name as the canonical + machine name instead of the initial, unqualified name. + Change dequote map to replace spaces in quoted text with a value + indicated by the -s flag on the dequote map definition. + For example, ``Mdequote dequote -s_'' will change + "Foo Bar" into an unquoted Foo_Bar instead of leaving it + quoted (because of the space character). Suggested by Dan + Oscarsson for use in X.400 addresses. + Implement long macro names as ${name}; long class names can + be similarly referenced as $={name} and $~{name}. + Definitions are (e.g.) ``D{name}value''. Names that have + a leading lower case letter or punctuation characters are + reserved for internal use by sendmail; i.e., config files + should use names that begin with a capital letter. Based + on code contributed by Dan Oscarsson. + Fix core dump if getgrgid returns a null group list (as opposed + to an empty group list, that is, a pointer to a list + with no members). Fix from Andrew Chang of Sun Microsystems. + Fix possible core dump if malloc fails -- if the malloc in xalloc + failed, it called syserr which called newstr which called + xalloc.... The newstr is now avoided for "panic" messages. + Reported by Stuart Kemp of James Cook University. + Improve connection cache timeouts; previously, they were not even + checked if you were delivering to anything other than an + IPC-connected host, so a series of (say) local mail + deliveries could cause cached connections to be open + much longer than the specified timeout. + If an incoming message exceeds the maximum message size, stop + writing the incoming bytes to the queue data file, since + this can fill your mqueue partition -- this is a possible + denial-of-service attack. + Don't reject all numeric local user names unless HESIOD is + defined. It turns out that Posix allows all-numeric + user names. Fix from Tony Sanders of BSDI. + Add service switch support. If the local OS has a service + switch (e.g., /etc/nsswitch.conf on Solaris or /etc/svc.conf + on DEC systems) that will be used; otherwise, it falls back + to using a local mechanism based on the ServiceSwitchFile + option (default: /etc/service.switch). For example, if the + service switch lists "files" and "nis" for the aliases + service, that will be the default lookup order. the "files" + ("local" on DEC) service type expands to any alias files + you listed in the configuration file, even if they aren't + actually file lookups. + Option I (NameServerOptions) no longer sets the "UseNameServer" + variable which tells whether or not DNS should be considered + canonical. This is now determined based on whether or not + "dns" is in the service list for "hosts". + Add preliminary support for the ESMTP "DSN" extension (Delivery + Status Notifications). DSN notifications override + Return-Receipt-To: headers, which are bogus anyhow. + Add T=mts-name-type/address-type/diagnostic-type keyletter to mailer + definitions to define the types used in DSN returns for + MTA names, addresses, and diagnostics respectively. + Extend heuristic to force running in ESMTP mode to look for the + five-character string "ESMTP" anywhere in the 220 greeting + message (not just the second line). This is to provide + better compatibility with other ESMTP servers. + Print sequence number of job when running the queue so you can + easily see how much progress you have made. Suggested + by Peter Wemm of DIALix. + Map newlines to spaces in logged message-ids; some versions of + syslog truncate the rest of the line after newlines. + Suggested by Fletcher Mattox of U. Texas. + Move up forking for job runs so that if a message is split into + multiple envelopes you don't get "fork storms" -- this + also improves the connection cache utilization. + Accept "<<>>", "<<<>>>", and so forth as equivalent to "<>" for + the purposes of refusing to send error returns. Suggested + by Motonori Nakamura of Ritsumeikan University. + Relax rules on when a file can be written when referenced from + the aliases file: use the default uid/gid instead of the + real uid/gid. This allows you to create a file owned by + and writable only by the default uid/gid that will work + all the time (without having the setuid bit set). Change + suggested by Shau-Ping Lo and Andrew Cheng of Sun + Microsystems. + Add "DialDelay" option (no short name) to provide an "extra" + delay for dial on demand systems. If this is non-zero + and a connect fails, sendmail will wait this long and + then try again. If it takes longer than the kernel + timeout interval to establish the connection, this + option can give the network software time to establish + the link. The default units are seconds. + Move logging of sender information to be as early as possible; + previously, it could be delayed a while for SMTP mail + sent to aliases. Suggested by Brad Knowles of the + Defense Information Systems Agency. + Call res_init() before setting RES_DEBUG; this is required by + BIND 4.9.3, or so I'm told. From Douglas Anderson of + the National Computer Security Center. + Add xdelay= field in logs -- this is a transaction delay, telling + you how long it took to deliver to this address on the + last try. It is intended to be used for sorting mailing + lists to favor "quick" addresses. Provided for use by + the mailprio scripts (see below). + If a map cannot be opened, and that map is non-optional, and + an address requires that map for resolution, queue the + map instead of bouncing it. This involves creating a + pseudo-class of maps called "bogus-map" -- if a required + map cannot be opened, the class is changed to bogus-map; + all queries against bogus-map return "tempfail". The + bogus-map class is not directly accessible. A sample + implementation was donated by Jem Taylor of Glasgow + University Computing Service. + Fix a possible core dump when mailing to a program that talks + SMTP on its standard input. Fix from Keith Moore of + the University of Kentucky. + Make it possible to resolve filenames to $#local $: @ /filename; + previously, the "@" would cause it to not be recognized + as a file. Problem noted by Brian Hill of U.C. Davis. + Accept a -1 signal to re-exec the daemon. This only works if + argv[0] is a full path to sendmail. + Fix bug in "addr=..." field in O option on little-endian machines + -- the network number wasn't being converted to network + byte order. Patch from Kurt Lidl of Pix Technologies + Corporation. + Pre-initialize the resolver early on; this is to avoid a bug with + BIND 4.9.3 that can cause the _res.retry field to get + reset to zero, causing all name server lookups to time + out. Fix from Matt Day of Artisoft. + Restore T line (trusted users) in config file -- but instead of + locking out the -f flag, they just tell whether or not + an X-Authentication-Warning: will be added. This really + just creates new entries in class 't', so "Ft/file/name" + can be used to read trusted user names from a file. + Trusted users are also allowed to execute programs even + if they have a shell that isn't in /etc/shells. + Improve NEWDB alias file rebuilding so it will create them + properly if they do not already exist. This had been + a MAYBENEXTRELEASE feature in 8.6.9. + Check for @:@ entry in NIS maps before starting up to avoid + (but not prevent, sigh) race conditions. This ought to + be handled properly in ypserv, but isn't. Suggested by + Michael Beirne of Motorola. + Refuse connections if there isn't enough space on the filesystem + holding the queue. Contributed by Robert Dana of Wolf + Communications. + Skip checking for directory permissions in the path to a file + when checking for file permissions iff setreuid() + succeeded -- it is unnecessary in that case. This avoids + significant performance problems when looking for .forward + files. Based on a suggestion by Win Bent of USC. + Allow symbolic ruleset names. Syntax can be "Sname" to get an + arbitrary ruleset number assigned or "Sname = integer" + to assign a specific ruleset number. Reference is + $>name_or_number. Names can be composed of alphas, digits, + underscore, or hyphen (first character must be non-numeric). + Allow -o flag on AliasFile lines to make the alias file optional. + From Bryan Costales of ICSI. + Add NoRecipientAction option to handle the case where there is + no legal recipient header in the message. It can take + on values: + None Leave the message as is. The + message will be passed on even + though it is in technically + illegal syntax. + Add-To Add a To: header with any + recipients that it can find from + the envelope. This risks exposing + Bcc: recipients. + Add-Apparently-To Add an Apparently-To: header. This + has almost no redeeming social value, + and is provided only for back + compatibility. + Add-To-Undisclosed Add a header reading + To: undisclosed-recipients:; + which will have the effect of + making the message legal without + exposing Bcc: recipients. + Add-Bcc To add an empty Bcc: header. + There is a chance that mailers down + the line will delete this header, + which could cause exposure of Bcc: + recipients. + The default is NoRecipientAction=None. + Truncate (rather than delete) Bcc: lines in the header. This + should prevent later sendmails (at least, those that don't + themselves delete Bcc:) from considering this message to + be non-conforming -- although it does imply that non-blind + recipients can see that a Bcc: was sent, albeit not to whom. + Add SafeFileEnvironment option. If declared, files named as delivery + targets must be regular files in addition to the regular + checks. Also, if the option is non-null then it is used as + the name of a directory that is used as a chroot(2) + environment for the delivery; the file names listed in an + alias or forward should include the name of this root. + For example, if you run with + O SafeFileEnvironment=/arch + then aliases should reference "/arch/rest/of/path". If a + value is given, sendmail also won't try to save to + /usr/tmp/dead.letter (instead it just leaves the job in the + queue as Qfxxxxxx). Inspired by *Hobbit*'s sendmail patch kit. + Support -A flag for alias files; this will comma concatenate like + entries. For example, given the aliases: + list: member1 + list: member2 + and an alias file declared as: + OAhash:-A /etc/aliases + the final alias inserted will be "list: member1,member2"; + without -A you will get an error on the second and subsequent + alias for "list". Contributed by Bryan Costales of ICSI. + Line-buffer transcript file. Suggested by Liudvikas Bukys. + Fix a problem that could cause very long addresses to core dump in + some special circumstances. Problem pointed out by Allan + Johannesen. + (Internal change.) Change interface to expand() (macro expansion) + to be simpler and more consistent. + Delete check for funny qf file names. This didn't really give + any extra security and caused some people some problems. + (If you -really- want this, define PICKY_QF_NAME_CHECK + at compile time.) Suggested by Kyle Jones of UUNET. + (Internal change.) Change EF_NORETURN to EF_NO_BODY_RETN and + merge with DSN code; this is simpler and more consistent. + This may affect some people who have written their own + checkcompat() routine. + (Internal change.) Eliminate `D' line in qf file. The df file + is now assumed to be the same name as the qf file (with + the `q' changed to a `d', of course). + Avoid forking for delivery if all recipient mailers are marked as + "expensive" -- this can be a major cost on some systems. + Essentially, this forces sendmail into "queue only" mode + if all it is going to do is queue anyway. + Avoid sending a null message in some rather unusual circumstances + (specifically, the RCPT command returns a temporary + failure but the connection is lost before the DATA + command). Fix from Scott Hammond of Secure Computing + Corporation. + Change makesendmail to use a somewhat more rational naming scheme: + Makefiles and obj directories are named $os.$rel.$arch, + where $os is the operating system (e.g., SunOS), $rel is + the release number (e.g., 5.3), and $arch is the machine + architecture (e.g., sun4). Any of these can be omitted, + and anything after the first dot in a release number can + be replaced with "x" (e.g., SunOS.4.x.sun4). The previous + version used $os.$arch.$rel and was rather less general. + Change makesendmail to do a "make depend" in the target directory + when it is being created. This involves adding an empty + "depend:" entry in most Makefiles. + Ignore IDENT return value if the OSTYPE field returns "OTHER", + as indicated by RFC 1413. Pointed out by Kari Hurtta + of the Finnish Meteorological Institute. + Fix problem that could cause multiple responses to DATA command + on header syntax errors (e.g., lines beginning with colons). + Problem noted by Jens Thomassen of the University of Oslo. + Don't let null bytes in headers cause truncation of the rest of + the header. + Log Authentication-Warning:s. Suggested by Motonori Nakamura. + Increase timeouts on message data puts to allow time for receivers + to canonify addresses in headers on the fly. This is still + a rather ugly heuristic. From Motonori Nakamura. + Add "HasWildcardMX" suboption to ResolverOptions; if set, MX + records are not used when canonifying names, and when MX + lookups are done for addressing they must be fully + qualified. This is useful if you have a wildcard MX record, + although it may cause other problems. In general, don't use + wildcard MX records. Patch from Motonori Nakamura. + Eliminate default two-line SMTP greeting message. Instead of + adding an extra "ESMTP spoken here" line, the word "ESMTP" + is added between the first and second word of the first + line of the greeting message (i.e., immediately after the + host name). This eliminates the need for the BROKEN_SMTP_PEERS + compile flag. Old sendmails won't see the ESMTP, but that's + acceptable because SIZE was the only useful extension that + old sendmails understand. + Avoid gethostbyname calls on UNIX domain sockets during SIGUSR1 + invoked state dumps. From Masaharu Onishi. + Allow on-line comments in .forward and :include: files; they are + introduced by the string "<LWSP>#@#<LWSP>", where <LWSP> + is a space or a tab. This is intended for native + representation of non-ASCII sets such as Japanese, where + existing encodings would be unreadable or would lose + data -- for example, + <motonori@cs.ritsumei.ac.jp> NAKAMURA Motonori + (romanized/less information) + <motonori@cs.ritsumei.ac.jp> =?ISO-2022-JP?B?GyRCQ2ZCPBsoQg==?= + =?ISO-2022-JP?B?GyRCQUdFNRsoQg==?= + (with MIME encoding, not human readable) + <motonori@cs.ritsumei.ac.jp> #@# ^[$BCfB<^[(B ^[$BAGE5^[(B + (native encoding with ISO-2022-JP) + The last form is human readable in the Japanese environment. + Based on a fix from (surprise!) Motonori Nakamura. + Don't make SMTP error returns on MAIL FROM: line be "sticky" for all + messages to that host; these are most frequently associated + with addresses rather than the host, with the exception of + 421 (service shutting down). The effect was to cause queues + to sometimes take an excessive time to flush. Reported by + Robert Sargent of Southern Geographics Technologies and + Eric Prestemon of American University. + Add Nice=N mailer option to set the niceness at which a mailer will + run. This is actually a relative niceness (that is, an + increment on the background value). + Log queue runs that are skipped due to high loads. They are logged + at LOG_INFO priority iff the log level is > 8. Contributed + by Bruce Nagel of Data General. + Allow the error mailer to accept a DSN-style error status code + instead of an sysexits status code in the host part. + Anything with a dot will be interpreted as a DSN-style code. + Add new mailer flag: F=3 will tell translations to Quoted-Printable + to encode characters that might be munged by an EBCDIC system + in addition to the set required by RFC 1521. The additional + characters are !, ", #, $, @, [, \, ], ^, `, {, |, }, and ~. + (Think of "IBM 360" as the mnemonic for this flag.) + Change check for mailing to files to look for a pathname of [FILE] + rather than looking for the mailer named *file*. The mapping + of leading slashes still goes to the *file* mailer. This + allows you to implement the *file* mailer as a separate + program, for example, to insert a Content-Length: header + or do special security policy. However, note that the usual + initial checking for the file permissions is still done, and + the program in question needs to be very careful about how + it does the file write to avoid security problems. + Be able to read ~root/.forward even if the path isn't accessible to + regular users. This is disrecommended because sendmail + sometimes does not run as root (e.g., when an unsafe option + is specified on the command line), but should otherwise be + safe because .forward files must be owned by the user for + whom mail is being forwarded, and cannot be a symbolic link. + Suggested by Forrest Aldrich of Wang Laboratories. + Add new "HostsFile" option that is the pathname to the /etc/hosts + file. This is used for canonifying hostnames when the + service type is "files". + Implement programs on F (read class from file) line. The syntax is + Fc|/path/to/program to read the output from the program + into class "c". + Probe the network interfaces to find alternate names for this + host. Requires the SIOCGIFCONF ioctl call. Code + contributed by SunSoft. + Add "E" configuration line to set or propogate environment + variables into children. "E<envar>" will propogate + the named variable from the environment when sendmail + was invoked into any children it calls; "E<envar>=<value>" + sets the named variable to the indicated value. Any + variables not explicitly named will not be in the child + environment. However, sendmail still forces an + "AGENT=sendmail" environment variable, in part to enforce + at least one environment variable, since many programs and + libraries die horribly if this is not guaranteed. + Change heuristic for rebuilding both NEWDB and NDBM versions of + alias databases -- new algorithm looks for the substring + "/yp/" in the file name. This is more portable and involves + less overhead. Suggested by Motonori Nakamura. + Dynamically allocate the queue work list so that you don't lose + jobs in large queue runs. The old QUEUESIZE compile parameter + is replaced by QUEUESEGSIZE (the unit of allocation, which + should not need to be changed) and the MaxQueueRunSize option, + which is the absolute maximum number of jobs that will ever + be handled in a single queue run. Based on code contributed + by Brian Coan of the Institute for Global Communications. + Log message when a message is dropped because it exceeds the maximum + message size. Suggested by Leo Bicknell of Virginia Tech. + Allow trusted users (those on a T line or in $=t) to use -bs without + an X-Authentication-Warning: added. Suggested by Mark Thomas + of Mark G. Thomas Consulting. + Announce state of compile flags on -d0.1 (-d0.10 throws in the + OS-dependent defines). The old semantic of -d0.1 to not + run the daemon in background has been moved to -d99.100, + and the old 52.5 flag (to avoid disconnect() from closing + all output files) has been moved to 52.100. This makes + things more consistent (flags below .100 don't change + semantics) and separates out the backgrounding so that + it doesn't happen automatically on other unrelated debugging + flags. + If -t is used but no addresses are found in the header, give an + error message rather than just doing nothing. Fix from + Motonori Nakamura. + On systems (like SunOS) where the effective gid is not necessarily + included in the group list returned by getgroups(), the + `restrictmailq' option could sometimes cause an authorized + user to not be able to use `mailq'. Fix from Charles Hannum + of MIT. + Allow symbolic service names for [IPC] mailers. Suggested by + Gerry Magennis of Logica International. + Add DontExpandCnames option to prevent $[ ... $] from expanding CNAMEs + when running DNS. For example, if the name FTP.Foo.ORG is + a CNAME for Cruft.Foo.ORG, then when sitting on a machine in + the Foo.ORG domain a lookup of "FTP" returns "Cruft.Foo.ORG" + if this option is not set, or "FTP.Foo.ORG" if it is set. + This is technically illegal under RFC 822 and 1123, but the + IETF is moving toward legalizing it. Note that turning on + this option is not sufficient to guarantee that a downstream + neighbor won't rewrite the address for you. + Add "-m" flag to makesendmail script -- this tells you what object + directory and Makefile it will use, but doesn't actually do + the make. + Do some additional checking on the contents of the qf file to try + to detect attacks against the qf file. In particular, + abort on any line beginning "From ", and add an "end of + file" line -- any data after that line is prohibited. + Always use /etc/sendmail.cf, regardless of the arbitrary vendor + choices. This can be overridden in the Makefile by using + either -DUSE_VENDOR_CF_PATH to get the vendor location + (to the extent that we know it) or by defining + _PATH_SENDMAILCF (which is a "hard override"). This allows + sendmail 8 to have more consistent installation instructions. + Allow macros on `K' line in config file. Suggested by Andrew Chang + of Sun Microsystems. + Improved symbol table hash function from Eric Wassenaar. This one + is at least 50% faster. + Fix problem that didn't notice that timeout on file open was a + transient error. Fix from Larry Parmelee of Cornell + University. + Allow comments (lines beginning with a `#') in files read for + classes. Suggested by Motonori Nakamura. + Make SIGINT (usually ^C) in test mode return to the prompt instead + of dropping out entirely. This makes testing some of the + name server lookups easier to deal with when there are + hung servers. From Motonori Nakamura. + Add new ${opMode} macro that is set to the current operation mode + (e.g., `s' for -bs, `t' for -bt, etc.). Suggested by + Claude Marinier <MARINIER@emp.ewd.dreo.dnd.ca>. + Add new delivery mode (Odd) that defers all map lookups to queue runs. + Kind of like queue-only mode (Odq) except it tries to avoid + any external service requests; for dial-on-demand hosts that + want to minimize DNS lookups when mail is being queued. For + this to work you will also have to make sure that gethostbyname + of your local host name does not do a DNS lookup. + Improved handling of "out of space" conditions from John Myers of + Carnegie Mellon. + Improved security for mailing to files on systems that have fchmod(2) + support. + Improve "cannot send message for N days" message -- now says "could + not send for past N days". Suggested by Tom Moore of AT&T + Global Information Solutions. + Less misleading Subject: line on messages sent to postmaster only. + From Motonori Nakamura. + Avoid duplicate error messages on bad command line flags. From + Motonori Nakamura. + Better error message for case where ruleset 0 falls off the end + or otherwise does not resolve to a canonical triple. + Fix a problem that could cause multiple bounce messages if a bad + address was sent along with a good address to an SMTP + site where that SMTP site returned a 4yz code in response + to the final dot of the data. Problem reported by David + James of British Telecom. + Add "volatile" declarations so that gcc -O2 will work. Patches + from Alexander Dupuy of System Management ARTS. + Delete duplicates in MX lists -- believe it or not, there are sites + that list the same host twice in an MX list. This deletion + only works on adjacent preferences, so an MX list that + had A=5, B=10, A=15 would leave both As, but one that had + A=5, A=10, B=15 would reduce to A, B. This is intentional, + just in case there is something wierd I haven't thought of. + Suggested by Barry Shein of Software Tool & Die. + SECURITY: .forward files cannot be symbolic links. If they are, + a bad guy can read your private files. + PORTABILITY FIXES: + Solaris 2 from Rob McMahon <cudcv@csv.warwick.ac.uk>. + System V Release 4 from Motonori Nakamura of Ritsumeikan + University. This expands the disk size + checking to include all (?) SVR4 configurations. + System V Release 4 from Kimmo Suominen -- initgroups(3) + and setrlimit(2) are both available. + System V Release 4 from sob@sculley.ffg.com -- some versions + apparently "have EX_OK defined in other headerfiles." + Linux Makefile typo. + Linux getusershell(3) is broken in Slackware 2.0 -- + from Andrew Pam of Xanadu Australia. + More Linux tweaking from John Kennedy of California State + University, Chico. + Cray changes from Eric Wassenaar: ``On Cray, shorts, + ints, and longs are all 64 bits, and all structs + are multiples of 64 bits. This means that the + sizeof operator returns only multiples of 8. + This requires adaptation of code that really + deals with 32 bit or 16 bit fields, such as IP + addresses or nameserver fields.'' + DG/UX 5.4.3 from Mark T. Robinson <mtr@ornl.gov>. To + get the old behaviour, use -DDGUX_5_4_2. + DG/UX hack: add _FORCE_MAIL_LOCAL_=yes environment + variable to fix bogus /bin/mail behaviour. + Tandem NonStop-UX from Rick McCarty <mccarty@mpd.tandem.com>. + This also cleans up some System V Release 4 compile + problems. + Solaris 2: sendmail.cw file should be in /etc/mail to + match all the other configuration files. Fix + from Glenn Barry of Emory University. + Solaris 2.3: compile problem in conf.c. Fix from Alain + Nissen of the University of Liege, Belgium. + Ultrix: freespace calculation was incorrect. Fix from + Takashi Kizu of Osaka University. + SVR4: running in background gets a SIGTTOU because the + emulation code doesn't realize that "getpeername" + doesn't require reading the file. Fix from Peter + Wemm of DIALix. + Solaris 2.3: due to an apparent bug in the socket emulation + library, sockets can get into a "wedged" state where + they just return EPROTO; closing and re-opening the + socket clears the problem. Fix from Bob Manson + of Ohio State University. + Hitachi 3050R & 3050RX running HI-UX/WE2: portability + fixes from Akihiro Hashimoto ("Hash") of Chiba + University. + AIX changes to allow setproctitle to work from Rainer Schöpf + of Zentrum für Datenverarbeitung der Universität + Mainz. + AIX changes for load average from Ed Ravin of NASA/Goddard. + SCO Unix from Chip Rosenthal of Unicom (code was using the + wrong statfs call). + ANSI C fixes from Adam Glass (NetBSD project). + Stardent Titan/ANSI C fixes from Kate Hedstrom of Rutgers + University. + DG-UX fixes from Bruce Nagel of Data General. + IRIX64 updates from Mark Levinson of the University of + Rochester Medical Center. + Altos System V (``the first UNIX/XENIX merge the Altos + did for their Series 1000 & Series 2000 line; + their merged code was licenced back to AT&T and + Microsoft and became System V release 3.2'') from + Tim Rice <timr@crl.com>. + OSF/1 running on Intel Paragon from Jeff A. Earickson + <jeff@ssd.intel.com> of Intel Scalable Systems + Divison. + Amdahl UTS System V 2.1.5 (SVr3-based) from Janet Jackson + <janet@dialix.oz.au>. + System V Release 4 (statvfs semantic fix) from Alain + Durand of I.M.A.G. + HP-UX 10.x multiprocessor load average changes from + Scott Hutton and Jeff Sumler of Indiana University. + Cray CSOS from Scott Bolte of Cray Computer Corporation. + Unicos 8.0 from Douglas K. Rand of the University of North + Dakota, Scientific Computing Center. + Solaris 2.4 fixes from Sanjay Dani of Dani Communications. + ConvexOS 11.0 from Christophe Wolfhugel. + IRIX 4.0.5 from David Ashton-Reader of CADcentre. + ISC UNIX from J. J. Bailey. + HP-UX 9.xx on the 8xx series machines from Remy Giraud + of Meteo France. + HP-UX configuration from Tom Lane <tgl@sss.pgh.pa.us>. + IRIX 5.2 and 5.3 from Kari E. Hurtta. + FreeBSD 2.0 from Mike Hickey of Federal Data Corporation. + Sony NEWS-OS 4.2.1R and 6.0.3 from Motonori Nakamura. + Omron LUNA unios-b, mach from Motonori Nakamura. + NEC EWS-UX/V 4.2 from Motonori Nakamura. + NeXT 2.1 from Bryan Costales. + AUX patch thanks to Mike Erwin of Apple Computer. + HP-UX 10.0 from John Beck of Hewlett-Packard. + Ultrix: allow -DBROKEN_RES_SEARCH=0 if you are using a + non-DEC resolver. Suggested by Allan Johannesen. + UnixWare 2.0 fixes from Petr Lampa of the Technical + University of Brno (Czech Republic). + KSR OS 1.2.2 support from Todd Miller of the University + of Colorado. + UX4800 support from Kazuhisa Shimizu of NEC. + MAKEMAP: allow -d flag to allow insertion of duplicate aliases + in type ``btree'' maps. The semantics of this are undefined + for regular maps, but it can be useful for the user database. + MAKEMAP: lock database file while rebuilding to avoid sendmail + lookups while the rebuild is going on. There is a race + condition between the open(... O_TRUNC ...) and the lock + on the file, but it should be quite small. + SMRSH: sendmail restricted shell added to the release. This can + be used as an alternative to /bin/sh for the "prog" mailer, + giving the local administrator more control over what + programs can be run from sendmail. + MAIL.LOCAL: add this local mailer to the tape. It is not really + part of the release proper, and isn't fully supported; in + particular, it does not run on System V based systems and + never will. + CONTRIB: a patch to rmail.c from Bill Gianopoulos of Raytheon + to allow rmail to compile on systems that don't have + function prototypes and systems that don't have snprintf. + CONTRIB: add the "mailprio" scripts that will help you sort mailing + lists by transaction delay times so that addresses that + respond quickly get sent first. This is to prevent very + sluggish servers from delaying other peoples' mail. + Contributed by Tony Sanders of BSDI. + CONTRIB: add the "bsdi.mc" file as contributed by Tony Sanders + of BSDI. This has a lot of comments to help people out. + CONFIG: Don't have .mc files include(../m4/cf.m4) -- instead, + put this on the m4 command line. On GNU m4 (which + supports the __file__ primitive) you can run m4 in an + arbitrary directory -- use either: + m4 ${CFDIR}/m4/cf.m4 config.mc > config.cf + or + m4 -I${CFDIR} m4/cf.m4 config.mc > config.cf + On other versions of m4 that don't support __file__, you + can use: + m4 -D_CF_DIR_=${CFDIR}/ ${CFDIR}/m4/cf.m4 ... + (Note the trailing slash on the _CF_DIR_ definition.) + Old versions of m4 will default to _CF_DIR_=.. for back + compatibility. + CONFIG: fix mail from <> so it will properly convert to + MAILER-DAEMON on local addresses. + CONFIG: fix code that was supposed to catch colons in host + names. Problem noted by John Gardiner Myers of CMU. + CONFIG: allow use of SMTP_MAILER_MAX in nullclient configuration. + From Paul Riddle of the University of Maryland, Baltimore + County. + CONFIG: Catch and reject "." as a host address. + CONFIG: Generalize domaintable to look up all domains, not + just unqualified ones. + CONFIG: Delete OLD_SENDMAIL support -- as near as I can tell, it + was never used and didn't work anyway. + CONFIG: Set flags A, w, 5, :, /, |, and @ on the "local" mailer + and d on all mailers in the UUCP class. + CONFIG: Allow "user+detail" to be aliased specially: it will first + look for an alias for "user+detail", then for "user+*", and + finally for "user". This is intended for forwarding mail + for system aliases such as root and postmaster to a + centralized hub. + CONFIG: add confEIGHT_BIT_HANDLING to set option 8 (see above). + CONFIG: add smtp8 mailer; this has the F=8 (just-send-8) flag set. + The F=8 flag is also set on the "relay" mailer, since + this is expected to be another sendmail. + CONFIG: avoid qualifying all UUCP addresses sent via SMTP with + the name of the UUCP_RELAY -- in some cases, this is the + wrong value (e.g., when we have local UUCP connections), + and this can create unreplyable addresses. From Chip + Rosenthal of Unicom. + CONFIG: add confRECEIVED_HEADER to change the format of the + Received: header inserted into all messages. Suggested by + Gary Mills of the University of Manitoba. + CONFIG: Make "notsticky" the default; use FEATURE(stickyhost) + to get the old behaviour. I did this upon observing + that almost everyone needed this feature, and that the + concept I was trying to make happen didn't work with + some user agents anyway. FEATURE(notsticky) still works, + but it is a no-op. + CONFIG: Add LUSER_RELAY -- the host to which unrecognized user + names are sent, rather than immediately diagnosing them + as User Unknown. + CONFIG: Add SMTP_MAILER_ARGS, ESMTP_MAILER_ARGS, SMTP8_MAILER_ARGS, + and RELAY_MAILER_ARGS to set the arguments for the + indicated mailers. All default to "IPC $h". Patch from + Larry Parmelee of Cornell University. + CONFIG: pop mailer needs F=n flag to avoid "annoying side effects + on the client side" and F=P to get an appropriate + return-path. From Kimmo Suominen. + CONFIG: add FEATURE(local_procmail) to use the procmail program + as the local mailer. For addresses of the form "user+detail" + the "detail" part is passed to procmail via the -a flag. + Contributed by Kimmo Suominen. + CONFIG: add MAILER(procmail) to add an interface to procmail for + use from mailertables. This lets you execute arbitrary + procmail scripts. Contributed by Kimmo Suominen. + CONFIG: add T= fields (MTS type) to local, smtp, and uucp mailers. + CONFIG: add OSTYPE(ptx2) for DYNIX/ptx 2.x from Sequent. From + Paul Southworth of CICNet Systems Support. + CONFIG: use -a$g as default to UUCP mailers, instead of -a$f. + This causes the null return path to be rewritten as + MAILER-DAEMON; otherwise UUCP gets horribly confused. + From Michael Hohmuth of Technische Universitat Dresden. + CONFIG: Add FEATURE(bestmx_is_local) to cause any hosts that + list us as the best possible MX record to be treated as + though they were local (essentially, assume that they + are included in $=w). This can cause additional DNS + traffic, but is easier to administer if this fits your + local model. It does not work reliably if there are + multiple hosts that share the best MX preference. + Code contributed by John Oleynick of Rutgers. + CONFIG: Add FEATURE(smrsh) to use smrsh (the SendMail Restricted + SHell) instead of /bin/sh as the program used for delivery + to programs. If an argument is included, it is used as + the path to smrsh; otherwise, /usr/local/etc/smrsh is + assumed. + CONFIG: Add LOCAL_MAILER_MAX and PROCMAILER_MAILER_MAX to limit the + size of messages to the local and procmail mailers + respectively. Contributed by Brad Knowles of the Defense + Information Systems Agency. + CONFIG: Handle leading ``phrase:'' and trailing ``;'' as comments + (just like text outside of angle brackets) in order to + properly deal with ``group: addr1, ... addrN;'' syntax. + CONFIG: Require OSTYPE macro (the defaults really don't apply to + any real systems any more) and tweak the DOMAIN macro + so that it is less likely that users will accidently use + the Berkeley defaults. Also, create some generic files + that really can be used in the real world. + CONFIG: Add new configuration macros to set character sets for + messages _arriving from_ various mailers: LOCAL_MAILER_CHARSET, + SMTP_MAILER_CHARSET, and UUCP_MAILER_CHARSET. + CONFIG: Change UUCP_MAX_SIZE to UUCP_MAILER_MAX for consistency. + The old name will still be accepted for a while at least. + CONFIG: Implement DECNET_RELAY as spec for host to which DECNET + mail (.DECNET pseudo-domain or node::user) will be sent. + As with all relays, it can be ``mailer:hostname''. Suggested + by Scott Hutton. + CONFIG: Add MAILER(mail11) to get DECnet support. Code contributed + by Barb Dijker of Labyrinth Computer Services. + CONFIG: change confCHECK_ALIASES to default to False -- it has poor + performance for large alias files, and this confused many + people. + CONFIG: Add confCF_VERSION to append local information to the + configuration version number displayed during SMTP startup. + CONFIG: fix some.newsgroup.usenet@local.host syntax (previously it + would only work when locally addressed. Fix from + Edvard Tuinder of Cistron Internet Services. + CONFIG: use ${opMode} to avoid error on .REDIRECT addresses if option + "n" (CheckAlaises) is set when rebuilding alias database. + Based on code contributed by Claude Marinier. + CONFIG: Allow mailertable to have values of the form + ``error:code message''. The ``code'' is a status code + derived from the sysexits codes -- e.g., NOHOST or UNAVAILABLE. + Contributed by David James <dwj@agw.bt.co.uk>. + CONFIG: add MASQUERADE_DOMAIN(domain list) to extend the list of + sender domains that will be replaced with the masquerade name. + These domains will not be treated as local, but if mail passes + through with sender addresses in those domains they will be + replaced by the masquerade name. These can also be specified + in a file using MASQUERADE_DOMAIN_FILE(filename). + CONFIG: add FEATURE(masquerade_envelope) to masquerade the envelope + as well as the header. Substantial improvements to this + code were contributed by Per Hedeland. + CONFIG: add MAILER(phquery) to define a new "ph" mailer; this can be + accessed from a mailertable to do CCSO ph lookups. Contributed + by Kimmo Suominen. + CONFIG: add MAILER(cyrus) to define a new Cyrus mailer; this can be + used to define cyrus and cyrusbb mailers (for IMAP support). + Contributed by John Gardiner Myers of Carnegie Mellon. + CONFIG: add confUUCP_MAILER to select default mailer to use for + UUCP addressing. Suggested by Tom Moore of AT&T GIS. + NEW FILES: + cf/cf/cs-hpux10.mc + cf/cf/cs-solaris2.mc + cf/cf/cyrusproto.mc + cf/cf/generic-bsd4.4.mc + cf/cf/generic-hpux10.mc + cf/cf/generic-hpux9.mc + cf/cf/generic-osf1.mc + cf/cf/generic-solaris2.mc + cf/cf/generic-sunos4.1.mc + cf/cf/generic-ultrix4.mc + cf/cf/huginn.cs.mc + cf/domain/berkeley-only.m4 + cf/domain/generic.m4 + cf/feature/bestmx_is_local.m4 + cf/feature/local_procmail.m4 + cf/feature/masquerade_envelope.m4 + cf/feature/smrsh.m4 + cf/feature/stickyhost.m4 + cf/feature/use_ct_file.m4 + cf/m4/cfhead.m4 + cf/mailer/cyrus.m4 + cf/mailer/mail11.m4 + cf/mailer/phquery.m4 + cf/mailer/procmail.m4 + cf/ostype/amdahl-uts.m4 + cf/ostype/bsdi2.0.m4 + cf/ostype/hpux10.m4 + cf/ostype/irix5.m4 + cf/ostype/isc4.1.m4 + cf/ostype/ptx2.m4 + cf/ostype/unknown.m4 + contrib/bsdi.mc + contrib/mailprio + contrib/rmail.oldsys.patch + mail.local/mail.local.0 + makemap/makemap.0 + smrsh/README + smrsh/smrsh.0 + smrsh/smrsh.8 + smrsh/smrsh.c + src/Makefiles/Makefile.CSOS + src/Makefiles/Makefile.EWS-UX_V + src/Makefiles/Makefile.HP-UX.10 + src/Makefiles/Makefile.IRIX.5.x + src/Makefiles/Makefile.IRIX64 + src/Makefiles/Makefile.ISC + src/Makefiles/Makefile.KSR + src/Makefiles/Makefile.NEWS-OS.4.x + src/Makefiles/Makefile.NEWS-OS.6.x + src/Makefiles/Makefile.NEXTSTEP + src/Makefiles/Makefile.NonStop-UX + src/Makefiles/Makefile.Paragon + src/Makefiles/Makefile.SCO.3.2v4.2 + src/Makefiles/Makefile.SunOS.5.3 + src/Makefiles/Makefile.SunOS.5.4 + src/Makefiles/Makefile.SunOS.5.5 + src/Makefiles/Makefile.UNIX_SV.4.x.i386 + src/Makefiles/Makefile.uts.systemV + src/Makefiles/Makefile.UX4800 + src/aliases.0 + src/mailq.0 + src/mime.c + src/newaliases.0 + src/sendmail.0 + test/t_seteuid.c + RENAMED FILES: + cf/cf/alpha.mc => cf/cf/s2k-osf1.mc + cf/cf/chez.mc => cf/cf/chez.cs.mc + cf/cf/hpux-cs-exposed.mc => cf/cf/cs-hpux9.mc + cf/cf/osf1-cs-exposed.mc => cf/cf/cs-osf1.mc + cf/cf/s2k.mc => cf/cf/s2k-ultrix4.mc + cf/cf/sunos4.1-cs-exposed.mc => cf/cf/cs-sunos4.1.mc + cf/cf/ultrix4.1-cs-exposed.mc => cf/cf/cs-ultrix4.mc + cf/cf/vangogh.mc => cf/cf/vangogh.cs.mc + cf/domain/Berkeley.m4 => cf/domain/Berkeley.EDU.m4 + cf/domain/cs-exposed.m4 => cf/domain/CS.Berkeley.EDU.m4 + cf/domain/eecs-hidden.m4 => cf/domain/EECS.Berkeley.EDU.m4 + cf/domain/s2k.m4 => cf/domain/S2K.Berkeley.EDU.m4 + cf/ostype/hpux.m4 => cf/ostype/hpux9.m4 + cf/ostype/irix.m4 => cf/ostype/irix4.m4 + cf/ostype/ultrix4.1.m4 => cf/ostype/ultrix4.m4 + src/Makefile.* => src/Makefiles/Makefile.* + src/Makefile.AUX => src/Makefiles/Makefile.A-UX + src/Makefile.BSDI => src/Makefiles/Makefile.BSD-OS + src/Makefile.DGUX => src/Makefiles/Makefile.dgux + src/Makefile.RISCos => src/Makefiles/Makefile.UMIPS + src/Makefile.SunOS.4.0.3 => src/Makefiles/Makefile.SunOS.4.0 + OBSOLETED FILES: + cf/cf/cogsci.mc + cf/cf/cs-exposed.mc + cf/cf/cs-hidden.mc + cf/cf/hpux-cs-hidden.mc + cf/cf/knecht.mc + cf/cf/osf1-cs-hidden.mc + cf/cf/sunos3.5-cs-exposed.mc + cf/cf/sunos3.5-cs-hidden.mc + cf/cf/sunos4.1-cs-hidden.mc + cf/cf/ultrix4.1-cs-hidden.mc + cf/domain/cs-hidden.m4 + contrib/rcpt-streaming + src/Makefiles/Makefile.SunOS.5.x + +8.6.12/8.6.12 95/03/28 + Fix to IDENT code (it was getting the size of the reply buffer + too small, so nothing was ever accepted). Fix from several + people, including Allan Johannesen, Shane Castle of the + Boulder County Information Services, and Jeff Smith of + Warwick University (all arrived within a few hours of + each other!). + Fix a problem that could cause large jobs to run out of + file descriptors on systems that use vfork() rather + than fork(). + +8.6.11/8.6.11 95/03/08 + The ``possible attack'' message would be logged more often + than necessary if you are using Pine as a user agent. + The wrong host would be reported in the ``possible attack'' + message when attempted from IDENT. + In some cases the syslog buffer could be overflowed when + reporting the ``possible attack'' message. This can + cause denial of service attacks. Truncate the message + to 80 characters to prevent this problem. + When reading the IDENT response a loop is needed around the + read from the network to ensure that you don't get + partial lines. + Password entries without any shell listed (that is, a null + shell) wouldn't match as "ok". Problem noted by + Rob McMahon. + When running BIND 4.9.x a problem could occur because the + _res.options field is initialized differently than it + was historically -- this requires that sendmail call + res_init before it tweaks any bits. + Fix an incompatibility in openxscript() between the file open mode + and the stdio mode passed to fdopen. This caused UnixWare + 2.0 to have conniptions. Fix from Martin Sohnius of + Novell Labs Europe. + Fix problem with static linking of local getopt routine when + using GNU's ld command. Fix from John Kennedy of + Cal State Chico. + It was possible to turn off privacy flags. Problem noted by + *Hobbit*. + Be more paranoid about writing files. Suggestions by *Hobbit* + and Liudvikas Bukys. + MAKEMAP: fixes for 64 bit machines (DEC Alphas in particular) + from Spider Boardman. + CONFIG: No changes (version number only, to keep it in sync + with the binaries). + +8.6.10/8.6.10 95/02/10 + SECURITY: Diagnose bogus values to some command line flags that + could allow trash to get into headers and qf files. + Validate the name of the user returned by the IDENT protocol. + Some systems that really dislike IDENT send intentionally + bogus information. Problem pointed out by Michael Bushnell + of the Free Software Foundation. Has some security + implications. + Fix a problem causing error messages about DNS problems when + the host name contained a percent sign to act oddly + because it was passed as a printf-style format string. + In some cases this could cause core dumps. + Avoid possible buffer overrun in returntosender() if error + message is quite ling. From Fletcher Mattox of the + University of Texas. + Fix a problem that would silently drop "too many hops" error + messages if and only if you were sending to an alias. + From Jon Giltner of the University of Colorado and + Dan Harton of Oak Ridge National Laboratory. + Fix a bug that caused core dumps on some systems if -d11.2 was + set and e->e_message was null. Fix from Bruce Nagel of + Data General. + Fix problem that can still cause df files to be left around + after "hop count exceeded" messages. Fix from Andrew + Chang and Shau-Ping Lo of SunSoft. + Fix a problem that can cause buffer overflows on very long + user names (as might occur if you piped to a program + with a lot of arguments). + Avoid returning an error and re-queueing if the host signature + is null; this can occur on addresses like ``user@.''. + Problem noted by Wesley Craig and the University of + Michigan. + Avoid possible calls to malloc(0) if MCI caching is turned + off. Bug fix from Pierre David of the Laboratoire + Parallelisme, Reseaux, Systemes et Modelisation (PRiSM), + Universite de Versailles - St Quentin, and Jacky + Thibault. + Make a local copy of the line being sent via senttolist() -- in + some cases, buffers could get trashed by map lookups + causing it to do unexpected things. This also simplifies + some of the map code. + CONFIG: No changes (version number only, to keep it in sync + with the binaries). + +8.6.9/8.6.9 94/04/19 + Do all mail delivery completely disconnected from any terminal. + This provides consistency with daemon delivery and + may have some security implications. + Make sure that malloc doesn't get called with zero size, + since that fails on some systems. Reported by Ed + Hill of the University of Iowa. + Fix multi-line values for $e (SMTP greeting message). Reported + by Mike O'Connor of Ford Motor Company. + Avoid syserr if no NIS domain name is defined, but the map it + is trying to open is optional. From Win Bent of USC. + Changes for picky compilers from Ed Gould of Digital Equipment. + Hesiod support for UDB from Todd Miller of the University of + Colorado. Use "hesiod" as the service name in the U + option. + Fix a problem that failed to set the "authentic" host name (that + is, the one derived from the socket info) if you called + sendmail -bs from inetd. Based on code contributed by + Todd Miller (this problem was also reported by Guy Helmer + of Dakota State University). This also fixes a related + problem reported by Liudvikas Bukys of the University of + Rochester. + Parameterize "nroff -h" in all the Makefiles so people with + variant versions can use them easily. Suggested by + Peter Collinson of Hillside Systems. + SMTP "MAIL" commands with multiple ESMTP parameters required two + spaces between parameters instead of one. Reported by + Valdis Kletnieks of Virginia Tech. + Reduce the number of system calls during message collection by + using global timeouts around the collect() loop. This + code was contributed by Eric Wassenaar. + If the initial hostname name gathering results in a name + without a dot (usually caused by NIS misconfiguration) + and BIND is compiled in, directly access DNS to get + the canonical name. This should make life easier for + Solaris systems. If it still can't be resolved, and + if the name server is listed as "required", try again + in 30 seconds. If that also fails, exit immediately to + avoid bogus "config error: mail loops back to myself" + messages. + Improve the "MAIL DELETED BECAUSE OF LACK OF DISK SPACE" error + message to explain how much space was available and + sound a bit less threatening. Suggested by Stan Janet + of the National Institute of Standards and Technology. + If mail is delivered to an alias that has an owner, deliver any + requested return-receipt immediately, and strip the + Return-Receipt-To: header from the subsequent message. + This prevents a certain class of denial of service + attack, arguably gives more reasonable semantics, and + moves things more towards what will probably become a + network standard. Suggested by Christopher Davis of + Kapor Enterprises. + Add a "noreceipts" privacy flag to turn off all return receipts + without recompiling. + Avoid printing ESMTP parameters as part of the error message + if there are errors during parsing. This change is + purely cosmetic. + Avoid sending out error messages during the collect phase of + SMTP; there is an MVS mailer from UCLA that gets + confused by this. Of course, I think it's their bug.... + Check for the $j macro getting undefined, losing a dot, or getting + lost from $=w in the daemon before accepting a connection; + if it is, it dumps state, prints a LOG_ALERT message, + and drops core for debugging. This is an attempt to + track down a bug that I thought was long since gone. + If you see this, please forward the log fragment to + sendmail@sendmail.ORG. + Change OLD_NEWDB from a #ifdef to a #if so it can be turned off + with -DOLD_NEWDB=0 on the command line. From Christophe + Wolfhugel. + Instead of trying to truncate the listen queue for the server + SMTP port when the load average is too high, just close + the port completely and reopen it later as needed. + This ensures that the other end gets a quick "connection + refused" response, and that the connection can be + recovered later. In particular, some socket emulations + seem to get confused if you tweak the listen queue + size around and can never start listening to connections + again. The down side is that someone could start up + another daemon process in the interim, so you could + have multiple daemons all not listening to connections; + this could in turn cause the sendmail.pid file to be + incorrect. A better approach might be to accept the + connection and give a 421 code, but that could break + other mailers in mysterious ways and have paging behaviour + implications. + Fix a glitch in TCP-level debugging that caused flag 16.101 to + set debugging on the wrong socket. From Eric Wassenaar. + When creating a df* temporary file, be sure you truncate any + existing data in the file -- otherwise system crashes + and the like could result in extra data being sent. + DOC: Replace the CHANGES-R5-R8 readme file with a paper in the + doc directory. This includes some additional + information. + CONFIG: change UUCP rules to never add $U! or $k! on the front + of recipient envelope addresses. This should have been + handled by the $&h trick, but broke if people were + mixing domainized and UUCP addresses. They should + probably have converted all the way over to uucp-uudom + instead of uucp-{new,old}, but the failure mode was to + loop the mail, which was bad news. + Portability fixes: + Newer BSDI systems (several people). + Older BSDI systems from Christophe Wolfhugel. + Intergraph CLIX, from Paul Southworth of CICNet. + UnixWare, from Evan Champion. + NetBSD from Adam Glass. + Solaris from Quentin Campbell of the University of + Newcastle upon Tyne. + IRIX from Dean Cookson and Bill Driscoll of Mitre + Corporation. + NCR 3000 from Kevin Darcy of Chrysler Financial Corporation. + SunOS (it has setsid() and setvbuf() calls) from + Jonathan Kamens of OpenVision Technologies. + HP-UX from Tor Lillqvist. + New Files: + src/Makefile.CLIX + src/Makefile.NCR3000 + doc/changes/Makefile + doc/changes/changes.me + doc/changes/changes.ps + +8.6.8/8.6.6 94/03/21 + SECURITY: it was possible to read any file as root using the + E (error message) option. Reported by Richard Jones; + fixed by Michael Corrigan and Christophe Wolfhugel. + +8.6.7/8.6.6 94/03/14 + SECURITY: it was possible to get root access by using wierd + values to the -d flag. Thanks to Alain Durand of + INRIA for forwarding me the notice from the bugtraq + list. + +8.6.6/8.6.6 94/03/13 + SECURITY: the ability to give files away on System V-based + systems proved dangerous -- don't run as the owner + of a :include: file on a system that allows giveaways. + Unfortunately, this also applies to determining a + valid shell. + IMPORTANT: Previous versions weren't expiring old connections + in the connection cache for a long time under some + circumstances. This could result in resource exhaustion, + both at your end and at the other end. This checks the + connections for timeouts much more frequently. From + Doug Anderson of NCSC. + Fix a glitch that snuck in that caused programs to be run as + the sender instead of the recipient if the mail was + from a local user to another local user. From + Motonori Nakamura of Kyoto University. + Fix "wildcard" on /etc/shells matching -- instead of looking + for "*", look for "/SENDMAIL/ANY/SHELL/". From + Bryan Costales of ICSI. + Change the method used to declare the "statfs" availability; + instead of HASSTATFS and/or HASUSTAT with a ton of + tweaking in conf.c, there is a single #define called + SFS_TYPE which takes on one of six values (SFS_NONE + for no statfs availability, SFS_USTAT for the ustat(2) + syscall, SFS_4ARGS for a four argument statfs(2) call, + and SFS_VFS, SFS_MOUNT, or SFS_STATFS for a two argument + statfs(2) call with the declarations in <sys/vfs.h>, + <sys/mount.h>, or <sys/statfs.h> respectively). + Fix glitch in NetInfo support that could return garbage if + there was no "/locations/sendmail" property. From + David Meyer of the University of Virginia. + Change HASFLOCK from defined/not-defined to a 0/1 definition + to allow Linux to turn it off even though it is a + BSD-like system. + Allow setting of "ident" timeout to zero to turn off the ident + protocol entirely. + Make 7-bit stripping local to a connection (instead of to a + mailer); this allows you to specify that SMTP is a + 7-bit channel, but revert to 8-bit should it advertise + that it supports 8BITMIME. You still have to specify + mailer flag 7 to get this stripping at all. + Improve makesendmail script so it handles more cases automatically. + Tighten up restrictions on taking ownership of :include: files + to avoid problems on systems that allow you to give away + files. + Fix a problem that made it impossible to rebuild the alias + file if it was on a read-only file system. From + Harry Edmon of the University of Washington. + Improve MX randomization function. From John Gardiner Myers + of CMU. + Fix a minor glitch causing a bogus message to be printed (used + %s instead of %d in a printf string for the line number) + when a bad queue file was read. From Harry Edmon. + Allow $s to remain NULL on locally generated mail. I'm not + sure this is necessary, but a lot of people have complained + about it, and there is a legitimate question as to whether + "localhost" is legal as an 822-style domain. + Fix a problem with very short line lengths (mailer L= flag) in + headers. This causes a leading space to be added onto + continuation lines (including in the body!), and also + tries to wrap headers containing addresses (From:, To:, + etc) intelligently at the shorter line lengths. Problem + Reported by Lars-Johan Liman of SUNET Operations Center. + Log the real user name when logging syserrs, since these can have + security implications. Suggested by several people. + Fix address logging of cached connections -- it used to always + log the numeric address as zero. This is a somewhat + bogus implementation in that it does an extra system + call, but it should be an inexpensive one. Fix from + Motonori Nakamura. + Tighten up handling of short syslog buffers even more -- there + were cases where the outgoing relay= name was too long + to share a line with delay= and mailer= logging. + Limit the overhead on split envelopes to one open file descriptor + per envelope -- previously the overhead was three + descriptors. This was in response to a problem reported + by P{r (Pell) Emanuelsson. + Fixes to better handle the case of unexpected connection closes; + this redirects the output to the transcript so the info + is not lost. From Eric Wassenaar. + Fix potential string overrun if you macro evaluate a string that + has a naked $ at the end. Problem noted by James Matheson + <jmrm@eng.cam.ac.uk>. + Make default error number on $#error messages 553 (``Requested + action not taken: mailbox name not allowed'') instead of + 501 (``Syntax error in parameters or arguments'') to + avoid bogus "protocol error" messages. + Strip off any existing trailing dot on names during $[ ... $] + lookup. This prevents it from ending up with two dots + on the end of dot terminated names. From Wesley Craig + of the University of Michigan and Bryan Costales of ICSI. + Clean up file class reading so that the debugging information is + more informative. It hadn't been using setclass, so you + didn't see the class items being added. + Avoid core dump if you are running a version of sendmail where + NIS is compiled in, and you specify an NIS map, but + NIS is not running. Fix from John Oleynick of + Rutgers. + Diagnose bizarre case where res_search returns a failure value, + but sets h_errno to a success value. + Make sure that "too many hops" messages are considered important + enough to send an error to the Postmaster (that is, the + address specified in the P option). This fix should + help problems that cause the df file to be left around + sometimes -- unfortunately, I can't seem to reproduce + the problem myself. + Avoid core dump (null pointer reference) on EXPN command; this + only occurred if your log level was set to 10 or higher + and the target account was an alias or had a .forward file. + Problem noted by Janne Himanka. + Avoid "denial of service" attacks by someone who is flooding your + SMTP port with bad commands by shutting the connection + after 25 bad commands are issued. From Kyle Jones of + UUNET. + Fix core dump on error messages with very long "to" buffers; + fmtmsg overflows the message buffer. Fixed by trimming + the to address to 203 characters. Problem reported by + John Oleynick. + Fix configuration for HASFLOCK -- there were some spots where + a #ifndef was incorrectly #ifdef. Pointed out by + George Baltz of the University of Maryland. + Fix a typo in savemail() that could cause the error message To: + lists to be incorrect in some places. From Motonori + Nakamura. + Fix a glitch that can cause duplicate error messages on split + envelopes where an address on one of the lists has a + name server failure. Fix from Voradesh Yenbut of the + University of Washington. + Fix possible bogus pointer reference on ESMTP parameters that + don't have an ``=value'' part. + CNAME loops caused an error message to be generated, but also + re-queued the message. Changed to just re-queue the + message (it's really hard to just bounce it because + of the wierd way the name server works in the presence + of CNAME loops). Problem noted by James M.R.Matheson + of Cambridge University. + Avoid giving ``warning: foo owned process doing -bs'' messages + if they use ``MAIL FROM:<foo>'' where foo is their true + user name. Suggested by Andreas Stolcke of ICSI. + Change the NAMED_BIND compile flag to be a 0/1 flag so you can + override it easily in the Makefile -- that is, you can + turn it off using -DNAMED_BIND=0. + If a gethostbyname(...) of an address with a trailing dot fails, + try it without the trailing dot. This is because if + you have a version of gethostbyname() that falls back + to NIS or the /etc/hosts file it will fail to find + perfectly reasonable names that just don't happen to + be dot terminated in the hosts file. You don't want to + strip the dot first though because we're trying to ensure + that country names that match one of your subdomains get + a chance. + PRALIASES: fix bogus output on non-null-terminated strings. + From Bill Gianopoulos of Raytheon. + CONFIG: Avoid rewriting anything that matches $w to be $j. + This was in code intended to only catch the self-literal + address (that is, [1.2.3.4], where 1.2.3.4 is your + IP address), but the code was broken. However, it will + still do this if $M is defined; this is necessary to + get client configurations to work (sigh). Note that this + means that $M overrides :mailname entries in the user + database! Problem noted by Paul Southworth. + CONFIG: Fix definition of Solaris help file location. From + Steve Cliffe <steve@gorgon.cs.uow.edu.au>. + CONFIG: Fix bug that broke news.group.USENET mappings. + CONFIG: Allow declaration of SMTP_MAILER_MAX, FAX_MAILER_MAX, + and USENET_MAILER_MAX to tweak the maximum message + size for various mailers. + CONFIG: Change definition of USENET_MAILER_ARGS to include argv[0] + instead of assuming that it is "inews" for consistency + with other mailers. From Michael Corrigan of UC San Diego. + CONFIG: When mail is forwarded to a LOCAL_RELAY or a MAIL_HUB, + qualify the address in the SMTP envelope as user@{relay|hub} + instead of user@$j. From Bill Wisner of The Well. + CONFIG: Fix route-addr syntax in nullrelay configuration set. + CONFIG: Don't turn off case mapping of user names in the local + mailer for IRIX. This was different than most every other + system. + CONFIG: Avoid infinite loops on certainly list:; syntaxes in + envelope. Noted by Thierry Besancon + <besancon@excalibur.ens.fr>. + CONFIG: Don't include -z by default on uux line -- most systems + don't want it set by default. Pointed out by Philippe + Michel of Thomson CSF. + CONFIG: Fix some bugs with mailertables -- for example, if your + host name was foo.bar.ray.com and you matched against + ".ray.com", the old implementation bound %1 to "bar" + instead of "foo.bar". Also, allow "." in the mailertable + to match anything -- essentially, take over SMART_HOST. + This also moves matching of explicit local host names + before the mailertable so they don't have to be special + cased in the mailertable data. Reported by Bill + Gianopoulos of Raytheon; the fix for the %1 binding + problem was contributed by Nicholas Comanos of the + University of Sydney. + CONFIG: Don't include "root" in class $=L (users to deliver + locally, even if a hub or relay exists) by default. + This is because of the known bug where definition of + both a LOCAL_RELAY and a MAIL_HUB causes $=L to ignore + both and deliver into the local mailbox. + CONFIG: Move up bitdomain and uudomain handling so that they + are done before .UUCP class matching; uudomain was + reported as ineffective before. This also frees up + diversion 8 for future use. Problem reported by Kimmo + Suominen. + CONFIG: Don't try to convert dotted IP address (e.g., [1.2.3.4]) + into host names. As pointed out by Jonathan Kamens, + these are often used because either the forward or reverse + mapping is broken; this translation makes it broken again. + DOC: Clarify $@ and $: in the Install & Op Guide. From Kimmo + Suominen. + Portability fixes: + Unicos from David L. Kensiski of Sterling Sofware. + DomainOS from Don Lewis of Silicon Systems. + GNU m4 1.0.3 from Karst Koymans of Utrecht University. + Convex from Kimmo Suominen <kim@tac.nyc.ny.us>. + NetBSD from Adam Glass <glass@sun-lamp.cs.berkeley.edu>. + BSD/386 from Tony Sanders of BSDI. + Apollo from Eric Wassenaar. + DGUX from Doug Anderson. + Sequent DYNIX/ptx 2.0 from Tim Wright of Sequent. + NEW FILES: + src/Makefile.DomainOS + src/Makefile.PTX + src/Makefile.SunOS.5.1 + src/Makefile.SunOS.5.2 + src/Makefile.SunOS.5.x + src/mailq.1 + cf/ostype/domainos.m4 + doc/op/Makefile + doc/intro/Makefile + doc/usenix/Makefile + +8.6.5/8.6.5 94/01/13 + Security fix: /.forward could be owned by anyone (the test + to allow root to own any file was backwards). From + Bob Campbell at U.C. Berkeley. + Security fix: group ids were not completely set when programs + were invoked. This caused programs to have group + permissions they should not have had (usually group + daemon instead of their own group). In particular, + Perl scripts would refuse to run. + Security: check to make sure files that are written are not + symbolic links (at least under some circumstances). + Although this does not respond to a specific known + attack, it's just a good idea. Suggested by + Christian Wettergren. + Security fix: if a user had an NFS mounted home directory on + a system with a restricted shell listed in their + /etc/passwd entry, they could still execute any + program by putting that in their .forward file. + This fix prevents that by insisting that their shell + appear in /etc/shells before allowing a .forward to + execute a program or write a file. You can disable + this by putting "*" in /etc/shells. It also won't + permit world-writable :include: files to reference + programs or files (there's no way to disable this). + These behaviours are only one level deep -- for + example, it is legal for a world-writable :include: + file to reference an alias that writes a file, on + the assumption that the alias file is well controlled. + Security fix: root was not treated suspiciously enough when + looking into subdirectories. This would potentially + allow a cracker to examine files that were publically + readable but in a non-publically searchable directory. + Fix a problem that causes an error on QUIT on a cached + connection to create problems on the current job. + These are typically unrelated, so errors occur in + the wrong place. + Reset CurrentLA in sendall() -- this makes sendmail queue + runs more responsive to load average, and fixes a + problem that ignored the load average in locally + generated mail. From Eric Wassenaar. + Fix possible core dump on aliases with null LHS. From + John Orthoefer of BB&N. + Revert to using flock() whenever possible -- there are just + too many bugs in fcntl() locking, particularly over + NFS, that cause sendmail to fail in perverse ways. + Fix a bug that causes the connection cache to get confused + when sending error messages. This resulted in + "unexpected close" messages. It should fix itself + on the following queue run. Problem noted by + Liudvikas Bukys of the University of Rochester. + Include $k in $=k as documented in the Install & Op Guide. + This seems odd, but it was documented.... From + Michael Corrigan of UCSD. + Fix problem that caused :include:s from alias files to be + forced to be owned by root instead of daemon + (actually DefUid). From Tim Irvin. + Diagnose unrecognized I option values -- from Mortin Forssen + of the Chalmers University of Technology. + Make "error" mailer work consistently when there is no error + code associated with it -- previously it returned OK + even though there was a real problem. Now it assumes + EX_UNAVAILABLE. + Fix bug that caused the last header line of messages that had + no body and which were terminated with EOF instead of + "." to be discarded. Problem noted by Liudvikas Bukys. + Fix core dump on SMTP mail to programs that failed -- it tried + to go to a "next MX host" when none existed, causing + a core dump. From der Mouse at McGill University. + Change IDENTPROTO from a defined/not defined to a 0/1 switch; + this makes it easier to turn it off (using + -DIDENTPROTO=0 in the Makefile). From der Mouse. + Fix YP_MASTER_NAME store to use the unupdated result of + gethostname() (instead of myhostname(), which tries + to fully qualify the name) to be consistent with + SunOS. If your hostname is unqualified, this fixes + transfers to slave servers. Bug noted by Keith + McMillan of Ameritech Services, Inc. + Fix Ultrix problem: gethostbyname() can return a very large + (> 500) h_length field, which causes the sockaddr + to be trashed. Use the size of the sockaddr instead. + Fix from Bob Manson of Ohio State. + Don't assume "-a." on host lookups if NAMED_BIND is not + defined -- this confuses gethostbyname on hosts + file lookups, which doesn't understand the trailing + dot convention. + Log SMTP server subprocesses that die with a signal instead + of from a clean exit. + If you don't have option "I" set, don't assume that a DNS + "host unknown" message is authoritative -- it + might still be found in /etc/hosts. + Fix a problem that would cause Deferred: messages to be sent + as the subject of an error message, even though the + actual cause of a message was more severe than that. + Problem noted by Chris Seabrook of OSSI. + Fix race condition in DBM alias file locking. From Kyle + Jones of UUNET. + Limit delivery syslog line length to avoid bugs in some + versions of syslog(3). This adds a new compile time + variable SYSLOG_BUFSIZE. From Jay Plett of Princeton + University, which is in turn derived from IDA. + Fix quotes inside of comments in addresses -- previously + it insisted that they be balanced, but the 822 spec + says that they should be ignored. + Dump open file state to syslog upon receiving SIGUSR1 (for + debugging). This also evaluates ruleset 89, if set + (with the null input), and logs the result. This + should be used sparingly, since the rewrite process + is not reentrant. + Change -qI, -qR, and -qS flags to be case-insensitive as + documented in the Bat Book. + If the mailer returned EX_IOERR or EX_OSERR, sendmail did not + return an error message and did not requeue the message. + Fix based on code from Roland Dirlewanger of + Reseau Regional Aquarel, Bordeaux, France. + Fix a problem that caused a seg fault if you got a 421 error + code during some parts of connection initialization. + I've only seen this when talking to buggy mailers on + the other end, but it shouldn't give a seg fault in + any case. From Amir Plivatsky. + Fix core dump caused by a ruleset call that returns null. + Fix from Bryan Costales of ICSI. + Full-Name: field was being ignored. Fix from Motonori Nakamura + of Kyoto University. + Fix a possible problem with very long input lines in setproctitle. + From P{r Emanuelsson. + Avoid putting "This is a warning message" out on return receipts. + Suggested by Douglas Anderson. + Detect loops caused by recursive ruleset calls. Suggested by + Bryan Costales. + Initialize non-alias maps during alias rebuilds -- they may be + needed for parsing. Problem noted by Douglas Anderson. + Log sender address even if no message was collected in SMTP + (e.g., if all RCPTs failed). Suggested by Motonori + Nakamura. + Don't reflect the owner-list contents into the envelope sender + address if the value contains ", :, /, or | (to avoid + illegal addresses appearing there). + Efficiency hack for toktype macro -- from Craig Partridge of + BB&N. + Clean up DNS error printing so that a host name is always + included. + Remember to set $i during queue runs. Reported by Stephen + Campbell of Dartmouth University. + If the environment variable HOSTALIASES is set, use it during + canonification as the name of a file with per-user host + translations so that headers are properly mapped. Reported + by Anne Bennett of Concordia University. + Avoid printing misleading error message if SMTP mailer (not + using [IPC]) should die on a core dump. + Avoid incorrect diagnosis of "file 1 closed" when it is caused + by the other end closing the connection. From + Dave Morrison of Oracle. + Improve several of the error messages printed by "mailq" + to include a host name or other useful information. + Add NetInfo preliminary support for NeXT systems. From Vince + DeMarco. + Fix a glitch that sometimes caused :include:s that pointed to + NFS filesystems that were down to give an "aliasing/ + forwarding loop broken" message instead of queueing + the message for retry. Noted by William C Fenner of + the NRL Connection Machine Facility. + Fix a problem that could cause a core dump if the input sequence + had (or somehow acquired) a \231 character. + Make sure that route-addrs always have <angle brackets> around + them in non-SMTP envelopes (SMTP envelopes already do + this properly). + Avoid wierd headers on unbalanced punctuation of the form: + ``Joe User <user)'' -- this caused reference to the + null macro. Fix from Rick McCarty of IO.COM. + Fix a problem that caused an alias "user: user@local.host" to + not have the QNOTREMOTE bit set; this caused configs + to act as if FEATURE(notsticky) was defined even when + it was not. The effect of the problem was to make it + very hard to to set up satellite sites that had a few + local accounts, with everything else forwarded to a + corporate hub. Reported by Detlef Drewanz of the + University of Rostock and Mark Frost of NCD. + Change queuing to not call rulesets 3, {1 or 2}, 4 on header + addresses. This is more efficient (fewer name server + calls) and fixes certain unusual configurations, such + as those that have ruleset 4 do something that is + non-idempotent unless a mailer-specific ruleset did + something else. Problem reported by Brian J. Coan + of the Institute for Global Communications. + Fix the "obsolete argument" routine in main to better understand + new arguments. For example, if you used ``sendmail + -C config -v -q'' it would choke on the -q because + the -C would stop looking for old-format arguments. + Fix the code that was intended to allow two users to forward their + mail to the same program and have them appear unique. + Portability fixes for: + SCO UNIX from Murray Kucherawy. + SCO Open Server 3.2v4 from Philippe Brand. + System V Release 4 from Rick Ellis and others. + OSF/1 from Steve Campbell. + DG/UX from Ben Mesander of the USGS and Bryan Curnutt + of Stoner Associates. + Motorola SysV88 from Kevin Johnson of Motorola. + Solaris 2.3 from Casper H.S. Dik of the University + of Amsterdam and John Caruso of University + of Maryland. + FreeBSD from Ollivier Robert. + NetBSD from Adam Glass. + TitanOS from Kate Hedstrom of Rutgers University. + Irix from Bryan Curnutt. + Dynix from Jim Davis of the University of Arizona. + RISC/os. + Linux from John Kennedy of California State University + at Chico. + Solaris 2.x from Tony Boner of the U.S. Air Force. + NEXTSTEP 3.x from Vince DeMarco. + HP-UX from various people. NOTA BENE: the location + of the config file has moved to /usr/lib + to match the HP-UX version of sendmail. + CONFIG: Don't do any recipient rewriting on relay mailer; + since this is intended only for internal use, the + usual RFC 821/822/1123 rules can be relaxed. The + main point of this is to avoid munging (ugh) UUCP + addresses when relaying internally. + CONFIG: fix typo in mailer/uucp.m4 that mutilates list:; + syntax addresses delivered via UUCP. Solution + provided by Peter Wemm. + CONFIG: fix thumb-fumble in default UUCP relaying in ruleset + zero; it caused double @ signs in addresses. From + Irving Reid of the University of Toronto. + CONFIG: Portability fixes for SCO Unix 3.2 with TCP/IP 1.2.1 + from Markku Toijala of ICL Personal Systems Oy. + CONFIG: Add trailing "." on pseudo-domains for consistency; + this fixes a problem (noted by Al Whaley of Sunnyside) + that made it hard to recognize your own pseudodomain + names. + CONFIG: catch "@host" syntax errors (i.e., null local-parts) + rather than letting them get "local configuration + error"s. Problem noted by John Gardiner Myers. + CONFIG: add uucp-uudom mailer variant, based on code posted + by Spider Boardman <spider@Orb.Nashua.NH.US>; this + has uucp-dom semantics but old UUCP syntax. This + also permits "uucp-old" as an alias for "uucp" and + "uucp-new" as a synonym for "suucp" for consistency. + CONFIG: add POP mailer support (from Kimmo Suominen + <kim@grendel.lut.fi>). + CONFIG: drop CSNET_RELAY support -- CSNET is long gone. + CONFIG: fix bug caused with domain literal addresses (e.g., + ``[128.32.131.12]'') when FEATURE(allmasquerade) + was set; it would get an additional @masquerade.host + added to the address. Problem noted by Peter Wan + of Georgia Tech. + CONFIG: make sure that the local UUCP name is in $=w. From + Jim Murray of Stratus. + CONFIG: changes to UUCP rewriting to simulate IDA-style "V" + mailer flag. Briefly, if you are sending to host + "foo", then it rewrites "foo!...!baz" to "...!baz", + "foo!baz" remains "foo!baz", and anything else has + the local name prepended. + CONFIG: portability fixes for HP-UX. + DOC: several minor problems fixed in the Install & Op Guide. + MAKEMAP: fix core dump problem on lines that are too long or + which lack newline. From Mark Delany. + MAILSTATS: print sums of columns (total messages & kbytes + in and out of the system). From Tom Ferrin of UC + San Francisco Computer Graphics Lab. + SIGNIFICANT USER- OR SYSAD-VISIBLE CHANGES: + On HP-UX, /etc/sendmail.cf has been moved to + /usr/lib/sendmail.cf to match HP sendmail. + Permissions have been tightened up on world-writable + :include: files and accounts that have shells + that are not listed in /etc/shells. This may + cause some .forward files that have worked + before to start failing. + SIGUSR1 dumps some state to the log. + NEW FILES: + src/Makefile.DGUX + src/Makefile.Dynix + src/Makefile.FreeBSD + src/Makefile.Mach386 + src/Makefile.NetBSD + src/Makefile.RISCos + src/Makefile.SCO + src/Makefile.SVR4 + src/Makefile.Titan + cf/mailer/pop.m4 + cf/ostype/bsdi1.0.m4 + cf/ostype/dgux.m4 + cf/ostype/dynix3.2.m4 + cf/ostype/sco3.2.m4 + makemap/Makefile.dist + praliases/Makefile.dist + +8.6.4/8.6.4 93/10/31 + Repair core-dump problem (write to read-only memory segment) + if you fall back to the return-to-Postmaster case in + savemail. Problem reported by Richard Liu. + Immediately diagnose bogus sender addresses in SMTP. This + makes quite certain that crackers can't use this + class of attack. + Reliability Fix: check return value from fclose() and fsync() + in a few critical places. + Minor problem in initsys() that reversed a condition for + redirecting the output channel on queue runs. It's + not clear this code even does anything. From Eric + Wassenaar of the Dutch National Institute for Nuclear + and High-Energy Physics. + Fix some problems that caused queue runs to do "too much work", + such as double-reading the Errors-To: header. From + Eric Wassenaar. + Error messages on writing the temporary file (including the + data file) were getting suppressed in SMTP -- this + fix causes them to be properly reported. From Eric + Wassenaar. + Some changes to support AF_UNIX sockets -- this will only + really become relevant in the next release, but some + people need it for local patches. From Michael + Corrigan of UC San Diego. + Use dynamically allocated memory (instead of static buffers) + for macros defined in initsys() and settime(); since + these can have different values depending on which + envelope they are in. From Eric Wassenaar. + Improve logging to show ctladdr on to= logging; this tells you + what uid/gid processes ran as. + Fix a problem that caused error messages to be discarded if + the sender address was unparseable for some reason; + this was supposed to fall back to the "return to + postmaster" case. + Improve aliaswait backoff algorithm. + Portability patches for Linux (8.6.3 required another header + file) (from Karl London) and SCO UNIX. + CONFIG: patch prog mailer to not strip host name off of envelope + addresses (so that it matches local again). From + Christopher Davis. + CONFIG: change uucp-dom mailer so that "<>" translates to $n; + this prevents uux from seeing lines with null names like + ``From Sat Oct 30 14:55:31 1993''. From Motonori + Nakamura of Kyoto University. + CONFIG: handle <list:;> syntax correctly. This isn't legal, but + it shouldn't fail miserably. From Motonori Nakamura. + +8.6.2/8.6.2 93/10/15 + Put a "successful delivery" message in the transcript for + addresses that get return-receipts. + Put a prominent "this is only a warning" message in warning + messages -- some people don't read carefully enough + and end up sending the message several times. + Include reason for temporary failure in the "warning" return + message. Currently, it just says "cannot send for + four hours". + Fix the "Original message received" time generated for + returntosender messages. It was previously listed as + the current time. Bug reported by Eric Hagberg of + Cornell University Medical College. + If there is an error when writing the body of a message, + don't send the trailing dot and wait for a response + in sender SMTP, as this could cause the connection to + hang up under some bizarre circumstances. From Eric + Wassenaar. + Fix some server SMTP synchronization problems caused when + connections fail during message collection. From + Eric Wassenaar. + Fix a problem that can cause srvrsmtp to reject mail if the + name server is down -- it accepts the RCPT but rejects + the DATA command. Problem reported by Jim Murray of + Stratus. + Fix a problem that can cause core dumps if the config file + incorrectly resolves to a null hostname. Reported by + Allan Johannesen of WPI. + Non-root use of -C flag, dangerous -f flags, and use of -oQ + by non-root users were not put into + X-Authentication-Warning:s as intended because the + config file hadn't set the PrivacyFlags yet. Fix + from Sven-Ove Westberg of the University of Lulea. + Under very odd circumstances, the alias file rebuild code + could get confused as to whether a database was + open or not. + Check "vendor code" on the end of V lines -- this is + intended to provide a hook for vendor-specific + configuration syntax. (This is a "new feature", + but I've made an exception to my rule in a belief + that this is a highly exceptional case.) + Portability fixes for DG/UX (from Douglas Anderson of NCSC), + SCO Unix (from Murray Kucherawy), A/UX, and OSF/1 + (from Jon Forrest of UC Berkeley) + CONFIG: fix ``mailer:host'' form of UUCP relay naming. + +8.6.1/8.6 93/10/08 + Portability fixes for A/UX and Encore UMAX V. + Fix error message handling -- if you had a name server down + causing an error during parsing, that message was never + propogated to the queue file. + +8.6/8.6 93/10/05 + Configuration cleanup: make it easier to undo IDENTPROTO in + conf.h (other systems have the same bug). + If HASGETDTABLESIZE and _SC_OPEN_MAX are both defined, assume + getdtablesize() instead of sysconf(); a disturbingly + large number of systems defined _SC_OPEN_MAX in the + header files but don't have the syscall. + Another patch to really truly ignore MX records in getcanonname + if trymx == FALSE. + Fix problem that caused the "250 IAA25499 Message accepted for + delivery" message to be omitted if there was an error + in the header of the message (e.g., a bad Errors-To: + line). Pointed out by Michael Corrigan of UCSD. + Announce name of host we are chatting when we get errors; this + is an IDA-ism suggested by Christophe Wolfhugel. + Portability fixes for Alpha OSF/1 (from Anthony Baxter of the + Australian Artificial Intelligence Institute), SCO Unix + (from Murray Kucherawy of Hookup Communication Corp.), + NeXT (from Vince DeMarco and myself), Linux (from + Karl London <karl@borg.demon.co.uk>), BSDI (from + Christophe Wolfhugel, and SVR4 on Dell (from Kimmo + Suominen), AUX 3.0 on Macintosh, and ANSI C compilers. + Some changes to get around gcc optimizer bugs. From Takahiro + Kanbe. + Fix error recovery in queueup if another tf file of the same + name already exists. Problem stumbled over by Bill + Wisner of The Well. + Output YP_MASTER_NAME and YP_LAST_MODIFIED without null bytes. + Problem noted by Keith McMillan of Ameritech Services. + Deal with group permissions properly when opening .forward and + :include: files. This relaxes the 8.1C restrictions + slightly more. This includes proper setting of groups + when reading :include: files, allowing you to read some + files that you should be able to read but have previously + been denied unless you owned them or they had "other" + read permission. + Make certain that $j is in $=w (after the .cf is read) so that + if the user is forced to override some silly system, + MX suppression will still work. + Fix a couple of efficiency problems where newstr was double- + calling expensive routines. In at least one case, it + wasn't guaranteed that they would always return the + same result. Problem noted by Christophe Wolfhugel. + Fix null pointer dereference in putoutmsg -- only on an error + condition from a non-SMTP mailer. From Motonori + Nakamura. + Macro expand "C" line class definitions before scanning so that + "CX $Z" works. + Fix problem that caused error message to be sent while still + trying to send the original message if the connection + is closed during a DATA command after getting an error + on an RCPT command (pretty obscure). Problem reported + by John Myers of CMU. + Fix reply to NOOP to be 250 instead of 200 -- this is a long + term bug. + Fix a nasty bug causing core dumps when returning the "warning: + cannot deliver for N hours -- will keep trying" message; + it only occurred if you had PostMasterCopy set and + only on some architectures. Although sendmail would + keep trying, it would send error messages on each + queue interval. This is an important fix. + Allow u and g options to take user and group names respectively. + Don't do a chdir into the queue directory in -bt mode to make + ruleset testing a bit easier. + Don't allow users to turn off logging (using -oL) on the command + line -- command line can only raise, not lower, logging + level. + Set $u to the original recipient on the SMTP transaction or on + the command line. This is only done if there is exactly + one recipient. Technically, this does not meet the + specs, because it does not guarantee a domain on the + address. + Fix a problem that dumped error messages on bad addresses if + you used the -t flag. Problem noted by Josh Smith of + Harvey Mudd College. + Given an address such as ``<foo> <bar>'', auto-quote the first + ``<foo>'' part, giving ``"<foo>" <bar>''. This is to + avoid the problem of people who use angle brackets in + their full name information. + Fix a null pointer dereference if you set option "l", have + an Errors-To: header in the message, and have Errors-To: + defined in the config file H lines. From J.R. Oldroyd. + Put YPCOMPAT on #ifdef NIS instead -- it's one less thing to get + wrong when compiling. Suggested by Rick McCarty of TI. + Fix a problem that could pass negative SIZE parameter if the + df file got lost; this would cause servers to always + give a temporary failure, making the problem even worse. + Problem noted by Allan Johannesen of WPI. + Add "ident" timeout (one of the "r" option selectors) for IDENT + protocol timeouts (30s default). Requested by Murray + Kucherawy of HookUp Communication Corp. to handle bogus + PC TCP/IP implementations. + Change $w default definition to be just the first component of + the domain name on config level 5. The $j macro defaults + to the FQDN; $m remains as before. This lets well-behaved + config files use any of the short, long, or subdomain + names. + Add makesendmail script in src to try to automate multi-architecture + builds. I know, this is sub-optimal, but it is still + helpful. + Fix very obscure race condition that can cause a queue run to + get a queue file for an already completed job. This + problem has existed for years. Problem noted by the + long suffering Allan Johannesen of WPI. + Fix a problem that caused the raw sender name to be passed to + udbsender instead of the canonified name -- this caused + it to sometimes miss records that it should have found. + Relax check of name on HELO packet so that a program using -bs + that claims to be itself works properly. + Restore rewriting of $: part of address through 2, R, 4 in + buildaddr -- this requires passing a lot of flags to get + it right. Unlike old versions, this ONLY rewrites + recipient addresses, not sender addresses. + Fix a bug that caused core dumps in config files that cannot + resolve /file/name style addresses. Fix from Jonathan + Kamens of OpenVision Technologies. + Fix problem with fcntl locking that can cause error returns to + be lost if the lock is lost; this required fully + queueing everything, dropping the envelope (so errors + would get returned), and then re-reading the queue from + scratch. + Fix a problem that caused aliases that redefine an otherwise + true address to still send to the original address + if and only if the alias failed in certain bizarre + ways (e.g, if they pointed at a list:; syntax address). + Problem pointed out by Jonathan Kamens. + Remove support for frozen configuration files. They caused + more trouble than it was worth. + Fix problem that can cause error messages to get ignored when + using both -odb and -t flags. Problem noted by Rob + McNicholas at U.C. Berkeley. + Include all "normal" variations on hostname in $=w. For example, + if the host name is vangogh.cs.berkeley.edu, $=w will + contain vangogh, vangogh.cs, and vangogh.cs.berkeley.edu. + Add "restrictqrun" privacy flag -- without this, anyone can run + the queue. + Reset SmtpPhase global on initial connection creation so that + messages don't come out with stale information. + Pass an "ext" argument to lockfile so that error/log messages + will properly reflect the true filename being locked. + Put all [...] address forms into $=w -- this eliminates the need + for MAXIPADDR in conf.h. Suggested by John Gardiner + Myers of CMU. + Fix a bug that can cause qf files to be left around even after + an SMTP RSET command. Problem and fix from Michael + Corrigan. + Don't send a PostMasterCopy to errors when the Precedence: is + negative. Error reports still go to the envelope + sender address. + Add LA_SHORT for load averages. + Lock sendmail.st file when posting statistics. + Add "SendBufSize" and "RcvBufSize" suboptions to "O" option to + set the size of the TCP send and receive buffers; if you + run over a slow slip line you may need to set these down + (although it would be better to fix the SLIP implementation + so that it's not necessary to recompile every program + that does bulk data transfer). + Allow null defaults on $( ... $) lookups. Problem reported by + Amir Plivatsky. + Diagnose crufty S and V config lines. This resulted from an + observation that some people were using the SITE macro + without the SITECONFIG macro first, which was causing + bogus config files that were not caught. + Fix makemap -f flag to turn off case folding (it was turning it + on instead). THIS IS A USER VISIBLE CHANGE!!! + Fix a problem that caused multiple error messages to be sent if + you used "sendmail -t -oem -odb", your system uses fcntl + locking, and one of the recipient addresses is unknown. + Reset uid earlier in include() so that recursive .forwards or + :include:s don't use the wrong uid. + If file descriptor 0, 1, or 2 was closed when sendmail was + called, the code to recover the descriptor was broken. + This sometimes (only sometimes) caused problems with the + alias file. Fix from Motonori Nakamura. + Fix a problem that caused aliaswait to go into infinite recursion + if the @:@ metasymbol wasn't found in the alias file. + Improve error message on newaliases if database files cannot be + opened or if running with no database format defined. + Do a better estimation of the size of error messages when NoReturn + is set. Problem noted by P{r (Pell) Emanuelsson. + Fix a problem causing the "c" option (don't connect to expensive + mailers) to be ignored in SMTP. Problem noted and the + solution suggested by Robert Elz of Munnari University. + Improve connection caching algorithm by passing "[host]" to + hostsignature, which strips the square brackets and + returns the real name. This allows mailertable entries + to match regular entries. + Re-enable Return-Receipt-To: -- people seem to want this stupid + feature, even if it doesn't work right. + Catch and log attempts to try the "wiz" command in server SMTP. + This also ups the log level from LOG_NOTICE to LOG_CRIT. + Be more generous at assigning $z to the home directory -- do this + for programs that are specified through a .forward file. + Fix from Andrew Chang of Sun Microsystems. + Always save a fatal error message in preference to a non-fatal + error message so that the "subject" line of return + messages is the best possible. + CONFIG: reduce the number of quotes needed to quote configuration + parameters with commas: two quotes should work now, e.g., + define(ALIAS_FILE, ``/etc/aliases,/etc/aliases.local''). + CONFIG: class $=Z is a set of UUCP hosts that use uucp-dom + connections (domain-ized UUCP). + CONFIG: fix bug in default maps (-o must be before database file + name). Pointed out by Christophe Wolfhugel. + CONFIG: add FEATURE(nodns) to state that we are not relying on + DNS. This would presumably be used in UUCP islands. + CONFIG: add OSTYPE(nextstep) and OSTYPE(linux). + CONFIG: log $u in Received: line. This is in technical violation + of the standards, since it doesn't guarantee a domain + on the address. + CONFIG: don't assume "m" in local mailer flags -- this means that + if you redefine LOCAL_MAILER_FLAGS you will have to include + the "m" flag should you want it. Apparently some Solaris 2.2 + installations can't handle multiple local recipients. + Problem noted by Josh Smith. + CONFIG: add confDOMAIN_NAME to set $j (if undefined, $j defaults). + CONFIG: change default version level from 4 to 5. + CONFIG: add FEATURE(nullclient) to create a config file that + forwards all mail to a hub without ever looking at the + addresses in any detail. + CONFIG: properly strip mailer: information off of relays when + used to change .BITNET form into %-hack form. + CONFIG: fix a problem that caused infinite loops if presented + with an address such as "!foo". + CONFIG: check for self literal (e.g., [128.32.131.12]) even if + the reverse "PTR" mapping is broken. There's a better + way to do this, but the change is fairly major and I + want to hold it for another release. Problem noted by + Bret Marquis. + +8.5/8.5 93/07/23 + Serious bug: if you used a command line recipient that was unknown + sendmail would not send a return message (it was treating + everything as though it had an SMTP-style client that + would do the return itself). Problem noted by Josh Smith. + Change "trymx" option in getcanonname() to ignore all MX data, + even during a T_ANY query. This actually didn't break + anything, because the only time you called getcanonname + with !trymx was if you already knew there were no MX + records, but it is somewhat cleaner. From Motonori + Nakamura. + Don't call getcanonname from getmxrr if you already know there + are no DNS records matching the name. + Fix a problem causing error messages to always include "The + original message was received ... from localhost". + The correct original host information is now included. + Previous change to cf/sh/makeinfo.sh doesn't port to Ultrix (their + version of "test" doesn't have the -x flag). Change it + to use -f instead. From John Myers. + CONFIG: 8.4 mistakenly set the default SMTP-style mailer to + esmtp -- it should be smtp. + CONFIG: send all relayed mail using confRELAY_MAILER (defaults + to "relay" (a variant of "smtp") if MAILER(smtp) is used, + else "suucp" if MAILER(uucp) is used, else "unknown"); + this cleans up the configs somewhat. This fixes a serious + problem that caused route-addrs to get mistaken as relays, + pointed out by John Myers. WARNING: this also causes + the default on SMART_HOST to change from "suucp" to + "relay" if you have MAILER(smtp) specified. + +8.4/8.4 93/07/22 + Add option `w'. If you receive a message that comes to you because + you are the best (lowest preference) target of an MX, and + you haven't explicitly recognized the source MX host in + your .cf file, this option will cause you to try the target + host directly (as if there were no MX for it at all). If + `w' is not set, this case is a configuration error. + Beware: if `w' is set, senders may get bogus errors like + "message timed out" or "host unknown" for problems that + are really configuration errors. This option is + disrecommended, provided only for compatibility with + UIUC sendmail. + Fix a problem that caused the incoming socket to be left open + when sendmail forks after the DATA command. This caused + calling systems to wait in FIN_WAIT_2 state until the + entire list was processed and the child closed -- a + potentially prodigious amount of time. Problem noted + by Neil Rickert. + Fix problem (created in 6.64) that caused mail sent to multiple + addresses, one of which was a bad address, to completely + suppress the sending of the message. This changes + handling of EF_FATALERRS somewhat, and adds an + EF_GLOBALERRS flag. This also fixes a potential problem + with duplicate error messages if there is a syntax error + in the header of a message that isn't noticed until late + in processing. Original problem pointed out by Josh Smith + of Harvey Mudd College. This release includes quite a bit + of dickering with error handling (see below). + Back out SMTP transaction if MAIL gets nested 501 error. This + will only hurt already-broken software and should help + humans. + Fix a problem that broke aliases when neither NDBM nor NEWDB were + compiled in. It would never read the alias file. + Repair unbalanced `)' and `>' (the "open" versions are already + repaired). + Logging of "done" in dropenvelope() was incorrect: it would + log this even when the queue file still existed. Change + this to only log "done" (at log level 11) when the + queue file is actually removed. From John Myers. + Log "lost connection" in server SMTP at log level 20 if there + is no pending transaction. Some senders just close the + connection rather than sending QUIT. + Fix a bug causing getmxrr to add a dot to the end of unqualified + domains that do not have MX records -- this would cause + the subsequent host name lookup to fail. The problem + only occurred if you had FEATURE(nocanonify) set. + Problem noted by Rick McCarty of Texas Instruments. + Fix invocation of setvbuf when passed a -X flag -- I had + unwittingly used an ANSI C extension, and this caused + core dumps on some machines. + Diagnose self-destructive alias loops on RCPT as well as EXPN. + Previously it just gave an empty send queue, which + then gave either "Need RCPT (recipient)" at the DATA + (confusing, since you had given an RCPT command which + returned 250) or just dropped the email, depending on + whether you were running VERBose mode. Now it usually + diagnoses this case as "aliasing/forwarding loop broken". + Unfortunately, it still doesn't adequately diagnose + some true error conditions. + Add internal concept of "warning messages" using 6xx codes. + These are not reported only to Postmaster. Unbalanced + parens, brackets, and quotes are printed as 653 codes. + They are always mapped to 5xx codes before use in SMTP. + Clean up error messages to tell both the actual address that + failed and the alias they arose from. This makes it + somewhat easier to diagnose problems. Difficulty noted + by Motonori Nakamura. + Fix a problem that inappropriately added a ctladdr to addresses + that shouldn't have had one during a queue run. This + caused error messages to be handled differently during + a queue run than a direct run. + Don't print the qf name and line number if you get errors during + the direct run of the queue from srvrsmtp -- this was + just extra stuff for users to crawl through. + Put command line flags on second line of pid file so you can + auto-restart the daemon with all appropriate arguments. + Use "kill `head -1 /etc/sendmail.pid`" to stop the + daemon, and "eval `tail -1 /etc/sendmail.pid`" to + restart it. + Remove the ``setuid(getuid())'' in main -- this caused the + IDENT daemon to screw up. This required that I change + HASSETEUID to HASSETREUID and complicate the mode + changing somewhat because both Ultrix and SunOS seem + to have a bug causing seteuid() to set the saved uid + as well as the effective. The program test/t_setreuid.c + will test to see if your implementation of setreuid(2) + is appropriately functional. + The FallBackMX (option V) handling failed to properly identify + fallback to yourself -- most of the code was there, + but it wasn't being enabled. Problem noted by Murray + Kucherawy of the University of Waterloo. + Change :include: open timeout from ETIMEDOUT to an internal + code EOPENTIMEOUT; this avoids adding "during SmtpPhase + with CurHostName" in error messages, which can be + confusing. Reported by Jonathan Kamens of OpenVision + Technologies. + Back out setpgrp (setpgid on POSIX systems) call to reset the + process group id. The original fix was to get around + some problems with recalcitrant MUAs, but it breaks + any call from a shell that creates a process group id + different from the process id. I could try to fix + this by diddling the tty owner (using tcsetpgrp or + equivalent) but this is too likely to break other + things. + Portability changes: + Support -M as equivalent to -oM on Ultrix -- apparently + DECnet calls sendmail with -MrDECnet -Ms<HOST> -bs + instead of using standard flags. Oh joy. This + behaviour reported by Jon Giltner of University + of Colorado. + SGI IRIX -- this includes several changes that should + help other strict ANSI compilers. + SCO Unix -- from Murray Kucherawy of HookUp Communication + Corporation. + Solaris running the Sun C compiler (which despite the + documentation apparently doesn't define + __STDC__ by default). + ConvexOS from Eric Schnoebelen of Convex. + Sony NEWS workstations and Omron LUNA workstations from + Motonori Nakamura. + CONFIG: add confTRY_NULL_MX_LIST to set option `w'. + CONFIG: delete `C' and `e' from default SMTP mailers flags; + several people have made a good argument that this + creates more problems than it solves (although this + may prove painful in the short run). + CONFIG: generalize all the relays to accept a "mailer:host" + format. + CONFIG: move local processing in ruleset 0 into a new ruleset + 98 (8 on old sendmail). Domain literal [a.b.c.d] + addresses are also passed through this ruleset. + CONFIG: if neither SMART_HOST nor MAILER(smtp) were defined, + internet-style addresses would "fall off the end" of + ruleset zero and be interpreted as local -- however, + the angle brackets confused the recursive call. + These are now diagnosed as "Unrecognized host name". + CONFIG: USENET rules weren't included in S0 because of a mistaken + ifdef(`_MAILER_USENET_') instead of + ifdef(`_MAILER_usenet_'). Problem found by Rein Tollevik + of SINTEF RUNIT, Oslo. + CONFIG: move up LOCAL_RULE_0 processing so that it happens very + early in ruleset 0; this allows .mc authors to bypass + things like the "short circuit" code for local addresses. + Prompted by a comment by Bill Wisner of The Well. + CONFIG: add confSMTP_MAILER to define the mailer used (smtp or + esmtp) to send SMTP mail. This allows you to default + to esmtp but use a mailertable or other override to + deal with broken servers. This logic was pointed out + to me by Bill Wisner. Ditto for confLOCAL_MAILER. + Changes to cf/sh/makeinfo.sh to make it portable to SVR4 + environments. Ugly as sin. + +8.3/8.3 93/07/13 + Fix setuid problems introduced in 8.2 that caused messages + like "Cannot create qfXXXXXX: Invalid argument" + or "Cannot reopen dfXXXXXX: Permission denied". This + involved a new compile flag "HASSETEUID" that takes + the place of the old _POSIX_SAVED_IDS -- it turns out + that the POSIX interface is broken enough to break + some systems badly. This includes some fixes for + HP-UX. Also fixes problems where the real uid is + not reset properly on startup (from Neil Rickert). + Fix a problem that caused timed out messages to not report the + addresses that timed out. Error messages are also more + "user friendly". + Drop required bandwidth on connections from 64 bytes/sec to + 16 bytes/sec. + Further Solaris portability changes -- doesn't require the BSD + compatibility library. This also adds a new + "HASGETDTABLESIZE" compile flag which can be used if + you want to use getdtablesize(2) instead of sysconf(2). + These are loosely based on changes from David Meyer at + University of Oregon. This now seems to work, at least + for quick test cases. + Fix a problem that can cause duplicate error messages to be + sent if you are in SMTP, you send to multiple addresses, + and at least one of those addresses is good and points + to an account that has a .forward file (whew!). + Fix a problem causing messages to be discarded if checkcompat() + returned EX_TEMPFAIL (because it didn't properly mark + the "to" address). Problem noted by John Myers. + Fix dfopen to return NULL if the open failed; I was depending + on fdopen(-1) returning NULL, which isn't the case. This + isn't serious, but does result in wierd error diagnoses. + From Michael Corrigan. + CONFIG: add UUCP_MAX_SIZE M4 macro to set the maximum size of + messages sent through UUCP-family mailers. Suggested + by Bill Wisner of The Well. + CONFIG: if both MAILER(uucp) and MAILER(smtp) are specified, + include a "uucp-dom" mailer that uses domain-style + addressing. Suggested by Bill Wisner. + CONFIG: Add LOCAL_SHELL_FLAGS and LOCAL_SHELL_ARGS to match + LOCAL_MAILER_FLAGS and LOCAL_MAILER_ARGS. Suggested by + Christophe Wolfhugel. + CONFIG: Add OSTYPE(aix3). From Christophe Wolfhugel. + +8.2/8.2 93/07/11 + Don't drop out on config file parse errors in -bt mode. + On older configuration files, assume option "l" (use Errors-To + header) for back compatibility. NOTE: this DOES NOT + imply an endorsement of the Errors-To: header in any way. + Accept -x flag on AIX-3 as well as OSF/1. Why, why, why??? + Don't log errors on EHLO -- it isn't a "real" error for an old + SMTP server to give an error on this command, and + logging it in the transcript can be confusing. Fix + from Bill Wisner. + IRIX compatibility changes provided by Dan Rich + <drich@sandman.lerc.nasa.gov>. + Solaris 2 compatibility changes. Provided by Bob Cunningham + <bob@kahala.soest.hawaii.edu>, John Oleynick + <juo@klinzhai.rutgers.edu> + Debugging: -d17 was overloaded (hostsignature and usersmtp.c); + move usersmtp (smtpinit and smtpmailfrom) to -d18 to + match the other flags in that file. + Flush transcript before fork in mailfile(). From Eric Wassenaar. + Save h_errno in mci struct and improve error message display. + Changes from Eric Wassenaar. + Open /dev/null for the transcript if the create of the xf file + failed; this avoids at least one possible null pointer + reference in very wierd cases. From Eric Wassenaar. + Clean up statistics gathering; it was over-reporting because of + forks. From Eric Wassenaar. + Fix problem that causes old Return-Path: line to override new + Return-Path: line (conf.c needs H_FORCE to avoid + re-using old value). From Motonori Nakamura. + Fix broken -m flag in K definition -- even if -m (match only) + was specified, it would still replace the key with the + value. Noted by Rick McCarty of Texas Instruments. + If the name server timed out over several days, no "timed out" + message would ever be sent back. The timeout code + has been moved from markfailure() to dropenvelope() + so that all such failures should be diagnosted. Pointed + out by Christophe Wolfhugel and others. + Relax safefile() constraints: directories in an include or + forward path must be readable by self if the controlling + user owns the entry, readable by all otherwise (e.g., + when reading your .forward file, you have to own and + have X permssion in it; everyone needs X permission in + the root and directories leading up to your home); + include files must be readable by anyone, but need not + be owned by you. + If _POSIX_SAVED_IDS is defined, setuid to the owner before + reading a .forward file; this gets around some problems + on NFS mounts if root permission is not exported and + the user's home directory isn't x'able. + Additional NeXT portability enhancements from Axel Zinser. + Additional HP-UX portability enhancements from Brian Bullen. + Add a timeout around SMTP message writes; this assumes you can + get throughput of at least 64 bytes/second. Note that + this does not impact the "datafinal" default, which + is separate; this is just intended to work around + network clogs that will occur before the final dot + is sent. From Eric Wassenaar. + Change map code to set the "include null" flag adaptively -- + it initially tries both, but if it finds anything + matching without a null it never tries again with a + null and vice versa. If -N is specified, it never + tries without the null and creates new maps with a + null byte. If -O is specified, it never tries with + the null (for efficiency). If -N and -O are specified, + you get -NO (get it?) lookup at all, so this would + be a bad idea. If you don't specify either -N or -O, + it adapts. + Fix recognition of "same from address" so that MH submissions + will insert the appropriate full name information; + this used to work and got broken somewhere along the + way. + Some changes to eliminate some unnecessary SYSERRs in the + log. For example, if you lost a connection, don't + bother reporting that fact on the connection you lost. + Add some "extended debugging" flags to try to track down + why we get occassional problems with file descriptor + one being closed when execing a mailer; it seems to + only happen when there has been another error in the + same transaction. This requires XDEBUG, defined + by default in conf.h. + Add "-X filename" command line flag, which logs both sides of + all SMTP transactions. This is intended ONLY for + debugging bad implementations of other mailers; start + it up, send a message from a mailer that is failing, + and then kill it off and examine the indicated log. + This output is not intended to be particularly human + readable. This also adds the HASSETVBUF compile + flag, defaulted on if your compiler defines __STDC__. + CONFIG: change SMART_HOST to override an SMTP mailer. If you + have a local net that should get direct connects, you + will need to use LOCAL_NET_CONFIG to catch these hosts. + See cf/README for an example. + CONFIG: add LOCAL_MAILER_ARGS (default: `mail -d $u') to handle + sites that don't use the -d flag. + CONFIG: hide recipient addresses as well as sender addresses + behind $M if FEATURE(allmasquerade) is specified; this + has been requested by several people, but can break + local aliases. For example, if you mail to "localalias" + this will be rewritten as "localalias@masqueradehost"; + although initial delivery will work, replies will be + broken. Use it sparingly. + CONFIG: add FEATURE(domaintable). This maps unqualified domains + to qualified domains in headers. I believe this is + largely equivalent to the IDA feature of the same name. + CONFIG: use $U as UUCP name instead of $k. This permits you + to override the "system name" as your UUCP name -- + in particular, to use domain-ized UUCP names. From + Bill Wisner of The Well. + CONFIG: create new mailer "esmtp" that always tries EHLO + first. This is currently unused in the config files, + but could be used in a mailertable entry. + +8.1C/8.1B 93/06/27 + Serious security bug fix: it was possible to read any file on + the system, regardless of ownership and permissions. + If a subroutine returns a fully qualified address, return it + immediately instead of feeding it back into rewriting. + This fixes a problem with mailertable lookups. + CONFIG: fix some M4 frotz (concat => CONCAT) + +8.1B/8.1A 93/06/12 + Serious bug fix: pattern matching backup algorithm stepped by + two tokens in classes instead of one. Found by Claus + Assmann at University of Kiel, Germany. + +8.1A/8.1A 93/06/08 + Another mailertable fix.... + +8.1/8.1 93/06/07 + 4.4BSD freeze. No semantic changes. + +6.65/6.34 93/06/06 + Fix some lintish problems. + Fix some cases where server SMTP behaved poorly when handed bogus + input, pointed out by Eric Wassenaar. + CONFIG: fix some more (sigh) mailertable bugs -- thanks to + Motonori Nakamura of Kyoto University (again). + +6.64/6.33 93/06/05 + Don't send 050 (-v) information after the 250 response to a QUIT + command in srvrsmtp -- clients usually close the connection + at this point, and it causes bogus error messages. + Don't send messages that have errors on input (such as unbalanced + parentheses) during SMTP transactions, since a return + message has (probably) already been sent. + Give better diagnostics on timeouts during network reads, including + information similar to the SMTP phase. + Fix bug that caused SMTP messages to deliver synchronously; this + happened after the DATA 250, and hence caused reading the + next command to be delayed. + Ignore Errors-To: header unless 'l' (lower case el) header is + specified. The Errors-To: header violates RFC 1123. + Errors-To: was only needed to take the place of the + envelope sender in the days when most Unix mailers + didn't understand about the two kinds of senders. + Don't send warning messages in response to automatically generated + messages (that is, those From:<>). + CONFIG: fix some rather stupid typos in the mailertable code + pointed out by Motonori Nakamura of Kyoto University. + CONFIG: add confUSE_ERRORS_TO configuration option. + CONFIG: if ALWAYS_ADD_DOMAIN is selected, try to use $M + (masquerade name) instead of $j. + CONFIG: don't add dots to relay names (added in 6.29); it breaks + several things, and can be simulated by dot terminating + the names of relays. For example, use: + DBbit.net.relay. + (note the trailing dot). + +6.63/6.32 93/06/01 + Fix prototypes to eliminate chars in argument lists -- some + compilers are pissy about this. + Log protocol ($r) and body type if set so we can determine if + the adaptive algorithms are working. + Pessimize on locking of database files (particularly for NEWDB + databases) during opens. There were problems with + processes opening the file while it was rebuilt; since + NEWDB caches heavily, the reader opened an empty file, + which is an error. If your system has the ability to + lock atomically on open, this works properly; otherwise, + there are race conditions. + Check mod time on .pag file instead of .dir in NDBM aliases + because the .dir file doesn't get updated for small + alias files. From John Gardiner Myers of CMU. + More Solaris portability -- it now compiles on Solaris, but + hangs up in gethostbyname(). + Move setting of RES_DEBUG flag before first myhostname() call + so we can see name server traffic on that call. + Fsync() queue files. + Fix a problem that causes -bi to try to rebuild maps other than + the alias file(s). + Fix a problem that caused udb to reject entries from any but + the first database listed. + Rearrange doc subdirectory for 4.4BSD release tape. + CONFIG: put $r into the Received line. This was an oversight. + CONFIG: fix typo (call to ruleset 99 should have been rulset 90). + CONFIG: move "auxiliary" subroutines to be in ruleset 90-99 + range -- in the long run, single digit rulesets may + become reserved for builtin use by sendmail. + CONFIG: fix major problem that causes host aliases (that is, + anything in $=w != $j) to not be recognized. This has + been around since 6.30. + +6.62/6.31 93/05/28 + BETA RELEASE + Fix recursive syserr (if there is an error printing a syserr + message). This makes the code much less eager to consider + a write error as serious. This also includes some + heuristics to be clever about closed connections. + Lock NEWDB files during gets. This requires version 1.5 or later + of the db library. If you have an older version, you + can use -DOLD_NEWDB. This will go away in a few weeks. + Fix problem causing aliases that use host maps to get overwritten. + Do appropriate byte swapping on port numbers in ident protocol + code. Fix from Allan Johannesen of WPI. + Defer opening of map files to the same time as alias files so that + the daemon will tend to pick up new versions more promptly. + Prototype a bunch more functions. + Some Solaris 2.1 changes (still doesn't link though). + Try to simplify Makefiles by including more subordinate #defines + in conf.h (based on OS type). + CONFIG: check for domains if FEATURE(mailertable) is defined. + For example, if the host name is "knecht.cs.berkeley.edu" + it will search the following mailertable keys: + knecht.cs.berkeley.edu + .cs.berkeley.edu + .berkeley.edu + .edu + This could be used to replace the special relays for bitnet + and similar nets. + +6.61/6.30 93/05/24 + Fix problem that prevented appending dots on canonified host + names. This breaks tons of config files -- very + important fix. + Fix improper pointer dereference in response to HELO command. + Fix core dump if debugging set in map_rewrite. + CONFIG: add FEATURE(always_add_domain) to always attach the + local domain (only impacts local mail). + CONFIG: try to avoid turning names into $j -- although + technically a host can only have one "canonical name", + it seems to be common practice to have several. + +6.60/6.29 93/05/22 + Major change: merge alias databases with maps. This expands and + changes the map class interface but fixes a bunch of bugs. + The important user-visible change is that the file name + in a K line now does not include the ".db" extension; this + is added automatically. Also, the -d (NIS domain) flag is + missing from the K config line; use @domain instead. + When compiling, the *_MAP names are gone -- just compile + in NDBM, NEWDB, and/or NIS support. + Announce mailer/host/user triple on -bv flag -- from Brian + Bullen of Stirling University. + Don't send more than one line in response to HELO -- it confuses + Pony Express, which then behaves very badly. However, + this change does send two line 220 greetings, with the + second line reading "ESMTP spoken here". The usersmtp + module recognizes this and goes into ESMTP mode regardless + of the setting of the "a" mailer flag. Thus, "a" means + "always try EHLO". + AIX portability changes (thanks to Christophe Wolfhugel of + Herve Schauer Consultants (Paris) for providing me with + an INSA account for this purpose). Lightly tested. Use + -D_AIX3. This probably breaks compatibility with some + older systems (e.g., 4.2bsd) but still works on SunOS + 4.1.2, Ultrix 4.2A, HP-UX 8.07, OSF/1 T1.3, and AIX 3.2.3. + Fix a problem causing an error message loop if the output channel + is hosed. + Add the Makefiles that I use for various environments -- some are + Berkeley make versions and some are old make versions. + My makefile for the NeXT box has gotten lost, alas! + PRALIASES: support for printing NEWDB databases. From + Michael J. Corrigan of U.C. San Diego. + CONFIG: don't pass pseudo-domains to $[ ... $] (if you have + a wildcard MX it can have wierd results). From + Christophe Wolfhugel. + CONFIG: dot terminate relay hostnames in S0. From Christophe + Wolfhugel. + +6.59/6.28 93/05/13 + Log version with SMTP daemon startup message. + Adjust setproctitle to work on NetBSD and BSD/386. + Fix null pointer reference in MX fallback code. + A bunch of minor fixes from Eric Wassenaar: + If deliver cannot execv the mailer, return EX_OSERR + instead of EX_TEMPFAIL (to give better + error messages). + Consistently malloc e_message. + Catch degenerate case of calling returntosender() + with an empty returnq. + MIME reformatting. + +6.58/6.28 93/05/13 + Fix bug that can cause incorrect verbose display of user smtp + messages. + Disable SMTP VERB command if PRIV_NOEXPN is set (since this + could reveal the same information. + Allow failure when reading SMTP greeting message to go on to + next MX host. + Add "MIME-Version: 1.0" header if using MIME (this was NOT + included in RFC 1344, but Bill King of Allan-Bradley + Company forwarded me email from Nathaniel Borenstein + claiming that it was an inadvertent omission). + Don't use Content-Type: X-message-header. According to John + Myers of CMU, many MIME readers will completely ignore + the data if they don't recognize it. Instead, just + add a blank line to make it a legal (empty) message. + Fix problem causing dots to keep getting appended to cached + hostnames. This can cause buffer overrun conditions. + The problem was found by Erik Forsberg of Retix, + although I used a different bug fix than he provided. + Fix parsing of split header/envelope rewriting specs -- from + Eric Forsberg. + Fix from Eric Wassenaar to correct To: lists in error messages. + +6.57/6.28 93/05/11 + Fix minor glitch causing extra ctladdrs to be output to queue + file. Just an annoyance. + Cache results of name server canonification lookups to avoid + backed up queue runs. + Major rewrite of alias.c: considerable cleanup, plus sample + (untested) support for NIS aliases. The "A" option + can now be a comma separated list (or be repeated) -- + that is, you can have multiple alias databases. Each + database can have the syntax ``class:file''; if no class + is specified, the "implicit" class is assumed. Implicit + searches through a list of compiled in types -- hash, + dbm, nis, and stab. Alias files are searched in the + order they are listed. For example: + OAhash:/etc/aliases.local,/etc/aliases + OAnis:mail.aliases@my.nis.domain + first searches the hash database /etc/aliases.local, + then the regular /etc/aliases database, then the NIS + map "mail.aliases" in the NIS domain "my.nis.domain". + If in Verbose mode (probably from VERB command) run SMTP job + in foreground and don't do RCPT optimizations. + Add udb :mailsender as equivalent to owner- for regular aliases. + Delete option 8; add option 7 that means the opposite. That is, + default to 8-bit mode; a special option is needed to + force sendmail into 7 bit mode. + Send error messages in encapsulated MIME format. + New compile flag "NIS" that turns on NIS alias and NIS map + support. + Add "j" option to send error messages in MIME (RFC 1341) + encapsulated message format per RFC 1344. The + syntax is pretty ugly if you don't have MIME-aware + user agents. + Clean up message handling (for display in mailq output). + New setproctitle implementation for 4.4bsd. + Create files (such as ~/dead.letter) using mode FileMode (the + F option value) instead of 0666. + Fix bug causing output of EXPN command to not be fully qualified. + This may cause some problems with UUCP addresses that + will require some config file assistance -- specifically, + the $: part has to include the host name for this output + to make sense. + Fix a problem that sometimes diagnosed errors and still sent the + message if the header syntax was bad. + Fix a bug that caused an error message to be emailed when sendmail + was operating in -bv mode. + Add "ListenQueueSize" keyword to daemon options option (OO) to + set the queue size parameter passed to listen(). You + will normally have to tweak your kernel to up this. + Strip spaces off of beginning of message-id before logging (in + case it was folded across lines). + Tweak compile flags in daemon.c -- there were some cases where + it wouldn't work without NETINET. + Change *file* mailer to output all the usual default headers + (From, Date, Message-Id). It gets used when sending + back error messages. + CONFIG: explicitly catch and diagnose list:; syntax in ruleset + zero -- this is not a valid recipient syntax according + to RFC 821. + CONFIG: add confMIME_FORMAT_ERRORS to send error messages in + MIME format. Defaults to on. + CONFIG: add SMTP_MAILER_FLAGS and UUCP_MAILER_FLAGS to augment + the flags for those mailers. + +6.56/6.27 93/05/01 + Fix problem that causes the fallback mail to postmaster + (case ESM_POSTMASTER in savemail()) to not look at + aliases (ugh). + Some more HPUX tweaking (compile flag hpux => __hpux so it + still works in ANSI mode). + Don't try to flock non-regular files when mailing to a file. + In particular, this was a problem if you tried to + send to /dev/null. + Fix a wierd bug that can cause senders to be queued as + recipients if the name server is down when the mail + is initially sent. This hack just ignores sender + deletion (essentially, it sets the MeToo flag) if there + is a TEMPFAIL during processing of the sender address. + Obscure. + Fix a dangling else problem -- from Brian Bullen from University + of Stirling, UK. + Add the "b" mailer flag to force a blank line on the end of + messages. Some brilliant versions of /bin/mail insist + on this but do not add it themselves. + Add the "g" mailer flag to prevent user SMTP from sending + "MAIL From:<>". This is only intended to be a + transitional gesture, and should not be used if at + all possible. It appears that Berkeley and IDA + config files have always handled this properly; the + UK config kit apparently does not. + Don't lowercase and then capitalize header field names -- leave + them with original capitalization. Fixes from Bill + King of Allen-Bradley Company. + Further cleanup and improved reporting of error messages, + particularly conditions that cause messages to be + requeued for future delivery. + Tweak syslog priorities in some cases. + CONFIG: clean up route-addr on UUCP addresses. + +6.55/6.25 93/04/27 + HPUX 8.07 compatibility changes in getla() -- I had to make + these changes to get it to work at Berkeley, although + others seem to have been working before (???). + Various patches to XLA code. + Fix problem that causes setuid bit on files to be ignored from + SMTP or in queue runs. Problem noted by Jason Ornstein + of Under The Wire, Inc. + Fix problem that can cause CNAMEs to be ignored. + Generalize getmxrr to match local host in $=w instead of a + single name passed in. + Some cleanup from Eric Wassenaar: + Use FileMailer instead of ProgMailer in two places. + Eliminate duplicate 8th-bit stripping in commaize. + Fix a problem with mis-parsing of backslash escapes + under some circumstances. + NIS map fix (was always including trailing null character) + from Mike Glendinning of Ingres UK. + Add "a" mailer flag to try using ESMTP. It tries the EHLO + command and if that fails falls back to regular SMTP. + Also parses EHLO option keywords. If host supports + SIZE extension, this is added to the MAIL FROM: + command. + Extend "b" option to include a second value which is the + maximum message size this server is willing to accept. + For example, a value of "10/1000000" says that there + must be ten blocks free, and sendmail will reject + any message larger than one megabyte. + Some portability hooks for NeXT (this could be applicable + to Mach in general). You have to create an empty + file called "unistd.h" to get it to compile. + Adjust config values (MAXLINE, MAXATOM, and PSBUFSIZE) to + be more generous. + Add X400-Received: to the list of headers tagged with H_TRACE + in conf.c. From Bill King, Allen-Bradley Co. + +6.54/6.25 93/04/19 + Fix problem that caused redefinition of SMTP and QUEUE compile + flags. Pointed out by Jon Forrest of the Sequoia 2000 + project at Berkeley. + Properly handle \! hack -- it was treating host\!user as one + token (host!user) instead of three (host, !, user). + Fix from Eric Wassenaar of NIKHEF-H. + Fix compilation problem in getauthinfo() if IDENTPROTO is off. + Turn off DEFNAMES and DNSRCH when getting the hostsignature + (i.e., MX records) in level 1 configuration files; this + matches the old behaviour. From Motonori Nakamura of + Kyoto University. + Improve error message printing -- if sent through an alias, + error messages include the name of the alias in the + message. Unfortunately, in order to make this work + properly in queue runs, this changes the format of the + C line in the qf file. The relatively uselessness of + the previous information was pointed out to me by + Allan E Johannesen of WPI. + Add XLA compile flag to add hooks to Christophe Wolfhugel's + extended load average code. This is still in very early + form. For information regarding the guts of the xla + code, contact Christophe.Wolfhugel@grasp.insa-lyon.fr. + Additional hooks for detecting tempfails in rewriting rules + (that is, in map lookups). + +6.53/6.25 93/04/15 + Properly diagnose ruleset zero returning null (instead of a mailer + triple). From Motonori Nakamura of Kyoto University. + More generalization of socket code for other protocols. + Shorten timeouts on reverse name lookups -- since they are done + during connection establishment, long timeouts here can + cause higher level timeouts. This mainly serves to accept + mail from hosts that do not have proper reverse (PTR) DNS + records set up. + Reset e_statmsg before each mailer invocation to avoid bogus + messages in the log. + Redefine $r, $s, and $_ in error envelopes so you don't get + incorrect cruft in the error message. Problem noted by + Motonori Nakamura of Kyoto University. + Fix a problem that can cause failure to return errors to Postmaster + in certain cases. From Motonori Nakamura. + Fix a problem that can cause some systems to give duplicate error + messages when a bad syntax address such as "<a" is presented + to an SMTP server. It doesn't seem to occur on all + machines. From Motonori Nakamura. + Default IDENTPROTO off for Ultrix and HPUX, which apparently have + the interesting "feature" that when they receive a "Host + unreachable" message they closes all open connections to + that host. However, some firewall gateways send this message + if you try to connect to an unauthorized port, such as the + IDENT port (113). Thus, no email can be received from such + hosts. There is some evidence that versions of Ultrix before + 4.3 do not have this problem. Thanks to Tom Ivar Helbekkmo + for pointing out this behaviour to me and to Michael Corrigan + of U.C. San Diego for informing me about the HPUX problem. + Allow IPC mailers to return a colon-separated list of hosts in the + $@ clause; these are searched in order as though they were + MX records. + When sending an error report, print the list of addresses tagged + as bad. Requested by Allan E Johannesen of WPI. + Change map function calls to return a status code. This gets + passed back as the result of rewrite. Parseaddr marks + the address as a QUEUEUP address if the return code is + EX_TEMPFAIL. All this to queue properly if the name + server is down. This code is not well tested. This code + changes the interface to map lookup functions (a fifth + parameter, int *statp, is added). Feature requested by + Dan Oscarsson. + Don't delete quotes (in the dequote map) if there are spaces in + the string, since this would cause them to be replaced by + the SpaceSub character. + Accept BODY=8BITMIME on SMTP MAIL command. This isn't advertised + because the 8BIT to 7BIT translation doesn't exist yet. + This does add a "bodytype" field to both envelope and + queue file and a -B command line flag to pass the type in + during direct invocations. + Discard return error messages only on responses to responses to + responses, not on responses to responses. That is, the + algorithm is to try return to sender, then return to + postmaster, then discard. Previously it discarded + immediately if the return to sender pass failed. + CONFIG: back out change to hide unqualified hostnames behind %-hack. + This screws up local aliases and .forward files. + CONFIG: add FEATURE(nocanonify) to turn off calls to $[ ... $]; + some sites only handle completely canonified names. + Requested by John Gardiner Myers of CMU. + CONFIG: some UUCP code was still included even if FEATURE(nouucp) + was specified. + +6.52/6.24 93/04/10 + Clean up some minor glitches on error return messages pointed out + by Motonori Nakamura of Kyoto University. + Fix reply() to not reset SmtpReplyBuffer on fatal errors; this + was supposed to reset SmtpMsg Buffer. This makes the + client side code virtually useless. Reported by Allan + E Johannesen of WPI and Phil Brandenberger of Swarthmore. + Better debug messages if fuzzy is disabled, suggested by Allan + E Johannesen of WPI. + Offset SmtpReplyBuffer by four in usersmtp when checking for + loopback. From Eric Wassenaar. + Don't set $s until after runinchild in srvrsmtp -- otherwise + it gets cleared. From Eric Wassenaar. + Implement IDA-style $&x for deferred macro expansion. + More POSIX compatibility. + CONFIG: Hide unqualified hostnames behind %-hack using $s as the + actual sender. This is only done if $r is non-null, that + is, if this is not locally submitted mail. + CONFIG: Add FEATURE(bitdomain) allowing mapping of BITNET host + names to internet domains. A program contributed by + John Gardiner Myers of CMU to create the maps is included + in the contrib directory (in the "misc" tar file). + CONFIG: Add FEATURE(uucpdomain) for a similar mapping for UUCP + hosts. There is currently no tool to create this map. + +6.51/6.23 93/04/04 + Add D= mailer flag to specify a path of possible working directories + in which to execute the mailer. This is intended for the + prog mailer; some shells can get upset if they don't have + access to the current directory. + Add RFC 1413 (IDENT) protocol support. This is only very loosely + tested. This adds a $_ macro to be the authenticated + info (in ``user@domain [address]'' form) and debug flag + 9 to trace the protocol. + Check for loopbacks in usersmtp instead of srvrsmtp -- there is no + reason for a local agent to not be talking to the localhost + (although the inverse is not true). + Add a few hooks for automated map rebuilding. This is certainly + not done yet. + CONFIG: Have prog mailer specify a path of ``D=$z:/'' -- that is, + user's home directory then the root. + CONFIG: Log RFC 1413 identification in Received: line. + +6.50/6.22 93/04/01 + Fixes to requeueing code to make it compute priority, nrcpts, + and the like properly. + +6.49/6.22 93/04/01 + Diagnose incorrect privacy flags. Suggested by Bryan Costales + of ICSI. + Some ANSI C fixes. + Arrange to quote backslashes as well as other special characters + in the phrase part of a route-addr. + Some fixes to FallBackMX code suggested by Motonori Nakamura of + Kyoto University. + More vigorous zeroing of CurHostAddr to avoid logging of bogus + host addresses when you are actually just printing + information from the MCI structure; problem noted by + Michael Corrigan of U.C. San Diego. + Don't ignore rest of queue if any job is not runnable. This can + also cause an incorrect job to be lost. Fix from + Eric Wassenaar. + Always respond "quickly" to RCPT command; do alias expansion and + the like later. This also means that mail for lists that + have errors will be acccepted, and an error sent back + later. This is done by instantiating the queue file + and then immediately running and requeueing it. + +6.48/6.22 93/03/30 + Fix incorrect diagnosis of infinite loop in ruleset. Problem noted + by several people. + Improve information printed when infinite loops are discovered. + Zero CurHostAddr to fix erroneous internet addresses in log when no + addresses can be bound. Pointed out by Motonori Nakamura + of Kyoto University. + "Probe" SMTP connections using RSET instead of NOOP "just in case". + Suggested by John Gardiner Myers of CMU. + Don't warn about -f if you are setting sender to yourself. + +6.47/6.22 93/03/29 + Fix incompatible call to endmailer in smtpquit which causes core + dumps. Noted by Allan E Johannesen of WPI. + HPUX portability changes from Michael J. Corrigan of UC San Diego. + Require MAIL before RCPT command in srvrsmtp.c. This had been + intentional from the 821 draft days when the order wasn't + clear, but is silly now. + Fix bug in nis_magic routine that was initializing parameters + incorrectly. Fix from Takahiro Kanbe of Fuji Xerox + Information Systems Co., Ltd. + Change default for PrivacyFlags in conf.c to 0 -- since it always + "or"s in new values, there was no way to turn off the + AuthWarning stuff. + Add O option to set SMTP daemon options. + Add V option to set fallback MX host. This always sorts at lower + priority than anything it gets from the name server. It + should only be used for environments with very bad network + connectivity. Requested by several people. + Log sending info. It's not clear this is a good idea. + CONFIG: fix typo in mailertable code. Noted by Phil Brandenberger + of Swarthmore. + CONFIG: add confDAEMON_OPTIONS and confFALLBACK_MX to set options + O and V, respectively. + +6.46/6.21 93/03/26 + Fix botch in server SMTP that broke transactions that did not + use HELO first (like MH). Fix from Michael Corrigan + of U.C. San Diego. + Fall back to other MX records if there is an error anywhere + in delivery (actually on MAIL or DATA -- RCPT is harder). + Suggested by John Gardiner Myers and Motonori Nakamura. + Revert to non-prototypes -- it turns out that our ANSI C + compiler is more forgiving than most others about + mixing prototyped extern declarations with non-prototyped + function definitions. + Fix a problem with multi-word class matching pointed out by + Neil Rickert. Given: + CX b a.b.c + R$+ $=X $+ $: $1 < $2 > $3 + the input "user@a.b.c" failed instead of being properly + rewritten as "user@a.<b>.c". + Neil also convinced me that it was correct that $~ should match + only one token -- the problem is that it's always possible + to add another token, so $~ matches far too eagerly. + +6.45/6.21 93/03/25 + Implement multi-word classes (properly!). + +6.44/6.21 93/03/25 + Add X-Authentication-Warning: headers to clue users into possible + attempts to forge mail. This is on the authwarnings + privacy flag, but is the default. Suggested by Bryan + Costales of ICSI. + Pass default units for convtime in so they can be more reasonable. + Allow config files to always add a new Comments: header (i.e., + they will be added even if an old one already exists). + Suggested by Bryan Costales of ICSI. + Allow config files to delete an existing Return-Path: header. + These should only be added at final delivery. Suggested + by Bryan Costales of ICSI. + Some debugging additions. Suggested by Bryan Costales of ICSI. + Clean up logging of Family 0 addresses. Noted by David Muir + Sharnoff and others. + Add a "dequote" map class. This allows config files to strip + quotes off of addresses. Note that this is not a builtin + map, just a class -- so you have to define the map + using the K line. + Fix a bug in the queueup() loop getting a locked tf where in + very odd cases it can fall off the bottom and core dump. + Of course, it was P{r Emanuelsson who found it.... + Open a new transcript when splitting an envelope. Problem found + by Allan E Johannesen of WPI. + Improved error output in endmailer if the mailer core dumps. + CONFIG: Fix typo in UUCP mailer definition. + CONFIG: Default several of the new options on: eight bit input, + privacy flags set to "authwarnings", and message warning + set to 4h. + CONFIG: Use dequote map. + +6.43/6.20 93/03/23 + Fix problem with assumption of an sa_len field in a generic + sockaddr -- it turns out that most vendors haven't + picked up this (very important) fix. + Change compilation flags for daemon code -- select one or both + of NETINET or NETISO, but don't ever set DAEMON manually. + CONFIG: add FEATURE(mailertable) to do IDA-style mailertables. + +6.42/6.19 93/03/19 + Use Postmaster as default fallback return address, not root. + POSIX changes for file descriptor handling. + Diagnose errors writing new queue file. + If you change the owner using an owner- alias, also change the + error mode to EM_MAIL so that errors don't get dropped + into an inappropriate directory. Problem noted by + Allan E Johannesen of WPI. + If you are su'ed to root, send email as who you really are, not + as root. From Brian Kantor of U.C. San Diego. + Allow warning messages to be sent after a configurable interval + has passed without delivery. The message is sent only + once per envelope. This changes the format of the qf + file to have an F line, and the format of the T option + to accept take the format "return/warn" (both intervals). + Don't force all local names to lower case -- this was left over + from the wierd handling of case mapping on aliases. It + is now driven (as expected) by the "u" mailer flag. + Problem noted by P{r Emanuelsson. + Fix problem that caused headers on returned email to be trashed; + they were getting freed, but are still accessible via + BlankEnvelope. + Fix problem that caused bogus ids to be created on returned + mail. + Add support for ISO and other non-INET networking. This is by + no means finished yet. This does assume a lot of other + system support, like a version of gethostbyname that + returns non-AF_INET addresses. + CONFIG: change default on prog mailer to keep upper case in + user names (i.e., in the program command line). + CONFIG: strip trailing dots off of hosts in uucp mailer before + convert to bang format. + CONFIG: create new "relay" mailer for $R (LOCAL_RELAY) and $H + (MAIL_HUB) delivery that doesn't add local domain. Note + that this violates 821, but is probably "more correct" + for what we are trying to do. Problem pointed out by + Michael Graff of Iowa State. + +6.41/6.18 93/03/18 + Clean up unnecessary creates of queue ids (i.e., empty qf files) + when not needed, such as when starting up an SMTP + connection. + Fix problem where split envelopes aren't instantiated in the queue. + This is quite a serious bug. + Owner- aliases had problems with leading spaces causing a + premature delimitation. + +6.40/6.18 93/03/18 + Have ending 250 (after DATA) include the id; suggested by + Brian Kantor of UC San Diego. + Add logging on envelope splitting. + Change queue ids to have one more letter encoding the hour of + the day so that during a single day there is a greater + likelihood of uniqueness; requested by Brian Kantor. + +6.39/6.18 93/03/18 + Fix minor compile problem if LOCKF is defined. + Define size of tobuf in conf.h. Observed by Toshinari Takahashi + of Toshiba. + Restore e_sender -- this is equivalent to e_from.q_paddr without + decorations such as angle brackets and comments. + OSF/1 on Alpha changes from Allan E Johannesen of WPI. + CONFIG: fix typo in S3 for list syntax (;: => :;). Thanks to + Christopher Hoover for noting the problem. + +6.38/6.17 93/03/17 + Pass envelope to disconnect to avoid another use of CurEnv, which + can apparently end up being null at inopportune times. + Log "received from" as "relay=" for consistency (suggested by + John Gardiner Myers). + Fix major bug in header handling: if no From: line existed in + the header (so sendmail inserts one), and the sender is + an alias that has an owner, the From: line shows the + owner (as well as the envelope). Fixed by early binding + the headers (which will change debugging output). + HPUX portability patches from Michael J. Corrigan of UC San Diego. + Some attempts to adapt better to out of open file conditions. + Some changes to ctladdr handling in queue files. + +6.37/6.17 93/03/16 + MAJOR CHANGE: delete e_sender and e_returnpath (why are these + different from e_from?) and $< macro. + Log correct IP address in relay= field even if the connection + times out. + Log "received from [RESPONSE]" on EF_RESPONSE messages (from + John Gardiner Myers). + Fixes to SysExMsg logging (sometimes just got "message: %s" + instead of "message: error message"), noted by Eric + Wassenaar. Also reported by Motonori Nakamura. + Improvements to MX piggybacking code, from Motonori Nakamura. + Fix case where CurHostName points to an auto variable that has + been deallocated (from Motonori Nakamura). + Fix bug causing newlines to be included in aliases if option + "n" (check alias RHS) is set; bug noted by David Muir + Sharnoff. + Fix problem causing user names that should be mapped to lower + case to not be mapped if they are sent during a queue + run. This greatly simplifies the case mapping code. + Problem noted by Allan E Johannesen of WPI. + Don't do recipient address rewriting in buildaddr. This + improperly did recipient rewriting on sender addresses, + and just seems bogus in general -- but the change could + break some .cf files. + Pass TZ envariable to child processes for System V. + CONFIG: allow LOCAL_RULE_1 and LOCAL_RULE_2 if you want to + define those rulesets. + KNOWN PROBLEM: I have seen some problems on SunOS that causes + the User Data Base to give errors on some addresses. I + have tracked the problem back at least as far as 93.02.15 + (version 6.22). Running with debugging on makes it + go away, so I conclude that it is referencing uninitialized + stack data. I haven't been able to track this down yet. + +6.36/6.16 93/03/08 + Allow local mailer to specify $@host -- this lets you assign the + "foo" part of jgm+foo to $h for passing in to the local + mailer. + Additional debug printing in getcanonname (show query type). + Don't add the e_fromdomain on sender addresses -- this interacts + wierdly with the owner- code. + Improve delivery logging to not log obvious or meaningless stuff. + Include numeric IP address in Received: lines per RFC 1123 section + 5.2.8. + Fixed a bug in checking stat() return value if restrictmailq is + set. Also, check the entire group set instead of just the + primary group. Both from John Gardiner Myers. + Don't have usrerr automatically print errno, since this is often + misleading. + Use transienterror() in makeconnection after connect() fails and + in openmailer after execve() fails (from Eric Wassenaar). + Also moved transienterror() from util.c to conf.c. + Clean up from= logging on response messages. + Undo patch allowing prescan to return a null vector -- it breaks + too many things. + Config: FEATURE(notsticky) lets you use UDB for everything coming + in to the machine, even if it is specifically targetted + to this machine. Without it, UDB is bypassed if the user + name is fully qualified. + Config: fix another minor botch with <> (local mailer wasn't + mapping them properly). + +6.35/6.15 93/03/05 + Fix getrealhostname to return null if sinlen <= 0 -- this can + occur if stdin is a pipe. + Avoid infinite loop in getcanonname if name server return + NO_DATA (for example). + Config: avoid having C flag qualify list syntax and error syntax. + +6.34/6.14 93/03/05 + Fix logging in deliver to not pass too many parameters to Ultrix + versions of syslog. + Don't write the pid file until after the daemon has actually + opened and conditioned the connection. + Consider addresses "different" if their q_uids differ (so that + two users forwarding to the same program will be seen + as different, rather than the same). + Fix problem with bad parameters in main() -- they set ExitStat + but don't exit. + Fix null pointer references through RealHostName -- painfully + discovered by Allan E Johannesen of WPI. + Fix bug causing user@@localhost to core dump (yuch). + Config: don't put two @host.dom.ain on users in $=E in SMTP + mailer. Also, catch user@ (no host) in ruleset 0. + +6.33/6.13 93/03/03 + Config: add confCW_FILE as the name of the cw configuration file + (defaults to /etc/sendmail.cw). From P{r Emanuelsson. + Allow prescan to return a pointer to an empty list -- this is + not an error. Also, clean up error reporting to avoid + double errors (prescan reports once, then the caller + reports again). + Changes to avoid trusting T_ANY queries -- run them, but if you + don't get the info you expected, do T_A and T_MX queries + anyhow. This also fixes an oversight where _res.options + bits were being ignored. + If PRIV_NOVRFY is set, use 252 response code instead of 502 per + RFC 1123 section 5.2.3. It's not 100% clear that this + is correct, but it probably works better with stupid + mailers that do a VRFY and only check the first digit. + +6.32/6.12 93/03/02 + Fix uninitialized variable "protocol" in smtp code. + Include <unistd.h> in sendmail.h -- move towards POSIX/ANSI. + Additional hooks for RFC 1427 (ESMTP SIZE extension). This + includes requiring that enoughspace() know the system + block size, which will undoubtedly break most ports. + Trace flag 19 in use for srvrsmtp.c. + Additional logging -- notably the sending mailer name. This + also changes the delivery logging to strict field=value + syntax. + Fix some problems with messages getting sent even to addresses + that had been marked bad -- from Eric Wassenaar. + More WIDE changes: accept host name inside [...] as non-MXed + host. This is intended ONLY for use inside firewalled + environments, where the MX points at the gateway. + Change .cf file conventions so that mapping for <> addresses + don't have an @ in them (to avoid confusing the C mailer + flag). Pointed out by Neil Rickert. + Config extensions for Sam Leffler's FlexFAX software. + +6.31/6.10 93/02/28 + Fix some more bugs in alias owner code -- there were some wierd + cases where an error in a non-aliased name would override + the return info in an aliased name with an owner. + Changes from WIDE Project, forwarded to me by Motonori Nakamura: + Log actual delivery host (after MX et al); from + yasuhiro@dcl.co.jp. + Log daemon startup. + Deliver Postmaster copies without a body. + Better logging of SMTP senders. + Send all program email as daemon even when local. + As requested in various forms from many people, accept -qIstring + to limit queue runs to jobs with queue-id matching string. + Similarly for -qRstring for recipients, -qSstring for + senders. + Initial hooks for ESMTP support (see RFC 1425). + Fixed a syntax error in the UUCP mailer specification that caused + core dumps on startup. + Check for missing A= or P= arguments in mailer definitions. + +6.30/6.10 93/02/27 + Require FROZENCONFIG compilation flag to include frozen + configuration code. Frozen configuration is really + not a very good idea any more, particularly in shared + library environments. + Do better checking of errno after opens of :include: and .forward + files to defer delivery on network and other transient + errors. Suggestion from Craig Everhart. + Fix minor botch in read timeout macro processing. + Add FEATURE(nouucp) to config files for sites that know absolutely + nothing about UUCP. + Add built cf files to distribution tape and clarify how to build + them if you don't have the Berkeley make. + Some sizeof(long) portability changes for the Alpha, from Allan + E Johannesen. + Add "restrictmailq" privacy flag -- if set, only people in the same + group as your queue directory can print the queue. If you + set this, be sure you also restrict access to log files.... + Fix another bug in owner-list stuff that can cause data files to + be "lost". + Fix a bug with queue runs that cause forwards to yourself to go + into alias/forwarding loops. I'm still iffy about this + fix. + Fix from Eric Wassenaar for suppression of return message code. + +6.29/6.9 93/02/24 + Fix yet another problem in alias owner code -- put the wrong return + address on the enclosed return-to-sender letter. + +6.28/6.9 93/02/24 + Fix botch in alias owner code that caused it to not operate if the + error was detected locally. + +6.27/6.9 93/02/24 + M_LOCAL => M_LOCALMAILER to avoid conflict with Ultrix include + file <sys/mount.h>. + Miscellaneous bug fixes from Eric Wassenaar: + sendmail -bv -t logs the from line even though in verify + mode only. + sendmail -v can go into queue mode if shouldqueue returns + TRUE. + Add route-addr pruning per RFC 1123 section 5.3.3. This can be + disabled using the "R" option. + Delete (always undocumented) -R flag (save original recipients); + there are ways to syslog(3) these now. + Clean up SMTP reply codes -- specify them as needed in the code, + instead of in conf.c -- this was needed during the NCP to + TCP transition, but seems silly now. This also changes + parameters to message and nmessage. + Have mailstats read the .cf file to find the sendmail.st file and + get text versions of mailer names. An initial version of + this code was provided by Tuominen Keijo (although the + comments indicate the good bits were written by "E.V."). + Add yet more System V compatibility hacks. + Fix bug in VRFY code (assumes everything must be a local user). + Allow specification of any of the hard-wired pathnames in the + Makefile. + Delete concept of "trusted users" -- this really didn't provide + any security anyway, and caused some problems. + Delete last vestige of support for the word "at" as an equivalent + to the character "@". + Propagate owner-foo alias information into the envelope sender. + Based on code from John Gardiner Myers. This is a major + semantic change -- beware! + Allow $@ on LHS to indicate "match zero" -- this is used to match + the null expression. + +6.26/6.8 93/02/21 + Don't "lose" queue runs. Very important fix from (who else?) + Eric Wassenaar. + Completely reset state on RSET command -- from Eric Wassenaar. + Send error messages and return receipts using an envelope sender + of <> regardless of the setting of $n. Rewriting rules + can undo this if they feel the necessity, as might be + needed for networks that don't understand the syntax. + This is permitted by RFC 821 section 3.6 and required by + RFC 1123 section 5.3.3. THIS REQUIRES VERSION 4 CONFIG + FILES because the rulesets must be able to parse <> + properly. + Don't ever send error messages to "<>" -- they will get sent to + the local postmaster or dumped in /usr/tmp/dead.letter + instead. Per RFC 1123 section 5.3.3. + Explicitly check for email to yourself as a dotted quad. You + have to call $[ [ ... ] $] to get this. + Up the message timeout to five days per RFC 1123 section 5.3.1.1. + Make all read timeouts individually configurable, as strongly + recommended by RFC 1123 section 5.3.2. + Use f_bavail (blocks available to regular users) instead of f_bfree + (blocks available to superuser) in free block checks. + Change $d macro to be the current time, not the origination time, + since this is consistent with how it is used now. + Generalization of enoughspace from Eric Wassenaar covering + SGI, Apollo, HPUX, Ultrix, and SunOS. + Ignore process group signals -- some front ends can do this if + you kill a window too quickly. From Eric Wassenaar. + Change umask to 022. + +6.25/6.8 93/02/20 + Close all cached connections before calling mailers and after + forking for delivery (caused double closes which resulted + in false errors). + Add FEATURE(redirect) in config files -- this allows you to alias + old addresses to a pointer to the new address that will + give a 551 error message, but not deliver the mail. + Some code changes to make the 551 errors look pretty. + Names of M4 program paths in config files have changed -- they + are all XXX_MAILER_PATH now, to match XXX_MAILER_FLAGS. + Fix a bug in the QSELFREF code having to do with empty .forward + files, reported by Eric Wassenaar. + Add option "p" (privacy flags); this allows you to tune how + picky the SMTP server will be. This also adds the + confPRIVACY_FLAGS M4 macro in the config files. + Add option "b" (minimum blocks free). If there are fewer than + this number of blocks free on the filesystem containing + the queue directory, the SMTP MAIL command will return + a 452 response and ask you to try again later. This + also adds the confMIN_FREE_BLOCKS M4 macro in the config + files. + Made VRFY just verify (doesn't expand aliases and .forward files); + EXPN does full expansion. RCPT in queue-only mode also + doesn't chase aliases and .forward. + +6.24/6.7 93/02/19 + Increase the number of domain search entries in domain.c to allow + for the extra "" entry indicating the root domain. + Reported by Motonori Nakamura of Kyoto U. + Add a "SMART_HOST" in the configs for UUCP-connected sites that + want to forward all mail with extra "@"s to that site. + Also allows SMART_HOST, LOCAL_RELAY, and MAIL_HUB to + be specified as ``mailer:hostname'' to use an alternate + mailer. + Clarified and updated some wording in the Operations Guide. + Add the "c" mailer flag -- this suppresses all comment parts of + addresses (requested by John Curran of NEARnet). + Have -v print prompts in -bt mode even if stdin is not a terminal + (default behaviour is to be silent if not reading from + a terminal). Suggested by Bryan Costales, ICSI. + Move the metacharacters from C0 space (\001-\037) into C1 space + (\201-\237). This also fixes a bunch of potential bugs + with G1 characters (\240-\276) in headers relating to + negative numbers passed to isspace() et al. + Add YP_LAST_MODIFIED and YP_MASTER_NAME to DBM version of alias + database if YPCOMPAT is #defined. Enhancement from + Takahiro Kanbe of Fuji Xerox Information Systems Co., Ltd. + Add "list" Precedence (-30); this can be used with old sendmails + which will map to precedence 0 (which will return error + messages). Suggested by Stephen R. van den Berg. + Many bug fixes from Eric Wassenaar of the National Institute for + Nuclear and High-Energy Physics, Amsterdam: + Clear timeouts properly on open failures in include(). + Don't dereference through NULL if no home directory found. + Re-establish SIGCHLD signal on System 5 in reapchild(). + Avoid NULL pointer reference on -pFOO flag. + Properly handle backslash escapes in comments. + Correctly check reply status on SMTP NOOP command. + Properly save SMTP error message if peer gives + "Service Shutting Down" message. + Avoid writing to the transcript if it couldn't be opened. + Signal errors in SMTP children to parent properly. + Handle self references in a list more globally (include a + QSELFREF bit in the address flags). This enhancement + was suggested by Eric Wassenaar. + Use initgroups() in hpux, even though it's System-V based. The + HASINITGROUPS compile flag can set this on other systems. + This HPUX behaviour was pointed out by Eric Wassenaar. + +6.23/6.6 93/02/16 + Clean up handling of LogLevel to make it easier to figure out + what's on what level. + Change log levels to have some consistency: + 1 serious system failures, security problems + 2 lost communications, protocol failures + 3 other serious failures + 4 minor errors + 5 message collection + 6 vrfy logging, creation of return-to-sender + 7 delivery failures + 8 delivery successes + 9 delivery tempfails (queue ups) + 10 database expansion + >64 debugging + Allow IDA-style separated processing on S= and R= in Mailer + definition lines. Note that rulesets 1 and 2 are + still used for both addresses as before. Bruce Lilly + gave a convincing argument that RFC976 insists on + this behaviour. + Added some time zones to arpatounix -- they may not be in the + standards, but they are in use. However, I may delete + arpatounix entirely -- there appears to be no reason + for it to exist. + Change to UUCP mailer (in cf directory) to try to do a saner job. + I'm still not certain about this mailer in general. + +6.22/6.5 93/02/15 + Fix bug that prevents saving letters in ~/dead.letter. + Don't add angle brackets in VRFY command if angle brackets already + exist in the address. + Fix bogus error message in udbexpand. + Null terminate host buffers in buildaddr (broken in 6.21) -- + IMPORTANT FIX!! + +6.21/6.5 93/02/15 + Fix another incorrect error message in alias.c, found by Azuma + Okamoto. + Fix a couple of problems in the more-configurable config files, + found by Tom Ivar Helbekkmo. + Fix problem with quoted :include: entries. + Don't duplicate the filename on verbose printing of .forward and + :include: contents. + Extend size of prescan buffer (to allow bigger addresses). Also, + detect some buffer overflows. + Log user SMTP protocol errors (log level 4). + +6.20/6.4 93/02/14 + Fix another problem in the MCI state machine caused when there + were errors generated from the other end to commands + other than RCPT. + +6.19/6.4 93/02/14 + Include load average support for DEC Alpha running OSF/1. + Fix multiple-response problem with errors in MAIL From: line. + Fix SMTP reply codes for invalid address syntaxes (give 501; + never give multiple error messages for a single message). + Fix problem where a cached connection timeout rejects all + later connects to that host. + Fix incorrect error message if alias.c is compiled with DBM only. + Additional changes to fix nested conditionals (from Bruce Lilly). + Recover more gracefully from operating system failures, particularly + NULL returns from openmailer (from Noritoshi Demizu, + OMRON Corporation). + Log forward, alias, and userdb expand operations on log level 10; + concept suggested by P{r (Pell) Emanuelsson. + Changes for HPUX 8.07 compatibility. + +6.18/6.4 93/02/12 + Allow any config option to be set using an M4 define. + Change UNAME compile flag to HASUNAME for IDA compatibility + (besides, it's a better name). + Note in README that on SunOS it must be linked -Bstatic. + Fairly major change in domain.c to handle wildcard MX records + more rationally. NOTE: the "w" option (no wildcard MX + records match local domain) has been eliminated. + Fix some unset variable references pointed out by Bruce Lilly. + Fix host name in process titles when using cached connection. + +6.17/6.3 93/01/28 + Fix System 5 compatibility changes to be compatible with the rest + of the world. + +6.16/6.3 93/01/28 + Experimental fix for problem handling errors in the SMTP + protocol in conjunction with connection caching. + System 5 compatibility changes. + +6.15/6.3 93/01/26 + Fix a bug that causes local mail delivered using -odq to be + eliminated as a duplicate (because it matched the + ctladdr, now passed in as a C line). These changes + are pretty tricky...... + +6.14/6.3 93/01/25 + Add debugging for some MCI errors. + +6.13/6.3 93/01/22 + Fix -e compatibility flag to take a value. + Fix a couple of minor compilation warnings on Sun cc. + Improve error messages in a few cases to be more self-explanatory. + +6.12/6.3 93/01/21 + Fix yet-another problem with environment handling, pointed out + by Yoshitaka Tokugawa and Tom Ivar Helbekkmo. + Some heuristics to try to limit resource exhaustion problems + if a downstream host has been down for a long time. + Fix problem with incorrect host name being logged in "Connection + timed out" messages (from Tom Ivar Helbekkmo). + Fix some ANSI C problems (from Takahiro Kanbe). + Properly log message sender on returned mail during queue run. + Count number of recipients properly. + Fix a problem in yp map code. + Diagnose "message timed out" (from Motonori Nakamura). + +6.11/6.3 93/01/20 + Fix problem with address delimitor inside quotes. + Define $k and $=k to be the UUCP name (from the uname call) + based on code from Bruce Lilly. + +6.10/6.2 93/01/18 + Implement arpatounix (largely code from Bruce Lilly). + Log more info (suggested by John Myers). + Allow nested $?...$|...$. (inspired by code from Bruce Lilly of + Sony US). + POSIX compatibility (noted by Keith Bostic). + Handle SMTP MAIL command errors properly (urged by several people, + notably John Myers of CMU). + Do early diagnosis of .cf errors (notably referencing a RHS + substitution that isn't on the LHS). + Adjust checkpointing to better handle batched recipients, suggested + by John Myers. + Fix miscellaneous bugs. + (config files:) Implement MAIL_HUB for all local mail (to handle + NFS-mounted directories) as urged by Tom Ivar Helbekkmo + of the Norwegian School of Economics. + +6.9/6.1 93/01/13 + Environment handling simplification/bug fix -- child processes + get a minimal, fixed environment. This avoids different + behaviour in queue runs. + Handle commas inside comments properly. + Properly limit large messages submitted in -obq mode. + +6.8/6.1 93/01/10 + Check mtime of thaw file against .cf and sendmail binary, based on + code from John Myers. + +6.7/6.1 93/01/10 + MX piggybacking, based on code from John Myers@CMU. + Allow checkcompat to return -1 to mean tempfail. + Bug fix in m_mno computation. + +6.6/6.1 93/01/09 + Tuning of queueing functions as recommended by John Gardiner Myers. + Return mail headers (no body) on messages with negative precedence. + Minor other bug fixes. + +6.5/6.1 93/01/03 + Fix botch causing queued headers to have ?XX? prefixes. + +6.4/6.1 93/01/02 + Changes to recognize special mailer types (e.g., file) early. + +6.3/6.1 93/01/01 + Pass timeouts to sfgets. + Check for control characters in addresses. + Fixed deferred error reporting. + Report duplicate aliases. + Handle mixed case recursive aliases. + Misc bug fixes. + +6.2/6.1 92/12/30 + Put return-receipt-to on a conf.c flag (but don't set it). + Fix minor syslog problem. diff --git a/usr.sbin/sendmail/cf/README b/usr.sbin/sendmail/cf/README new file mode 100644 index 000000000000..c0fb9106b8af --- /dev/null +++ b/usr.sbin/sendmail/cf/README @@ -0,0 +1,1740 @@ + + + NEW SENDMAIL CONFIGURATION FILES + + Eric Allman <eric@CS.Berkeley.EDU> + + @(#)README 8.80 (Berkeley) 11/19/95 + + +This document describes the sendmail configuration files being used +at Berkeley. These use features in the new (R8) sendmail; they will +not work on other versions. + +These configuration files are probably not as general as previous +versions, and don't handle as many of the weird cases automagically. +I was able to simplify by them for two reasons. First, the network +has become more consistent -- for example, at this point, everyone +on the internet is supposed to be running a name server, so hacks to +handle NIC-registered hosts can go away. Second, I assumed that a +subdomain would be running SMTP internally -- UUCP is presumed to be +a long-haul protocol. I realize that this is not universal, but it +does describe the vast majority of sites with which I am familiar, +including those outside the US. + +Of course, the downside of this is that if you do live in a weird +world, things are going to get weirder for you. I'm sorry about that, +but at the time we at Berkeley had a problem, and it seemed like the +right thing to do. + +This package requires a post-V7 version of m4; if you are running the +4.2bsd, SysV.2, or 7th Edition version, I suggest finding a friend with +a newer version. You can m4-expand on their system, then run locally. +SunOS's /usr/5bin/m4 or BSD-Net/2's m4 both work. GNU m4 version 1.1 +also works. Unfortunately, I'm told that the M4 on BSDI 1.0 doesn't +work -- you'll have to use a Net/2 or GNU version. + +IF YOU DON'T HAVE A BERKELEY MAKE, don't despair! Just run +"m4 ../m4/cf.m4 foo.mc > foo.cf" -- that should be all you need. +There is also a fairly crude (but functional) Makefile.dist that works +on the old version of make. + +To get started, you may want to look at tcpproto.mc (for TCP-only +sites), uucpproto.mc (for UUCP-only sites), and clientproto.mc (for +clusters of clients using a single mail host). Others are versions +that we use at Berkeley, although not all are in current use. For +example, ucbarpa has gone away, but I've left ucbarpa.mc in because +it demonstrates some interesting techniques. + +I'm not pretending that this README describes everything that these +configuration files can do; clever people can probably tweak them +to great effect. But it should get you started. + +******************************************************************* +*** BE SURE YOU CUSTOMIZE THESE FILES! They have some *** +*** Berkeley-specific assumptions built in, such as the name *** +*** of our UUCP-relay. You'll want to create your own domain *** +*** description, and use that in place of domain/Berkeley.m4. *** +******************************************************************* + + ++--------------------------+ +| INTRODUCTION AND EXAMPLE | ++--------------------------+ + +Configuration files are contained in the subdirectory "cf", with a +suffix ".mc". They must be run through "m4" to produce a ".cf" file. +You must pre-load "cf.m4": + + m4 ${CFDIR}/m4/cf.m4 config.mc > config.cf + +where ${CFDIR} is the root of the cf directory and config.mc is the +name of your configuration file. If you are running a version of M4 +that understands the __file__ builtin (versions of GNU m4 >= 0.75 do +this, but the versions distributed with 4.4BSD and derivatives do not) +or the -I flag (ditto), then ${CFDIR} can be in an arbitrary directory. +For "traditional" versions, ${CFDIR} ***MUST*** be "..", or you MUST +use -D_CF_DIR_=/path/to/cf/dir/ -- note the trailing slash! For example: + + m4 -D_CF_DIR_=${CFDIR}/ ${CFDIR}/m4/cf.m4 config.mc > config.cf + +Let's examine a typical .mc file: + + divert(-1) + # + # Copyright (c) 1983 Eric P. Allman + # Copyright (c) 1988, 1993 + # The Regents of the University of California. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # 1. Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # 2. Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in + # the documentation and/or other materials provided with the + # distribution. + # 3. All advertising materials mentioning features or use of this + # software # must display the following acknowledgement: + # This product includes software developed by the University of + # California, Berkeley and its contributors. + # 4. Neither the name of the University nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' + # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS + # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # + + # + # This is a Berkeley-specific configuration file for HP-UX 9.x. + # It applies only the the Computer Science Division at Berkeley, + # and should not be used elsewhere. It is provided on the sendmail + # distribution as a sample only. To create your own configuration + # file, create an appropriate domain file in ../domain, change the + # `DOMAIN' macro below to reference that file, and copy the result + # to a name of your own choosing. + # + divert(0) + +The divert(-1) will delete the crud in the resulting output file. +The copyright notice can be replace by whatever your lawyers require; +our lawyers require the one that I've included in my files. A copyleft +is a copyright by another name. The divert(0) restores regular output. + + VERSIONID(`<SCCS or RCS version id>') + +VERSIONID is a macro that stuffs the version information into the +resulting file. We use SCCS; you could use RCS, something else, or +omit it completely. This is not the same as the version id included +in SMTP greeting messages -- this is defined in m4/version.m4. + + OSTYPE(hpux9)dnl + +You must specify an OSTYPE to properly configure things such as the +pathname of the help and status files, the flags needed for the local +mailer, and other important things. If you omit it, you will get an +error when you try to build the configuration. Look at the ostype +directory for the list of known operating system types. + + DOMAIN(CS.Berkeley.EDU)dnl + +This example is specific to the Computer Science Division at Berkeley. +You can use "DOMAIN(generic)" to get a sufficiently bland definition +that may well work for you, or you can create a customized domain +definition appropriate for your environment. + + MAILER(local) + MAILER(smtp) + +These describe the mailers used at the default CS site site. The +local mailer is always included automatically. Beware MAILER +declarations should always be last in the configuration file, and +MAILER(smtp) should always precede MAILER(uucp). + +One word of warning: M4 macros are expanded even in lines that appear +to be comments. For example, if you have + + # See FEATURE(foo) above + +it will not do what you expect, because the FEATURE(foo) will be +expanded. This also applies to + + # And then define the $X macro to be the return address + +because ``define'' is an M4 keyword. If you want to use them, surround +them with directed quotes, `like this'. + + ++--------+ +| OSTYPE | ++--------+ + +You MUST define an operating system environment, or the configuration +file build will puke. There are several environments available; look +at the "ostype" directory for the current list. This macro changes +things like the location of the alias file and queue directory. Some +of these files are identical to one another. + +It is IMPERATIVE that the OSTYPE occur before any MAILER definitions. +In general, the OSTYPE macro should go immediately after any version +information, and MAILER definitions should always go last. + +Operating system definitions are usually easy to write. They may define +the following variables (everything defaults, so an ostype file may be +empty). Unfortunately, the list of configuration-supported systems is +not as broad as the list of source-supported systems, since many of +the source contributors do not include corresponding ostype files. + +ALIAS_FILE [/etc/aliases] The location of the text version + of the alias file(s). It can be a comma-separated + list of names (but be sure you quote values with + commas in them -- for example, use + define(`ALIAS_FILE', `a,b') + to get "a" and "b" both listed as alias files; + otherwise the define() primitive only sees "a"). +HELP_FILE [/usr/lib/sendmail.hf] The name of the file + containing information printed in response to + the SMTP HELP command. +QUEUE_DIR [/var/spool/mqueue] The directory containing + queue files. +STATUS_FILE [/etc/sendmail.st] The file containing status + information. +LOCAL_MAILER_PATH [/bin/mail] The program used to deliver local mail. +LOCAL_MAILER_FLAGS [rmn] The flags used by the local mailer. The + flags lsDFM are always included. +LOCAL_MAILER_ARGS [mail -d $u] The arguments passed to deliver local + mail. +LOCAL_MAILER_MAX [undefined] If defined, the maximum size of local + mail that you are willing to accept. +LOCAL_MAILER_CHARSET [undefined] If defined, messages containing 8-bit data + that ARRIVE from an address that resolves to the + local mailer and which are converted to MIME will be + labelled with this character set. +LOCAL_SHELL_PATH [/bin/sh] The shell used to deliver piped email. +LOCAL_SHELL_FLAGS [eu] The flags used by the shell mailer. The + flags lsDFM are always included. +LOCAL_SHELL_ARGS [sh -c $u] The arguments passed to deliver "prog" + mail. +LOCAL_SHELL_DIR [$z:/] The directory search path in which the + shell should run. +USENET_MAILER_PATH [/usr/lib/news/inews] The name of the program + used to submit news. +USENET_MAILER_FLAGS [rlsDFMmn] The mailer flags for the usenet mailer. +USENET_MAILER_ARGS [-m -h -n] The command line arguments for the + usenet mailer. +USENET_MAILER_MAX [100000] The maximum size of messages that will + be accepted by the usenet mailer. +SMTP_MAILER_FLAGS [undefined] Flags added to SMTP mailer. Default + flags are `mDFMUX' for all SMTP-based mailers; the + "esmtp" mailer adds `a' and "smtp8" adds `8'. +SMTP_MAILER_MAX [undefined] The maximum size of messages that will + be transported using the smtp, smtp8, or esmtp + mailers. +SMTP_MAILER_ARGS [IPC $h] The arguments passed to the smtp mailer. + About the only reason you would want to change this + would be to change the default port. +ESMTP_MAILER_ARGS [IPC $h] The arguments passed to the esmtp mailer. +SMTP8_MAILER_ARGS [IPC $h] The arguments passed to the smtp8 mailer. +RELAY_MAILER_ARGS [IPC $h] The arguments passed to the relay mailer. +SMTP_MAILER_CHARSET [undefined] If defined, messages containing 8-bit data + that ARRIVE from an address that resolves to one of + the SMTP mailers and which are converted to MIME will + be labelled with this character set. +UUCP_MAILER_FLAGS [undefined] Flags added to UUCP mailer. Default + flags are `DFMhuU' (and `m' for uucp-new mailer, + minus `U' for uucp-dom mailer). +UUCP_MAILER_ARGS [uux - -r -z -a$g -gC $h!rmail ($u)] The arguments + passed to the UUCP mailer. +UUCP_MAILER_MAX [100000] The maximum size message accepted for + transmission by the UUCP mailers. +UUCP_MAILER_CHARSET [undefined] If defined, messages containing 8-bit data + that ARRIVE from an address that resolves to one of + the UUCP mailers and which are converted to MIME will + be labelled with this character set. +FAX_MAILER_PATH [/usr/local/lib/fax/mailfax] The program used to + submit FAX messages. +FAX_MAILER_MAX [100000] The maximum size message accepted for + transmission by FAX. +POP_MAILER_PATH [/usr/lib/mh/spop] The pathname of the POP mailer. +POP_MAILER_FLAGS [Penu] Flags added to POP mailer. Flags "lsDFM" + are always added. +POP_MAILER_ARGS [pop $u] The arguments passed to the POP mailer. +PROCMAIL_MAILER_FLAGS [Shu] Flags added to Procmail mailer. Flags + ``DFMmn'' are always set. +PROCMAIL_MAILER_ARGS [procmail -m $h $f $u] The arguments passed to + the Procmail mailer. +PROCMAIL_MAILER_MAX [undefined] If set, the maximum size message that + will be accepted by the procmail mailer. +MAIL11_MAILER_PATH [/usr/etc/mail11] The path to the mail11 mailer. +MAIL11_MAILER_FLAGS [nsFx] Flags for the mail11 mailer. +MAIL11_MAILER_ARGS [mail11 $g $x $h $u] Arguments passed to the mail11 + mailer. +PH_MAILER_PATH [/usr/local/etc/phquery] The path to the phquery + program. +PH_MAILER_FLAGS [ehmu] Flags for the phquery mailer. +PH_MAILER_ARGS [phquery -- $u] -- arguments to the phquery mailer. +CYRUS_MAILER_FLAGS [A5@] The flags used by the cyrus mailer. The + flags lsDFMnP are always included. +CYRUS_MAILER_PATH [/usr/cyrus/bin/deliver] The progam used to deliver + cyrus mail. +CYRUS_MAILER_ARGS [deliver -e -m $h -- $u] The arguments passed + to deliver cyrus mail. +CYRUS_BB_MAILER_FLAGS [undefined] The flags used by the cyrusbb + mailer. The flags lsDFMnP are always included. +CYRUS_BB_MAILER_ARGS [deliver -e -m $u] The arguments passed + to deliver cyrusbb mail. + + + ++---------+ +| DOMAINS | ++---------+ + +You will probably want to collect domain-dependent defines into one +file, referenced by the DOMAIN macro. For example, our Berkeley +domain file includes definitions for several internal distinguished +hosts: + +UUCP_RELAY The host that will accept UUCP-addressed email. + If not defined, all UUCP sites must be directly + connected. +BITNET_RELAY The host that will accept BITNET-addressed email. + If not defined, the .BITNET pseudo-domain won't work. +DECNET_RELAY The host that will accept DECNET-addressed email. + If not defined, the .DECNET pseudo-domain and addresses + of the form node::user will not work. +FAX_RELAY The host that will accept mail to the .FAX pseudo-domain. + The "fax" mailer overrides this value. +LOCAL_RELAY DEPRECATED. The site that will handle unqualified + names -- that is, names with out an @domain extension. + If not set, they are assumed to belong on this machine. + This allows you to have a central site to store a + company- or department-wide alias database. This + only works at small sites, and only with some user + agents. +LUSER_RELAY The site that will handle lusers -- that is, apparently + local names that aren't local accounts or aliases. + +Any of these can be either ``mailer:hostname'' (in which case the +mailer is the internal mailer name, such as ``uucp-new'' and the hostname +is the name of the host as appropriate for that mailer) or just a +``hostname'', in which case a default mailer type (usually ``relay'', +a variant on SMTP) is used. WARNING: if you have a wildcard MX +record matching your domain, you probably want to define these to +have a trailing dot so that you won't get the mail diverted back +to yourself. + +The domain file can also be used to define a domain name, if needed +(using "DD<domain>") and set certain site-wide features. If all hosts +at your site masquerade behind one email name, you could also use +MASQUERADE_AS here. + +You do not have to define a domain -- in particular, if you are a +single machine sitting off somewhere, it is probably more work than +it's worth. This is just a mechanism for combining "domain dependent +knowledge" into one place. + ++---------+ +| MAILERS | ++---------+ + +There are fewer mailers supported in this version than the previous +version, owing mostly to a simpler world. As a general rule, put the +MAILER definitions last in your .mc file, and always put MAILER(smtp) +before MAILER(uucp) -- several features and definitions will modify +the definition of mailers, and the smtp mailer modifies the UUCP +mailer. + +local The local and prog mailers. You will almost always + need these; the only exception is if you relay ALL + your mail to another site. This mailer is included + automatically. + +smtp The Simple Mail Transport Protocol mailer. This does + not hide hosts behind a gateway or another other + such hack; it assumes a world where everyone is + running the name server. This file actually defines + four mailers: "smtp" for regular (old-style) SMTP to + other servers, "esmtp" for extended SMTP to other + servers, "smtp8" to do SMTP to other servers without + converting 8-bit data to MIME (essentially, this is + your statement that you know the other end is 8-bit + clean even if it doesn't say so), and "relay" for + transmission to our RELAY_HOST, LUSER_RELAY, or + MAILER_HUB. + +uucp The Unix-to-Unix Copy Program mailer. Actually, this + defines two mailers, "uucp-old" (a.k.a. "uucp") and + "uucp-new" (a.k.a. "suucp"). The latter is for when you + know that the UUCP mailer at the other end can handle + multiple recipients in one transfer. If the smtp mailer + is also included in your configuration, two other mailers + ("uucp-dom" and "uucp-uudom") are also defined [warning: + you MUST specify MAILER(smtp) before MAILER(uucp)]. When you + include the uucp mailer, sendmail looks for all names in + the $=U class and sends them to the uucp-old mailer; all + names in the $=Y class are sent to uucp-new; and all + names in the $=Z class are sent to uucp-uudom. Note that + this is a function of what version of rmail runs on + the receiving end, and hence may be out of your control. + See the section below describing UUCP mailers in more + detail. + +usenet Usenet (network news) delivery. If this is specified, + an extra rule is added to ruleset 0 that forwards all + local email for users named ``group.usenet'' to the + ``inews'' program. Note that this works for all groups, + and may be considered a security problem. + +fax Facsimile transmission. This is experimental and based + on Sam Leffler's FlexFAX software. For more information, + see below. + +pop Post Office Protocol. + +procmail An interface to procmail (does not come with sendmail). + This is designed to be used in mailertables. For example, + a common question is "how do I forward all mail for a given + domain to a single person?". If you have this mailer + defined, you could set up a mailertable reading: + + host.com procmail:/etc/procmailrcs/host.com + + with the file /etc/procmailrcs/host.com reading: + + :0 # forward mail for host.com + ! -oi -f $1 person@other.host + + This would arrange for (anything)@host.com to be sent + to person@other.host. Within the procmail script, $1 is + the name of the sender and $2 is the name of the recipient. + If you use this with FEATURE(local_procmail), the FEATURE + should be listed first. + +mail11 The DECnet mail11 mailer, useful only if you have the mail11 + program from gatekeeper.dec.com:/pub/DEC/gwtools (and + DECnet, of course). This is for Phase IV DECnet support; + if you have Phase V at your site you may have additional + problems. + +phquery The phquery program. This is somewhat counterintuitively + referenced as the "ph" mailer internally. It can be used + to do CCSO name server lookups. The phquery program, which + this mailer uses, is distributed with the ph client. + +cyrus The cyrus and cyrusbb mailers. The cyrus mailer delivers to + a local cyrus user. this mailer can make use of the + "user+detail@local.host" syntax; it will deliver the mail to + the user's "detail" mailbox if the mailbox's ACL permits. + The cyrusbb mailer delivers to a system-wide cyrus mailbox + if the mailbox's ACL permits. + + +The local mailer accepts addresses of the form "user+detail", where +the "+detail" is not used for mailbox matching but is available +to certain local mail programs (in particular, see FEATURE(local_procmail)). +For example, "eric", "eric+sendmail", and "eric+sww" all indicate +the same user, but additional arguments <null>, "sendmail", and "sww" +may be provided for use in sorting mail. + + ++----------+ +| FEATURES | ++----------+ + +Special features can be requested using the "FEATURE" macro. For +example, the .mc line: + + FEATURE(use_cw_file) + +tells sendmail that you want to have it read an /etc/sendmail.cw +file to get values for class $=w. The FEATURE may contain a single +optional parameter -- for example: + + FEATURE(mailertable, dbm /usr/lib/mailertable) + +Available features are: + +use_cw_file Read the file /etc/sendmail.cw file to get alternate + names for this host. This might be used if you were + on a host that MXed for a dynamic set of other + hosts. If the set is static, just including the line + "Cw<name1> <name2> ..." is probably superior. + The actual filename can be overridden by redefining + confCW_FILE. + +use_ct_file Read the file /etc/sendmail.ct file to get the names + of users that will be ``trusted'', that is, able to + set their envelope from address using -f without + generating a warning message. + The actual filename can be overridden by redefining + confCT_FILE. + +redirect Reject all mail addressed to "address.REDIRECT" with + a ``551 User not local; please try <address>'' message. + If this is set, you can alias people who have left + to their new address with ".REDIRECT" appended. + +nouucp Don't do anything special with UUCP addresses at all. + +nocanonify Don't pass addresses to $[ ... $] for canonification. + This would generally only be used by sites that only + act as mail gateways or which have user agents that do + full canonification themselves. You may also want to + use "define(`confBIND_OPTS',`-DNSRCH -DEFNAMES')" to + turn off the usual resolver options that do a similar + thing. + +stickyhost If set, email sent to "user@local.host" are marked + as "sticky" -- that is, the local addresses aren't + matched against UDB and don't go through ruleset 5. + This is used if you want a set up where "user" is + not necessarily the same as "user@local.host", e.g., + to make a distinct domain-wide namespace. Prior to + 8.7 this was the default, and notsticky was used to + turn this off. + +mailertable Include a "mailer table" which can be used to override + routing for particular domains. The argument of the + FEATURE may be the key definition. If none is specified, + the definition used is: + hash -o /etc/mailertable + Keys in this database are fully qualified domain names + or partial domains preceded by a dot -- for example, + "vangogh.CS.Berkeley.EDU" or ".CS.Berkeley.EDU". + Values must be of the form: + mailer:domain + where "mailer" is the internal mailer name, and "domain" + is where to send the message. These maps are not + reflected into the message header. + +domaintable Include a "domain table" which can be used to provide + domain name mapping. Use of this should really be + limited to your own domains. It may be useful if you + change names (e.g., your company changes names from + oldname.com to newname.com). The argument of the + FEATURE may be the key definition. If none is specified, + the definition used is: + hash -o /etc/domaintable + The key in this table is the domain name; the value is + the new (fully qualified) domain. Anything in the + domaintable is reflected into headers; that is, this + is done in ruleset 3. + +bitdomain Look up bitnet hosts in a table to try to turn them into + internet addresses. The table can be built using the + bitdomain program contributed by John Gardiner Myers. + The argument of the FEATURE may be the key definition; if + none is specified, the definition used is: + hash -o /etc/bitdomain.db + Keys are the bitnet hostname; values are the corresponding + internet hostname. + +uucpdomain Similar feature for UUCP hosts. The default map definition + is: + hash -o /etc/uudomain.db + At the moment there is no automagic tool to build this + database. + +always_add_domain + Include the local host domain even on locally delivered + mail. Normally it is not added unless it is already + present. + +allmasquerade If masquerading is enabled (using MASQUERADE_AS), this + feature will cause recipient addresses to also masquerade + as being from the masquerade host. Normally they get + the local hostname. Although this may be right for + ordinary users, it can break local aliases. For example, + if you send to "localalias", the originating sendmail will + find that alias and send to all members, but send the + message with "To: localalias@masqueradehost". Since that + alias likely does not exist, replies will fail. Use this + feature ONLY if you can guarantee that the ENTIRE + namespace on your masquerade host supersets all the + local entries. + +nodns We aren't running DNS at our site (for example, + we are UUCP-only connected). It's hard to consider + this a "feature", but hey, it had to go somewhere. + +nullclient This is a special case -- it creates a stripped down + configuration file containing nothing but support for + forwarding all mail to a central hub via a local + SMTP-based network. The argument is the name of that + hub. + + The only other feature that should be used in conjunction + with this one is "nocanonify" (this causes addresses to + be sent unqualified via the SMTP connection; normally + they are qualifed with the masquerade name, which + defaults to the name of the hub machine). No mailers + should be defined. No aliasing or forwarding is done. + +local_procmail Use procmail as the local mailer. This mailer can + make use of the "user+indicator@local.host" syntax; + normally the +indicator is just tossed, but by default + it is passed as the -a argument to procmail. The + argument to this feature is the pathname of procmail, + which defaults to /usr/local/bin/procmail. + +bestmx_is_local Accept mail as though locally addressed for any host that + lists us as the best possible MX record. This generates + additional DNS traffic, but should be OK for low to + medium traffic hosts. THIS FEATURE IS FUNDAMENTALLY + INCOMPATIBLE WITH WILDCARD MX RECORDS!!! If you have + a wildcard MX record that matches your domain, you + cannot use this feature. + +smrsh Use the SendMail Restricted SHell (smrsh) provided + with the distribution instead of /bin/sh for mailing + to programs. This improves the ability of the local + system administrator to control what gets run via + e-mail. If an argument is provided it is used as the + pathname to smrsh; otherwise, /usr/local/etc/smrsh is + assumed. + + ++-------+ +| HACKS | ++-------+ + +Some things just can't be called features. To make this clear, +they go in the hack subdirectory and are referenced using the HACK +macro. These will tend to be site-dependent. The release +includes the Berkeley-dependent "cssubdomain" hack (that makes +sendmail accept local names in either Berkeley.EDU or CS.Berkeley.EDU; +this is intended as a short-term aid while we move hosts into +subdomains. + + ++--------------------+ +| SITE CONFIGURATION | ++--------------------+ + + ***************************************************** + * This section is really obsolete, and is preserved * + * only for back compatibility. You should plan on * + * using mailertables for new installations. In * + * particular, it doesn't work for the newer forms * + * of UUCP mailers, such as uucp-uudom. * + ***************************************************** + +Complex sites will need more local configuration information, such as +lists of UUCP hosts they speak with directly. This can get a bit more +tricky. For an example of a "complex" site, see cf/ucbvax.mc. + +If your host is known by several different names, you need to augment +the $=w class. This is a list of names by which you are known, and +anything sent to an address using a host name in this list will be +treated as local mail. You can do this in two ways: either create +the file /etc/sendmail.cw containing a list of your aliases (one per +line), and use ``FEATURE(use_cw_file)'' in the .mc file, or add the +line: + + Cw alias.host.name + +at the end of that file. See the ``vangogh.mc'' file for an example. +Be sure you use the fully-qualified name of the host, rather than a +short name. + +The SITECONFIG macro allows you to indirectly reference site-dependent +configuration information stored in the siteconfig subdirectory. For +example, the line + + SITECONFIG(uucp.ucbvax, ucbvax, U) + +reads the file uucp.ucbvax for local connection information. The +second parameter is the local name (in this case just "ucbvax" since +it is locally connected, and hence a UUCP hostname). The third +parameter is the name of both a macro to store the local name (in +this case, $U) and the name of the class (e.g., $=U) in which to store +the host information read from the file. Another SITECONFIG line reads + + SITECONFIG(uucp.ucbarpa, ucbarpa.Berkeley.EDU, W) + +This says that the file uucp.ucbarpa contains the list of UUCP sites +connected to ucbarpa.Berkeley.EDU. The $=W class will be used to +store this list, and $W is defined to be ucbarpa.Berkeley.EDU, that +is, the name of the relay to which the hosts listed in uucp.ucbarpa +are connected. [The machine ucbarpa is gone now, but I've left +this out-of-date configuration file around to demonstrate how you +might do this.] + +Note that the case of SITECONFIG with a third parameter of ``U'' is +special; the second parameter is assumed to be the UUCP name of the +local site, rather than the name of a remote site, and the UUCP name +is entered into $=w (the list of local hostnames) as $U.UUCP. + +The siteconfig file (e.g., siteconfig/uucp.ucbvax.m4) contains nothing +more than a sequence of SITE macros describing connectivity. For +example: + + SITE(cnmat) + SITE(sgi olympus) + +The second example demonstrates that you can use two names on the +same line; these are usually aliases for the same host (or are at +least in the same company). + + ++--------------------+ +| USING UUCP MAILERS | ++--------------------+ + +It's hard to get UUCP mailers right because of the extremely ad hoc +nature of UUCP addressing. These config files are really designed +for domain-based addressing, even for UUCP sites. + +There are four UUCP mailers available. The choice of which one to +use is partly a matter of local preferences and what is running at +the other end of your UUCP connection. Unlike good protocols that +define what will go over the wire, UUCP uses the policy that you +should do what is right for the other end; if they change, you have +to change. This makes it hard to do the right thing, and discourages +people from updating their software. In general, if you can avoid +UUCP, please do. + +The major choice is whether to go for a domainized scheme or a +non-domainized scheme. This depends entirely on what the other +end will recognize. If at all possible, you should encourage the +other end to go to a domain-based system -- non-domainized addresses +don't work entirely properly. + +The four mailers are: + + uucp-old (obsolete name: "uucp") + This is the oldest, the worst (but the closest to UUCP) way of + sending messages accros UUCP connections. It does bangify + everything and prepends $U (your UUCP name) to the sender's + address (which can already be a bang path itself). It can + only send to one address at a time, so it spends a lot of + time copying duplicates of messages. Avoid this if at all + possible. + + uucp-new (obsolete name: "suucp") + The same as above, except that it assumes that in one rmail + command you can specify several recipients. It still has a + lot of other problems. + + uucp-dom + This UUCP mailer keeps everything as domain addresses. + Basically, it uses the SMTP mailer rewriting rules. This mailer + is only included if MAILER(smtp) is also specified. + + Unfortunately, a lot of UUCP mailer transport agents require + bangified addresses in the envelope, although you can use + domain-based addresses in the message header. (The envelope + shows up as the From_ line on UNIX mail.) So.... + + uucp-uudom + This is a cross between uucp-new (for the envelope addresses) + and uucp-dom (for the header addresses). It bangifies the + envelope sender (From_ line in messages) without adding the + local hostname, unless there is no host name on the address + at all (e.g., "wolf") or the host component is a UUCP host name + instead of a domain name ("somehost!wolf" instead of + "some.dom.ain!wolf"). This is also included only if MAILER(smtp) + is also specified. + +Examples: + +We are on host grasp.insa-lyon.fr (UUCP host name "grasp"). The +following summarizes the sender rewriting for various mailers. + +Mailer sender rewriting in the envelope +------ ------ ------------------------- +uucp-{old,new} wolf grasp!wolf +uucp-dom wolf wolf@grasp.insa-lyon.fr +uucp-uudom wolf grasp.insa-lyon.fr!wolf + +uucp-{old,new} wolf@fr.net grasp!fr.net!wolf +uucp-dom wolf@fr.net wolf@fr.net +uucp-uudom wolf@fr.net fr.net!wolf + +uucp-{old,new} somehost!wolf grasp!somehost!wolf +uucp-dom somehost!wolf somehost!wolf@grasp.insa-lyon.fr +uucp-uudom somehost!wolf grasp.insa-lyon.fr!somehost!wolf + +If you are using one of the domainized UUCP mailers, you really want +to convert all UUCP addresses to domain format -- otherwise, it will +do it for you (and probably not the way you expected). For example, +if you have the address foo!bar!baz (and you are not sending to foo), +the heuristics will add the @uucp.relay.name or @local.host.name to +this address. However, if you map foo to foo.host.name first, it +will not add the local hostname. You can do this using the uucpdomain +feature. + + ++-------------------+ +| TWEAKING RULESETS | ++-------------------+ + +For more complex configurations, you can define special rules. +The macro LOCAL_RULE_3 introduces rules that are used in canonicalizing +the names. Any modifications made here are reflected in the header. + +A common use is to convert old UUCP addreses to SMTP addresses using +the UUCPSMTP macro. For example: + + LOCAL_RULE_3 + UUCPSMTP(decvax, decvax.dec.com) + UUCPSMTP(research, research.att.com) + +will cause addresses of the form "decvax!user" and "research!user" +to be converted to "user@decvax.dec.com" and "user@research.att.com" +respectively. + +This could also be used to look up hosts in a database map: + + LOCAL_RULE_3 + R$* < @ $+ > $* $: $1 < @ $(hostmap $2 $) > $3 + +This map would be defined in the LOCAL_CONFIG portion, as shown below. + +Similarly, LOCAL_RULE_0 can be used to introduce new parsing rules. +For example, new rules are needed to parse hostnames that you accept +via MX records. For example, you might have: + + LOCAL_RULE_0 + R$+ <@ host.dom.ain.> $#uucp $@ cnmat $: $1 < @ host.dom.ain.> + +You would use this if you had installed an MX record for cnmat.Berkeley.EDU +pointing at this host; this rule catches the message and forwards it on +using UUCP. + +You can also tweak rulesets 1 and 2 using LOCAL_RULE_1 and LOCAL_RULE_2. +These rulesets are normally empty. + +A similar macro is LOCAL_CONFIG. This introduces lines added after the +boilerplate option setting but before rulesets, and can be used to +declare local database maps or whatever. For example: + + LOCAL_CONFIG + Khostmap hash /etc/hostmap.db + Kyplocal nis -m hosts.byname + + ++---------------------------+ +| MASQUERADING AND RELAYING | ++---------------------------+ + +You can have your host masquerade as another using + + MASQUERADE_AS(host.domain) + +This causes outgoing SMTP mail to be labeled as coming from the +indicated domain, rather than $j. One normally masquerades as one +of one's own subdomains (for example, it's unlikely that I would +choose to masquerade as an MIT site). + +The masquerade name is not normally canonified, so it is important +that it be your One True Name, that is, fully qualified and not a +CNAME. + +Normally the only addresses that are masqueraded are those that come +from this host (that is, are either unqualified or in $=w, the list +of local domain names). You can augment this list using + + MASQUERADE_DOMAIN(otherhost.domain) + +The effect of this is that although mail to user@otherhost.domain +will not be delivered locally, any mail including any user@otherhost.domain +will, when relayed, be rewritten to have the MASQUERADE_AS address. +This can be a space-separated list of names. + +If these names are in a file, you can use + + MASQUERADE_DOMAIN_FILE(filename) + +to read the list of names from the indicated file. + +Normally only header addresses are masqueraded. If you want to +masquerade the envelope as well, use + + FEATURE(masquerade_envelope) + +There are always users that need to be "exposed" -- that is, their +internal site name should be displayed instead of the masquerade name. +Root is an example. You can add users to this list using + + EXPOSED_USER(usernames) + +This adds users to class E; you could also use something like + + FE/etc/sendmail.cE + +You can also arrange to relay all unqualified names (that is, names +without @host) to a relay host. For example, if you have a central +email server, you might relay to that host so that users don't have +to have .forward files or aliases. You can do this using + + define(`LOCAL_RELAY', mailer:hostname) + +The ``mailer:'' can be omitted, in which case the mailer defaults to +"smtp". There are some user names that you don't want relayed, perhaps +because of local aliases. A common example is root, which may be +locally aliased. You can add entries to this list using + + LOCAL_USER(usernames) + +This adds users to class L; you could also use something like + + FL/etc/sendmail.cL + +If you want all incoming mail sent to a centralized hub, as for a +shared /var/spool/mail scheme, use + + define(`MAIL_HUB', mailer:hostname) + +Again, ``mailer:'' defaults to "smtp". If you define both LOCAL_RELAY +and MAIL_HUB _AND_ you have FEATURE(stickyhost), unqualified names will +be sent to the LOCAL_RELAY and other local names will be sent to MAIL_HUB. +Names in $=L will be delivered locally, so you MUST have aliases or +.forward files for them. + +For example, if are on machine mastodon.CS.Berkeley.EDU and you have +FEATURE(stickyhost), the following combinations of settings will have the +indicated effects: + +email sent to.... eric eric@mastodon.CS.Berkeley.EDU + +LOCAL_RELAY set to mail.CS.Berkeley.EDU (delivered locally) +mail.CS.Berkeley.EDU (no local aliasing) (aliasing done) + +MAIL_HUB set to mammoth.CS.Berkeley.EDU mammoth.CS.Berkeley.EDU +mammoth.CS.Berkeley.EDU (aliasing done) (aliasing done) + +Both LOCAL_RELAY and mail.CS.Berkeley.EDU mammoth.CS.Berkeley.EDU +MAIL_HUB set as above (no local aliasing) (aliasing done) + +If you do not have FEATURE(stickyhost) set, then LOCAL_RELAY and +MAIL_HUB act identically, with MAIL_HUB taking precedence. + +If you want all outgoing mail to go to a central relay site, define +SMART_HOST as well. Briefly: + + LOCAL_RELAY applies to unqualifed names (e.g., "eric"). + MAIL_HUB applies to names qualified with the name of the + local host (e.g., "eric@mastodon.CS.Berkeley.EDU"). + SMART_HOST applies to names qualified with other hosts. + +However, beware that other relays (e.g., UUCP_RELAY, BITNET_RELAY, +DECNET_RELAY, and FAX_RELAY) take precedence over SMART_HOST, so if you +really want absolutely everything to go to a single central site you will +need to unset all the other relays -- or better yet, find or build a +minimal config file that does this. + + ++-------------------------------+ +| NON-SMTP BASED CONFIGURATIONS | ++-------------------------------+ + +These configuration files are designed primarily for use by SMTP-based +sites. I don't pretend that they are well tuned for UUCP-only or +UUCP-primarily nodes (the latter is defined as a small local net +connected to the rest of the world via UUCP). However, there is one +hook to handle some special cases. + +You can define a ``smart host'' that understands a richer address syntax +using: + + define(`SMART_HOST', mailer:hostname) + +In this case, the ``mailer:'' defaults to "relay". Any messages that +can't be handled using the usual UUCP rules are passed to this host. + +If you are on a local SMTP-based net that connects to the outside +world via UUCP, you can use LOCAL_NET_CONFIG to add appropriate rules. +For example: + + define(`SMART_HOST', suucp:uunet) + LOCAL_NET_CONFIG + R$* < @ $* .$m. > $* $#smtp $@ $2.$m. $: $1 < @ $2.$m. > $3 + +This will cause all names that end in your domain name ($m) via +SMTP; anything else will be sent via suucp (smart UUCP) to uunet. +If you have FEATURE(nocanonify), you may need to omit the dots after +the $m. If you are running a local DNS inside your domain which is +not otherwise connected to the outside world, you probably want to +use: + + define(`SMART_HOST', smtp:fire.wall.com) + LOCAL_NET_CONFIG + R$* < @ $* . > $* $#smtp $@ $2. $: $1 < @ $2. > $3 + +That is, send directly only to things you found in your DNS lookup; +anything else goes through SMART_HOST. + +If you are not running DNS at all, it is important to use +FEATURE(nodns) to avoid having sendmail queue everything waiting +for the name server to come up. + + ++-----------+ +| WHO AM I? | ++-----------+ + +Normally, the $j macro is automatically defined to be your fully +qualified domain name (FQDN). Sendmail does this by getting your +host name using gethostname and then calling gethostbyname on the +result. For example, in some environments gethostname returns +only the root of the host name (such as "foo"); gethostbyname is +supposed to return the FQDN ("foo.bar.com"). In some (fairly rare) +cases, gethostbyname may fail to return the FQDN. In this case +you MUST define confDOMAIN_NAME to be your fully qualified domain +name. This is usually done using: + + Dmbar.com + define(`confDOMAIN_NAME', `$w.$m')dnl + + ++--------------------+ +| USING MAILERTABLES | ++--------------------+ + +To use FEATURE(mailertable), you will have to create an external +database containing the routing information for various domains. +For example, a mailertable file in text format might be: + + .my.domain xnet:%1.my.domain + uuhost1.my.domain suucp:uuhost1 + .bitnet smtp:relay.bit.net + +This should normally be stored in /etc/mailertable. The actual +database version of the mailertable is built using: + + makemap hash /etc/mailertable.db < /etc/mailertable + +The semantics are simple. Any LHS entry that does not begin with +a dot matches the full host name indicated. LHS entries beginning +with a dot match anything ending with that domain name -- that is, +they can be thought of as having a leading "*" wildcard. Matching +is done in order of most-to-least qualified -- for example, even +though ".my.domain" is listed first in the above example, an entry +of "uuhost1.my.domain" will match the second entry since it is +more explicit. + +The RHS should always be a "mailer:host" pair. The mailer is the +configuration name of a mailer (that is, an `M' line in the +sendmail.cf file). The "host" will be the hostname passed to +that mailer. In domain-based matches (that is, those with leading +dots) the "%1" may be used to interpolate the wildcarded part of +the host name. For example, the first line above sends everything +addressed to "anything.my.domain" to that same host name, but using +the (presumably experimental) xnet mailer. + +In some cases you may want to temporarily turn off MX records, +particularly on gateways. For example, you may want to MX +everything in a domain to one machine that then forwards it +directly. To do this, you might use the DNS configuration: + + *.domain. IN MX 0 relay.machine + +and on relay.machine use the mailertable: + + .domain smtp:[gateway.domain] + +The [square brackets] turn off MX records for this host only. +If you didn't do this, the mailertable would use the MX record +again, which would give you an MX loop. + + ++--------------------------------+ +| USING USERDB TO MAP FULL NAMES | ++--------------------------------+ + +The user database was not originally intended for mapping full names +to login names (e.g., Eric.Allman => eric), but some people are using +it that way. (I would recommend that you set up aliases for this +purpose instead -- since you can specify multiple alias files, this +is fairly easy.) The intent was to locate the default maildrop at +a site, but allow you to override this by sending to a specific host. + +If you decide to set up the user database in this fashion, it is +imperative that you not use FEATURE(stickyhost) -- otherwise, +e-mail sent to Full.Name@local.host.name will be rejected. + +To build the internal form of the user database, use: + + makemap btree /usr/data/base.db < /usr/data/base.txt + +As a general rule, I am adamantly opposed to using full names as +e-mail addresses, since they are not in any sense unique. For example, +the Unix software-development community has two Andy Tannenbaums, +at least two well-known Peter Deutsches, and at one time Bell Labs +had two Stephen R. Bournes with offices along the same hallway. +Which one will be forced to suffer the indignity of being +Stephen_R_Bourne_2? The less famous of the two, or the one that +was hired later? + +Finger should handle full names (and be fuzzy). Mail should use +handles, and not be fuzzy. [Not that I expect anyone to pay any +attention to my opinions.] + + ++--------------------------------+ +| MISCELLANEOUS SPECIAL FEATURES | ++--------------------------------+ + +Plussed users + Sometimes it is convenient to merge configuration on a + centralized mail machine, for example, to forward all + root mail to a mail server. In this case it might be + useful to be able to treat the root addresses as a class + of addresses with subtle differences. You can do this + using plussed users. For example, a client might include + the alias: + + root: root+client1@server + + On the server, this will match an alias for "root+client1". + If that is not found, the alias "root+*" will be tried, + then "root". + + ++----------------+ +| SECURITY NOTES | ++----------------+ + +A lot of sendmail security comes down to you. Sendmail 8 is much +more careful about checking for security problems than previous +versions, but there are some things that you still need to watch +for. In particular: + +* Make sure the aliases file isn't writable except by trusted + system personnel. This includes both the text and database + version. + +* Make sure that other files that sendmail reads, such as the + mailertable, is only writable by trusted system personnel. + +* The queue directory should not be world writable PARTICULARLY + if your system allows "file giveaways" (that is, if a non-root + user can chown any file they own to any other user). + +* If your system allows file giveaways, DO NOT create a publically + writable directory for forward files. This will allow anyone + to steal anyone else's e-mail. Instead, create a script that + copies the .forward file from users' home directories once a + night (if you want the non-NFS-mounted forward directory). + +* If your system allows file giveaways, you'll find that + sendmail is much less trusting of :include: files -- in + particular, you'll have to have /SENDMAIL/ANY/SHELL/ in + /etc/shells before they will be trusted (that is, before + files and programs listed in them will be honored). + +In general, file giveaways are a mistake -- if you can turn them +off I recommend you do so. + + ++------------------+ +| FlexFAX SOFTWARE | ++------------------+ + +Sam Leffler's FlexFAX software is still in beta test -- but he expects a +public version out "later this week" [as of 3/1/93]. The following +blurb is direct from Sam: + + $Header: /usr/people/sam/fax/RCS/HOWTO,v 1.14 93/05/24 11:42:16 sam Exp $ + + How To Obtain This Software (in case all you get is this file) + -------------------------------------------------------------- + The source code is available for public ftp on + sgi.com sgi/fax/v2.1.src.tar.Z + (192.48.153.1) + + You can also obtain inst'able images for Silicon Graphics machines from + sgi.com sgi/fax/v2.1.inst.tar + (192.48.153.1) + + For example, + % ftp -n sgi.com + .... + ftp> user anonymous + ... <type in password> + ftp> cd sgi/fax + ftp> binary + ftp> get v2.1.src.tar.Z + + In general, the latest version of the 2.1 release of the software is + always available as "v2.1.src.tar.Z" or "v2.1.inst.tar" in the ftp + directory. This file is a link to the appropriate released version (so + don't waste your time retrieving the linked file as well!) Any files of + the form v2.1.*.patch are shell scripts that can be used to patch older + versions of the source code. For example, the file v2.1.0.patch would + contain patches to update v2.1.0.tar.Z. (Note to beta testers: this is + different than the naming conventions used during beta testing.) Patch + files only work to go between consecutive versions, so if you are + multiple versions behind the latest release, you will need to apply + each patch file between your current version and the latest. + + + Obtaining the Software by Electronic Mail + ----------------------------------------- + Do not send me requests for the software; they will be ignored (without + response). If you cannot use FTP at all, there is a service called + "ftpmail" available from gatekeeper.dec.com: you can send e-mail to + this machine and it will use FTP to retrieve files for you and send you + the files back again via e-mail. To find out more about the ftpmail + service, send a message to "ftpmail@gatekeeper.dec.com" whose body + consists of the single line "help". + + + Obtaining the Software Within Silicon Graphics + ---------------------------------------------- + Internal to Silicon Graphics there are inst'able images on the host + flake.asd in the directory /usr/dist. Thus you can do something like: + + % inst -f flake.asd.sgi.com:/usr/dist/flexfax + + to install the latest version of the software on your machine. + + + What to do Once You've Retrieved Stuff + -------------------------------------- + The external distributions come in a compressed or uncompressed tar + file. To extract the source distribution: + + % zcat v2.1.src.tar.Z | tar xf - + + (uncompress and extract individual files in current directory). To + unpack and install the client portion of the inst'able distribution: + + % mkdir dist + % cd dist; tar xf ../v2.1.inst.tar; cd .. + % inst -f dist/flexfax + ... + inst> go + + (Note, the dist subdirectory is because some versions of inst fail if + the files are in the current directory.) Server binaries are also + included in the inst'able images as flexfax.server.*. They are not + installed by default, so to get them also you need to do: + + % inst -f flexfax + ... + inst> install flexfax.server.* + inst> go + + The SGI binaries were built for Version 4.0.5H of the IRIX operating + system. They should work w/o problem on earlier versions of the + system, but I have not fully tested this. Also, note that to install a + server on an SGI machine, you need to have installed the Display + PostScript execution environment product (dps_eoe). Otherwise, the fax + server will not be able to convert PostScript to facsimile for + transmission. + + If you are working from the source distribution, look at the file + README in the top of the source tree. If you are working from the inst + images, the subsystem flexfax.man.readme contains the README file and + other useful pieces of information--the installed files are placed in + the directory /usr/local/doc/flexfax). Basically you will need to run + the faxaddmodem script to setup and configure your fax modem. Consult + the README file and the manual page for faxaddmodem for information. + + + FlexFAX Mail List + ----------------- + A mailing list for users of this software is located on sgi.com. + If you want to join this mailing list or have a list-related request + such as getting your name removed from it, send a request to + + majordomo@whizzer.wpd.sgi.com + + For example, to subscribe, send the line "subscribe flexfax" in + the body of your message. The line "help" will return a list of + the commands understood by the mailing list management software. + + Submissions (including bug reports) should be directed to: + + flexfax@sgi.com + + When corresponding about this software please always specify what + version you have, what system you're running on, and, if the problem is + specific to your modem, identify the modem and firmware revision. + + ++--------------------------------+ +| TWEAKING CONFIGURATION OPTIONS | ++--------------------------------+ + +There are a large number of configuration options that don't normally +need to be changed. However, if you feel you need to tweak them, you +can define the following M4 variables. This list is shown in four +columns: the name you define, the default value for that definition, +the option or macro that is affected (either Ox for an option or Dx +for a macro), and a brief description. Greater detail of the semantics +can be found in the Installation and Operations Guide. + +Some options are likely to be deprecated in future versions -- that is, +the option is only included to provide back-compatibility. These are +marked with "*". + +Remember that these options are M4 variables, and hence may need to +be quoted. In particular, arguments with commas will usually have to +be ``double quoted, like this phrase'' to avoid having the comma +confuse things. This is common for alias file definitions and for +the read timeout. + +M4 Variable Name Configuration Description & [Default] +================ ============= ======================= +confMAILER_NAME $n macro [MAILER-DAEMON] The sender name used + for internally generated outgoing + messages. +confDOMAIN_NAME $j macro If defined, sets $j. This should + only be done if your system cannot + determine your local domain name, + and then it should be set to + $w.Foo.COM, where Foo.COM is your + domain name. +confCF_VERSION $Z macro If defined, this is appended to the + configuration version name. +confFROM_HEADER From: [$?x$x <$g>$|$g$.] The format of an + internally generated From: address. +confRECEIVED_HEADER Received: + [.$?_($?s$|from $.$_) $.by $j ($v/$Z)$?r with $r$. id $i$?u for $u$.; $b] + The format of the Received: header + in messages passed through this host. + It is unwise to try to change this. +confCW_FILE Fw class [/etc/sendmail.cw] Name of file used + to get the local additions to the $=w + (local host names) class. +confCT_FILE Ft class [/etc/sendmail.ct] Name of file used + to get the local additions to the $=t + (trusted users) class. +confTRUSTED_USERS Ct class [no default] Names of users to add to + the list of trusted users. This list + always includes root, uucp, and daemon. + See also FEATURE(use_ct_file). +confSMTP_MAILER - [smtp] The mailer name used when + SMTP connectivity is required. + One of "smtp", "smtp8", or "esmtp". +confUUCP_MAILER - [uucp-old] The mailer to be used by + default for bang-format recipient + addresses. See also discussion of + $=U, $=Y, and $=Z in the MAILER(uucp) + section. +confLOCAL_MAILER - [local] The mailer name used when + local connectivity is required. + Almost always "local". +confRELAY_MAILER - [relay] The default mailer name used + for relaying any mail (e.g., to a + BITNET_RELAY, a SMART_HOST, or + whatever). This can reasonably be + "uucp-new" if you are on a + UUCP-connected site. +confSEVEN_BIT_INPUT SevenBitInput [False] Force input to seven bits? +confEIGHT_BIT_HANDLING EightBitMode [pass8] 8-bit data handling +confALIAS_WAIT AliasWait [10m] Time to wait for alias file + rebuild until you get bored and + decide that the apparently pending + rebuild failed. +confMIN_FREE_BLOCKS MinFreeBlocks [100] Minimum number of free blocks on + queue filesystem to accept SMTP mail. + (Prior to 8.7 this was minfree/maxsize, + where minfree was the number of free + blocks and maxsize was the maximum + message size. Use confMAX_MESSAGE_SIZE + for the second value now.) +confMAX_MESSAGE_SIZE MaxMessageSize The maximum size of messages that will + be accepted (in bytes). +confBLANK_SUB BlankSub [.] Blank (space) substitution + character. +confCON_EXPENSIVE HoldExpensive [False] Avoid connecting immediately + to mailers marked expensive? +confCHECKPOINT_INTERVAL CheckpointInterval + Checkpoint queue files every N + recipients. +confDELIVERY_MODE DeliveryMode [background] Default delivery mode. +confAUTO_REBUILD AutoRebuildAliases + Automatically rebuild alias + file if needed. +confERROR_MODE ErrorMode Error message mode. +confERROR_MESSAGE ErrorHeader Error message header/file. +confSAVE_FROM_LINES SafeFromLine Save extra leading From_ lines. +confTEMP_FILE_MODE TempFileMode [0600] Temporary file mode. +confMATCH_GECOS MatchGECOS Match GECOS field. +confMAX_HOP MaxHopCount Maximum hop count. +confIGNORE_DOTS* IgnoreDots Ignore dot as terminator for incoming + messages? +confBIND_OPTS ResolverOptions Default options for DNS resolver. +confMIME_FORMAT_ERRORS* SendMimeErrors [True] Send error messages as MIME- + encapsulated messages per RFC 1344. +confFORWARD_PATH ForwardPath [$z/.forward.$w:$z/.forward] + The colon-separated list of places to + search for .forward files. N.B.: see + the Security Notes section. +confMCI_CACHE_SIZE ConnectionCacheSize + [2] Size of open connection cache. +confMCI_CACHE_TIMEOUT ConnectionCacheTimeout + [5m] Open connection cache timeout. +confUSE_ERRORS_TO* UserErrorsTo [False] Use the Errors-To: header to deliver + error messages. This should not be + necessary because of general acceptance + of the envelope/header distinction. +confLOG_LEVEL LogLevel [9] Log level. +confME_TOO MeToo Include sender in group expansions. +confCHECK_ALIASES CheckAliases [False] Check RHS of aliases when + running newaliases. Since this does + DNS lookups on every address, it can + slow down the alias rebuild process + considerably on large alias files. +confOLD_STYLE_HEADERS* OldStyleHeaders [True] Assume that headers without + special chars are old style. +confDAEMON_OPTIONS DaemonPortOptions + SMTP daemon options. +confPRIVACY_FLAGS PrivacyOptions [authwarnings] Privacy flags. +confCOPY_ERRORS_TO PostmasterCopy Address for additional copies of all + error messages. +confQUEUE_FACTOR QueueFactor Slope of queue-only function. +confDONT_PRUNE_ROUTES DontPruneRoutes Don't prune down route-addr syntax + addresses to the minimum possible. +confSAFE_QUEUE* SuperSafe [True] Commit all messages to disk + before forking. +confTO_INITIAL Timeout.initial [5m] The timeout waiting for a response + on the initial connect. +confTO_HELO Timeout.helo [5m] The timeout waiting for a response + to a HELO or EHLO command. +confTO_MAIL Timeout.mail [10m] The timeout waiting for a + response to the MAIL command. +confTO_RCPT Timeout.rcpt [1h] The timeout waiting for a response + to the RCPT command. +confTO_DATAINIT Timeout.datainit + [5m] The timeout waiting for a 354 + response from the DATA command. +confTO_DATABLOCK Timeout.datablock + [1h] The timeout waiting for a block + during DATA phase. +confTO_DATAFINAL Timeout.datafinal + [1h] The timeout waiting for a response + to the final "." that terminates a + message. +confTO_RSET Timeout.rset [5m] The timeout waiting for a response + to the RSET command. +confTO_QUIT Timeout.quit [2m] The timeout waiting for a response + to the QUIT command. +confTO_MISC Timeout.misc [2m] The timeout waiting for a response + to other SMTP commands. +confTO_COMMAND Timeout.command [1h] In server SMTP, the timeout waiting + for a command to be issued. +confTO_IDENT Timeout.ident [30s] The timeout waiting for a response + to an IDENT query. +confTO_FILEOPEN Timeout.fileopen + [60s] The timeout waiting for a file + (e.g., :include: file) to be opened. +confTO_QUEUERETURN Timeout.queuereturn + [5d] The timeout before a message is + returned as undeliverable. +confTO_QUEUERETURN_NORMAL + Timeout.queuereturn.normal + [undefined] As above, for normal + priority messages. +confTO_QUEUERETURN_URGENT + Timeout.queuereturn.urgent + [undefined] As above, for urgent + priority messages. +confTO_QUEUERETURN_NONURGENT + Timeout.queuereturn.non-urgent + [undefined] As above, for non-urgent + (low) priority messages. +confTO_QUEUEWARN Timeout.queuewarn + [4h] The timeout before a warning + message is sent to the sender telling + them that the message has been deferred. +confTO_QUEUEWARN_NORMAL Timeout.queuewarn.normal + [undefined] As above, for normal + priority messages. +confTO_QUEUEWARN_URGENT Timeout.queuewarn.urgent + [undefined] As above, for urgent + priority messages. +confTO_QUEUEWARN_NONURGENT + Timeout.queuewarn.non-urgent + [undefined] As above, for non-urgent + (low) priority messages. +confTIME_ZONE TimeZoneSpec [USE_SYSTEM] Time zone info -- can be + USE_SYSTEM to use the system's idea, + USE_TZ to use the user's TZ envariable, + or something else to force that value. +confDEF_USER_ID DefaultUser [1:1] Default user id. +confUSERDB_SPEC UserDatabaseSpec + User database specification. +confFALLBACK_MX FallbackMXhost Fallback MX host. +confTRY_NULL_MX_LIST TryNullMXList If we are the best MX for a host and + haven't made other arrangements, try + connecting to the host directly; + normally this would be a config error. +confQUEUE_LA QueueLA Load average at which queue-only + function kicks in. +confREFUSE_LA RefuseLA Load average at which incoming + SMTP connections are refused. +confWORK_RECIPIENT_FACTOR + RecipientFactor Cost of each recipient. +confSEPARATE_PROC ForkEachJob Run all deliveries in a separate + process. +confWORK_CLASS_FACTOR ClassFactor Priority multiplier for class. +confWORK_TIME_FACTOR RetryFactor Cost of each delivery attempt. +confQUEUE_SORT_ORDER QueueSortOrder Queue sort algorithm: Priority or Host. +confMIN_QUEUE_AGE MinQueueAge The minimum amount of time a job + must sit in the queue between queue + runs. This allows you to set the + queue run interval low for better + resposiveness without trying all + jobs in each run. +confDEF_CHAR_SET DefaultCharSet When converting unlabelled 8 bit + input to MIME, the character set to + use by default. +confSERVICE_SWITCH_FILE ServiceSwitchFile + The file to use for the service switch + on systems that do not have a system- + defined switch. +confDIAL_DELAY DialDelay If a connection fails, wait this long + and try again. This is to allow + "dial on demand" connections to have + enough time to complete a connection. +confNO_RCPT_ACTION NoRecipientAction + What to do if there are no legal + recipient fields (To:, Cc: or Bcc:) + in the message. Legal values can + be "none" to just leave the + nonconforming message as is, "add-to" + to add a To: header with all the + known recipients (which may expose + blind recipients), "add-apparently-to" + to do the same but use Apparently-To: + instead of To:, "add-bcc" to add an + empty Bcc: header, or + "add-to-undisclosed" to add the header + ``To: undisclosed-recipients:;''. + Default is "none". +confSAFE_FILE_ENV SafeFileEnvironment + If set, sendmail will do a chroot() + into this directory before writing + files. +confCOLON_OK_IN_ADDR ColonOkInAddr If set, colons are treated as a regular + character in addresses. If not set, + they are treated as the introducer to + the RFC 822 "group" syntax. Colons are + handled properly in route-addrs. This + option defaults on for V5 and lower + configuration files. +confMAX_QUEUE_RUN_SIZE MaxQueueRunSize If set, limit the maximum size of any + given queue run to this number of + entries. Essentially, this will stop + reading the queue directory after this + number of entries are reached; it does + _not_ pick the highest priority jobs, + so this should be as large as your + system can tolerate. If not set, there + is no limit. +confDONT_EXPAND_CNAMES DontExpandCnames + If set, $[ ... $] lookups that do DNS + based lookups do not expand CNAME + records. This currently violates the + published standards, but the IETF + seems to be moving toward legalizing + this. For example, if "FTP.Foo.ORG" + is a CNAME for "Cruft.Foo.ORG", then + with this option set a lookup of + "FTP" will return "FTP.Foo.ORG"; if + clear it returns "Cruft.FOO.ORG". N.B. + you may not see any effect until your + downstream neighbors stop doing CNAME + lookups as well. +confFROM_LINE UnixFromLine [From $g $d] The From_ line used + when sending to files or programs. +confOPERATORS OperatorChars [.:%@!^/[]+] Address operator + characters. +confSMTP_LOGIN_MSG SmtpGreetingMessage + [$j Sendmail $v/$Z; $b] + The initial (spontaneous) SMTP + greeting message. The word "ESMTP" + will be inserted between the first and + second words to convince other + sendmails to try to speak ESMTP. +confDONT_INIT_GROUPS DontInitGroups If set, the initgroups(3) routine will + never be invoked. You might want to + do this if you are running NIS and you + have a large group map, since this + call does a sequential scan of the map; + in a large site this can cause your + ypserv to run essentially full time. + If you set this, agents run on behalf + of users will only have their primary + (/etc/passwd) group permissions. + +See also the description of OSTYPE for some parameters that can be +tweaked (generally pathnames to mailers). + + ++-----------+ +| HIERARCHY | ++-----------+ + +Within this directory are several subdirectories, to wit: + +m4 General support routines. These are typically + very important and should not be changed without + very careful consideration. + +cf The configuration files themselves. They have + ".mc" suffixes, and must be run through m4 to + become complete. The resulting output should + have a ".cf" suffix. + +ostype Definitions describing a particular operating + system type. These should always be referenced + using the OSTYPE macro in the .mc file. Examples + include "bsd4.3", "bsd4.4", "sunos3.5", and + "sunos4.1". + +domain Definitions describing a particular domain, referenced + using the DOMAIN macro in the .mc file. These are + site dependent; for example, "CS.Berkeley.EDU.m4" + describes hosts in the CS.Berkeley.EDU subdomain. + +mailer Descriptions of mailers. These are referenced using + the MAILER macro in the .mc file. + +sh Shell files used when building the .cf file from the + .mc file in the cf subdirectory. + +feature These hold special orthogonal features that you might + want to include. They should be referenced using + the FEATURE macro. + +hack Local hacks. These can be referenced using the HACK + macro. They shouldn't be of more than voyeuristic + interest outside the .Berkeley.EDU domain, but who knows? + We've all got our own peccadillos. + +siteconfig Site configuration -- e.g., tables of locally connected + UUCP sites. + + ++------------------------+ +| ADMINISTRATIVE DETAILS | ++------------------------+ + +The following sections detail usage of certain internal parts of the +sendmail.cf file. Read them carefully if you are trying to modify +the current model. If you find the above descriptions adequate, these +should be {boring, confusing, tedious, ridiculous} (pick one or more). + +RULESETS (* means built in to sendmail) + + 0 * Parsing + 1 * Sender rewriting + 2 * Recipient rewriting + 3 * Canonicalization + 4 * Post cleanup + 5 * Local address rewrite (after aliasing) + 1x mailer rules (sender qualification) + 2x mailer rules (recipient qualification) + 3x mailer rules (sender header qualification) + 4x mailer rules (recipient header qualification) + 5x mailer subroutines (general) + 6x mailer subroutines (general) + 7x mailer subroutines (general) + 8x reserved + 90 Mailertable host stripping + 96 Bottom half of Ruleset 3 (ruleset 6 in old sendmail) + 97 Hook for recursive ruleset 0 call (ruleset 7 in old sendmail) + 98 Local part of ruleset 0 (ruleset 8 in old sendmail) + 99 Guaranteed null (for debugging) + + +MAILERS + + 0 local, prog local and program mailers + 1 [e]smtp, relay SMTP channel + 2 uucp-* UNIX-to-UNIX Copy Program + 3 netnews Network News delivery + 4 fax Sam Leffler's FlexFAX software + 5 mail11 DECnet mailer + + +MACROS + + A + B Bitnet Relay + C DECnet Relay + D The local domain -- usually not needed + E reserved for X.400 Relay + F FAX Relay + G + H mail Hub (for mail clusters) + I + J + K + L Luser Relay + M Masquerade (who I claim to be) + N + O + P + Q + R Relay (for unqualified names) + S Smart Host + T + U my UUCP name (if I have a UUCP connection) + V UUCP Relay (class V hosts) + W UUCP Relay (class W hosts) + X UUCP Relay (class X hosts) + Y UUCP Relay (all other hosts) + Z Version number + + +CLASSES + + A + B + C + D + E addresses that should not seem to come from $M + F hosts we forward for + G + H + I + J + K + L addresses that should not be forwarded to $R + M domains that should be mapped to $M + N + O operators that indicate network operations (cannot be in local names) + P top level pseudo-domains: BITNET, DECNET, FAX, UUCP, etc. + Q + R + S + T + U locally connected UUCP hosts + V UUCP hosts connected to relay $V + W UUCP hosts connected to relay $W + X UUCP hosts connected to relay $X + Y locally connected smart UUCP hosts + Z locally connected domain-ized UUCP hosts + . the class containing only a dot + + +M4 DIVERSIONS + + 1 Local host detection and resolution + 2 Local Ruleset 3 additions + 3 Local Ruleset 0 additions + 4 UUCP Ruleset 0 additions + 5 locally interpreted names (overrides $R) + 6 local configuration (at top of file) + 7 mailer definitions + 8 + 9 special local rulesets (1 and 2) diff --git a/usr.sbin/sendmail/cf/cf/Makefile b/usr.sbin/sendmail/cf/cf/Makefile new file mode 100644 index 000000000000..33f594377a04 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/Makefile @@ -0,0 +1,111 @@ +# @(#)Makefile 8.17 (Berkeley) 9/12/95 + +# +# This Makefile uses the new Berkeley "make" program. See Makefile.dist +# for a more vanilla version. +# +# Configuration files are created using "m4 file.mc > file.cf"; +# this may be easier than tweaking the Makefile. You do need to +# have a fairly modern M4 available (GNU m4 works). On SunOS, use +# /usr/5bin/m4. +# + +M4= m4 +#M4= /usr/src/usr.bin/m4/obj/m4 +CFDIR= .. +CHMOD= chmod +ROMODE= 444 +RM= rm -f + +.SUFFIXES: .mc .cf + +.mc.cf: + $(RM) $@ + (cd ${.CURDIR} && $(M4) ${CFDIR}/m4/cf.m4 ${@:R}.mc > obj/$@) + $(CHMOD) $(ROMODE) $@ + +ALL= generic-bsd4.4.cf generic-hpux9.cf generic-hpux10.cf \ + generic-osf1.cf generic-solaris2.cf \ + generic-sunos4.1.cf generic-ultrix4.cf \ + cs-hpux9.cf cs-osf1.cf cs-solaris2.cf \ + cs-sunos4.1.cf cs-ultrix4.cf \ + s2k-osf1.cf s2k-ultrix4.cf \ + chez.cs.cf huginn.cs.cf mail.cs.cf mail.eecs.cf mailspool.cs.cf \ + python.cs.cf ucbarpa.cf ucbvax.cf vangogh.cs.cf + +all: $(ALL) + +clean cleandir: + $(RM) $(ALL) core + +depend install: + +# this is overkill, but.... +M4FILES=\ + ${CFDIR}/domain/Berkeley.EDU.m4 \ + ${CFDIR}/domain/CS.Berkeley.EDU.m4 \ + ${CFDIR}/domain/EECS.Berkeley.EDU.m4 \ + ${CFDIR}/domain/S2K.Berkeley.EDU.m4 \ + ${CFDIR}/feature/allmasquerade.m4 \ + ${CFDIR}/feature/always_add_domain.m4 \ + ${CFDIR}/feature/bestmx_is_local.m4 \ + ${CFDIR}/feature/bitdomain.m4 \ + ${CFDIR}/feature/domaintable.m4 \ + ${CFDIR}/feature/local_procmail.m4 \ + ${CFDIR}/feature/mailertable.m4 \ + ${CFDIR}/feature/nocanonify.m4 \ + ${CFDIR}/feature/nodns.m4 \ + ${CFDIR}/feature/notsticky.m4 \ + ${CFDIR}/feature/nouucp.m4 \ + ${CFDIR}/feature/nullclient.m4 \ + ${CFDIR}/feature/redirect.m4 \ + ${CFDIR}/feature/smrsh.m4 \ + ${CFDIR}/feature/stickyhost.m4 \ + ${CFDIR}/feature/use_cw_file.m4 \ + ${CFDIR}/feature/uucpdomain.m4 \ + ${CFDIR}/hack/cssubdomain.m4 \ + ${CFDIR}/m4/cf.m4 \ + ${CFDIR}/m4/cfhead.m4 \ + ${CFDIR}/m4/nullrelay.m4 \ + ${CFDIR}/m4/proto.m4 \ + ${CFDIR}/m4/version.m4 \ + ${CFDIR}/mailer/cyrus.m4 \ + ${CFDIR}/mailer/fax.m4 \ + ${CFDIR}/mailer/local.m4 \ + ${CFDIR}/mailer/mail11.m4 \ + ${CFDIR}/mailer/pop.m4 \ + ${CFDIR}/mailer/procmail.m4 \ + ${CFDIR}/mailer/smtp.m4 \ + ${CFDIR}/mailer/usenet.m4 \ + ${CFDIR}/mailer/uucp.m4 \ + ${CFDIR}/ostype/aix3.m4 \ + ${CFDIR}/ostype/amdahl-uts.m4 \ + ${CFDIR}/ostype/aux.m4 \ + ${CFDIR}/ostype/bsd4.3.m4 \ + ${CFDIR}/ostype/bsd4.4.m4 \ + ${CFDIR}/ostype/bsdi1.0.m4 \ + ${CFDIR}/ostype/dgux.m4 \ + ${CFDIR}/ostype/domainos.m4 \ + ${CFDIR}/ostype/dynix3.2.m4 \ + ${CFDIR}/ostype/hpux9.m4 \ + ${CFDIR}/ostype/irix4.m4 \ + ${CFDIR}/ostype/irix5.m4 \ + ${CFDIR}/ostype/linux.m4 \ + ${CFDIR}/ostype/nextstep.m4 \ + ${CFDIR}/ostype/osf1.m4 \ + ${CFDIR}/ostype/ptx2.m4 \ + ${CFDIR}/ostype/riscos4.5.m4 \ + ${CFDIR}/ostype/sco3.2.m4 \ + ${CFDIR}/ostype/solaris2.m4 \ + ${CFDIR}/ostype/sunos3.5.m4 \ + ${CFDIR}/ostype/sunos4.1.m4 \ + ${CFDIR}/ostype/svr4.m4 \ + ${CFDIR}/ostype/ultrix4.m4 \ + ${CFDIR}/siteconfig/uucp.cogsci.m4 \ + ${CFDIR}/siteconfig/uucp.old.arpa.m4 \ + ${CFDIR}/siteconfig/uucp.ucbarpa.m4 \ + ${CFDIR}/siteconfig/uucp.ucbvax.m4 \ + +$(ALL): $(M4FILES) + +.include <bsd.prog.mk> diff --git a/usr.sbin/sendmail/cf/cf/chez.cs.mc b/usr.sbin/sendmail/cf/cf/chez.cs.mc new file mode 100644 index 000000000000..b30fe9ce22da --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/chez.cs.mc @@ -0,0 +1,54 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for a specific +# machine in the Computer Science Division at Berkeley, and should +# not be used elsewhere. It is provided on the sendmail distribution +# as a sample only. +# +# This file is for a home machine that wants to masquerade as an +# on-campus machine. Additionally, all addresses without a hostname +# will be forwarded to that machine. +# + +VERSIONID(`@(#)chez.cs.mc 8.5 (Berkeley) 8/6/95') +OSTYPE(bsd4.4)dnl +DOMAIN(CS.Berkeley.EDU)dnl +define(`LOCAL_RELAY', vangogh.CS.Berkeley.EDU)dnl +MASQUERADE_AS(vangogh.CS.Berkeley.EDU)dnl +FEATURE(use_cw_file)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/clientproto.mc b/usr.sbin/sendmail/cf/cf/clientproto.mc new file mode 100644 index 000000000000..a59ac037e192 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/clientproto.mc @@ -0,0 +1,54 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This the prototype for a "null client" -- that is, a client that +# does nothing except forward all mail to a mail hub. IT IS NOT +# USABLE AS IS!!! +# +# To use this, you MUST use the nullclient feature with the name of +# the mail hub as its argument. You MUST also define an `OSTYPE' to +# define the location of the queue directories and the like. +# In addition, you MAY select the nocanonify feature. This causes +# addresses to be sent unqualified via the SMTP connection; normally +# they are qualifed with the masquerade name, which defaults to the +# name of the hub machine. +# Other than these, it should never contain any other lines. +# + +VERSIONID(`@(#)clientproto.mc 8.6 (Berkeley) 8/16/95') + +OSTYPE(unknown) +FEATURE(nullclient, mailhost.$m) diff --git a/usr.sbin/sendmail/cf/cf/cs-hpux10.mc b/usr.sbin/sendmail/cf/cf/cs-hpux10.mc new file mode 100644 index 000000000000..1d39ccfa413a --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cs-hpux10.mc @@ -0,0 +1,51 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for HP-UX 9.x. +# It applies only the the Computer Science Division at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. To create your own configuration +# file, create an appropriate domain file in ../domain, change the +# `DOMAIN' macro below to reference that file, and copy the result +# to a name of your own choosing. +# + +VERSIONID(`@(#)cs-hpux10.mc 8.3 (Berkeley) 8/6/95') +OSTYPE(hpux10)dnl +DOMAIN(CS.Berkeley.EDU)dnl +define(`MAIL_HUB', mailspool.CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/cs-hpux9.mc b/usr.sbin/sendmail/cf/cf/cs-hpux9.mc new file mode 100644 index 000000000000..a27febeaedac --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cs-hpux9.mc @@ -0,0 +1,51 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for HP-UX 9.x. +# It applies only the the Computer Science Division at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. To create your own configuration +# file, create an appropriate domain file in ../domain, change the +# `DOMAIN' macro below to reference that file, and copy the result +# to a name of your own choosing. +# + +VERSIONID(`@(#)cs-hpux9.mc 8.4 (Berkeley) 8/6/95') +OSTYPE(hpux9)dnl +DOMAIN(CS.Berkeley.EDU)dnl +define(`MAIL_HUB', mailspool.CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/cs-osf1.mc b/usr.sbin/sendmail/cf/cf/cs-osf1.mc new file mode 100644 index 000000000000..b5beca80c0f2 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cs-osf1.mc @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for OSF/1. +# It applies only the the Computer Science Division at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. To create your own configuration +# file, create an appropriate domain file in ../domain, change the +# `DOMAIN' macro below to reference that file, and copy the result +# to a name of your own choosing. +# + +VERSIONID(`@(#)cs-osf1.mc 8.3 (Berkeley) 8/6/95') +OSTYPE(osf1)dnl +DOMAIN(CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/cs-solaris2.mc b/usr.sbin/sendmail/cf/cf/cs-solaris2.mc new file mode 100644 index 000000000000..aad526b6a51c --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cs-solaris2.mc @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for Solaris 2.x. +# It applies only the the Computer Science Division at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. To create your own configuration +# file, create an appropriate domain file in ../domain, change the +# `DOMAIN' macro below to reference that file, and copy the result +# to a name of your own choosing. +# + +VERSIONID(`@(#)cs-solaris2.mc 8.2 (Berkeley) 8/6/95') +OSTYPE(solaris2)dnl +DOMAIN(CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/cs-sunos4.1.mc b/usr.sbin/sendmail/cf/cf/cs-sunos4.1.mc new file mode 100644 index 000000000000..024fc375d743 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cs-sunos4.1.mc @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for SunOS 4.1.x. +# It applies only the the Computer Science Division at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. To create your own configuration +# file, create an appropriate domain file in ../domain, change the +# `DOMAIN' macro below to reference that file, and copy the result +# to a name of your own choosing. +# + +VERSIONID(`@(#)cs-sunos4.1.mc 8.3 (Berkeley) 8/6/95') +OSTYPE(sunos4.1)dnl +DOMAIN(CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/cs-ultrix4.mc b/usr.sbin/sendmail/cf/cf/cs-ultrix4.mc new file mode 100644 index 000000000000..1f90d00e0151 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cs-ultrix4.mc @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for Ultrix 4.x. +# It applies only the the Computer Science Division at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. To create your own configuration +# file, create an appropriate domain file in ../domain, change the +# `DOMAIN' macro below to reference that file, and copy the result +# to a name of your own choosing. +# + +VERSIONID(`@(#)cs-ultrix4.mc 8.3 (Berkeley) 8/6/95') +OSTYPE(ultrix4)dnl +DOMAIN(CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/cyrusproto.mc b/usr.sbin/sendmail/cf/cf/cyrusproto.mc new file mode 100644 index 000000000000..125b931704c0 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cyrusproto.mc @@ -0,0 +1,40 @@ +divert(-1) +# +# (C) Copyright 1995 by Carnegie Mellon University +# +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose and without fee is hereby granted, +# provided that the above copyright notice appear in all copies and that +# both that copyright notice and this permission notice appear in +# supporting documentation, and that the name of CMU not be +# used in advertising or publicity pertaining to distribution of the +# software without specific, written prior permission. +# +# CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +# CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. +# +# Contributed to Berkeley by John Gardiner Myers <jgm+@CMU.EDU>. +# +# This sample mc file is for a site that uses the Cyrus IMAP server +# exclusively for local mail. +# + +VERSIONID(`@(#)cyrusproto.mc 8.2 (Carnegie Mellon) @(#)cyrusproto.mc 8.2') +define(`confBIND_OPTS',`-DNSRCH -DEFNAMES') +FEATURE(nouucp) +FEATURE(nocanonify) +FEATURE(always_add_domain) +MAILER(smtp) +MAILER(cyrus) + +define(`confLOCAL_MAILER',`cyrus') + +LOCAL_RULE_0 +Rbb + $+ < @ $=w . > $#cyrusbb $: $1 diff --git a/usr.sbin/sendmail/cf/cf/generic-bsd4.4.mc b/usr.sbin/sendmail/cf/cf/generic-bsd4.4.mc new file mode 100644 index 000000000000..482f671d0a5f --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/generic-bsd4.4.mc @@ -0,0 +1,48 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a generic configuration file for 4.4 BSD-based systems, +# including 4.4-Lite, BSDi, NetBSD, and FreeBSD. +# It has support for local and SMTP mail only. If you want to +# customize it, copy it to a name appropriate for your environment +# and do the modifications there. +# + +VERSIONID(`@(#)generic-bsd4.4.mc 8.1 (Berkeley) 9/12/95') +OSTYPE(bsd4.4)dnl +DOMAIN(generic)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/generic-hpux10.mc b/usr.sbin/sendmail/cf/cf/generic-hpux10.mc new file mode 100644 index 000000000000..9c59c64bed69 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/generic-hpux10.mc @@ -0,0 +1,47 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a generic configuration file for HP-UX 9.x. +# It has support for local and SMTP mail only. If you want to +# customize it, copy it to a name appropriate for your environment +# and do the modifications there. +# + +VERSIONID(`@(#)generic-hpux10.mc 8.2 (Berkeley) 8/6/95') +OSTYPE(hpux10)dnl +DOMAIN(generic)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/generic-hpux9.mc b/usr.sbin/sendmail/cf/cf/generic-hpux9.mc new file mode 100644 index 000000000000..d56e05ec9ec6 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/generic-hpux9.mc @@ -0,0 +1,47 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a generic configuration file for HP-UX 9.x. +# It has support for local and SMTP mail only. If you want to +# customize it, copy it to a name appropriate for your environment +# and do the modifications there. +# + +VERSIONID(`@(#)generic-hpux9.mc 8.2 (Berkeley) 8/6/95') +OSTYPE(hpux9)dnl +DOMAIN(generic)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/generic-osf1.mc b/usr.sbin/sendmail/cf/cf/generic-osf1.mc new file mode 100644 index 000000000000..3134f6138f5e --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/generic-osf1.mc @@ -0,0 +1,47 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a generic configuration file for OSF/1. +# It has support for local and SMTP mail only. If you want to +# customize it, copy it to a name appropriate for your environment +# and do the modifications there. +# + +VERSIONID(`@(#)generic-osf1.mc 8.2 (Berkeley) 8/6/95') +OSTYPE(osf1)dnl +DOMAIN(generic)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/generic-solaris2.mc b/usr.sbin/sendmail/cf/cf/generic-solaris2.mc new file mode 100644 index 000000000000..7e6b84ec9046 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/generic-solaris2.mc @@ -0,0 +1,47 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a generic configuration file for SunOS 5.x (a.k.a. Solaris 2.x) +# It has support for local and SMTP mail only. If you want to +# customize it, copy it to a name appropriate for your environment +# and do the modifications there. +# + +VERSIONID(`@(#)generic-solaris2.mc 8.2 (Berkeley) 8/6/95') +OSTYPE(solaris2)dnl +DOMAIN(generic)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/generic-sunos4.1.mc b/usr.sbin/sendmail/cf/cf/generic-sunos4.1.mc new file mode 100644 index 000000000000..1e3b3c83bfb2 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/generic-sunos4.1.mc @@ -0,0 +1,47 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a generic configuration file for SunOS 4.1.x. +# It has support for local and SMTP mail only. If you want to +# customize it, copy it to a name appropriate for your environment +# and do the modifications there. +# + +VERSIONID(`@(#)generic-sunos4.1.mc 8.2 (Berkeley) 8/6/95') +OSTYPE(sunos4.1)dnl +DOMAIN(generic)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/generic-ultrix4.mc b/usr.sbin/sendmail/cf/cf/generic-ultrix4.mc new file mode 100644 index 000000000000..a12b3d107ffe --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/generic-ultrix4.mc @@ -0,0 +1,47 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a generic configuration file for Ultrix 4.x. +# It has support for local and SMTP mail only. If you want to +# customize it, copy it to a name appropriate for your environment +# and do the modifications there. +# + +VERSIONID(`@(#)generic-ultrix4.mc 8.2 (Berkeley) 8/6/95') +OSTYPE(ultrix4)dnl +DOMAIN(generic)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/huginn.cs.mc b/usr.sbin/sendmail/cf/cf/huginn.cs.mc new file mode 100644 index 000000000000..4914f32e3137 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/huginn.cs.mc @@ -0,0 +1,63 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for a specific +# machine in the Computer Science Division at Berkeley, and should +# not be used elsewhere. It is provided on the sendmail distribution +# as a sample only. +# +# This file is for the backup CS Division mail server. +# + +VERSIONID(`@(#)huginn.cs.mc 8.6 (Berkeley) 8/25/95') +OSTYPE(hpux9)dnl +DOMAIN(CS.Berkeley.EDU)dnl +MASQUERADE_AS(CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl + +LOCAL_CONFIG +DDBerkeley.EDU + +# hosts for which we accept and forward mail (must be in .Berkeley.EDU) +CF CS +FF/etc/sendmail.cw + +LOCAL_RULE_0 +R< @ $=F . $D . > : $* $@ $>7 $2 @here:... -> ... +R$* $=O $* < @ $=F . $D . > $@ $>7 $1 $2 $3 ...@here -> ... + +R$* < @ $=F . $D . > $#local $: $1 use UDB diff --git a/usr.sbin/sendmail/cf/cf/mail.cs.mc b/usr.sbin/sendmail/cf/cf/mail.cs.mc new file mode 100644 index 000000000000..50daad7e68c0 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/mail.cs.mc @@ -0,0 +1,64 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for a specific +# machine in the Computer Science Division at Berkeley, and should +# not be used elsewhere. It is provided on the sendmail distribution +# as a sample only. +# +# This file is for the primary CS Division mail server. +# + +VERSIONID(`@(#)mail.cs.mc 8.9 (Berkeley) 8/25/95') +OSTYPE(ultrix4)dnl +DOMAIN(Berkeley.EDU)dnl +MASQUERADE_AS(CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl +define(`confUSERDB_SPEC', ``/usr/local/lib/users.cs.db,/usr/local/lib/users.eecs.db'')dnl + +LOCAL_CONFIG +DDBerkeley.EDU + +# hosts for which we accept and forward mail (must be in .Berkeley.EDU) +CF CS +FF/etc/sendmail.cw + +LOCAL_RULE_0 +R< @ $=F . $D . > : $* $@ $>7 $2 @here:... -> ... +R$* $=O $* < @ $=F . $D . > $@ $>7 $1 $2 $3 ...@here -> ... + +R$* < @ $=F . $D . > $#local $: $1 use UDB diff --git a/usr.sbin/sendmail/cf/cf/mail.eecs.mc b/usr.sbin/sendmail/cf/cf/mail.eecs.mc new file mode 100644 index 000000000000..f6d2bdcde106 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/mail.eecs.mc @@ -0,0 +1,64 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for a specific +# machine in Electrical Engineering and Computer Sciences at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. +# +# This file is for the primary EECS mail server. +# + +VERSIONID(`@(#)mail.eecs.mc 8.9 (Berkeley) 8/25/95') +OSTYPE(ultrix4)dnl +DOMAIN(EECS.Berkeley.EDU)dnl +MASQUERADE_AS(EECS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl +define(`confUSERDB_SPEC', `/usr/local/lib/users.eecs.db,/usr/local/lib/users.cs.db,/usr/local/lib/users.coe.db')dnl + +LOCAL_CONFIG +DDBerkeley.EDU + +# hosts for which we accept and forward mail (must be in .Berkeley.EDU) +CF EECS +FF/etc/sendmail.cw + +LOCAL_RULE_0 +R< @ $=F . $D . > : $* $@ $>7 $2 @here:... -> ... +R$* $=O $* < @ $=F . $D . > $@ $>7 $1 $2 $3 ...@here -> ... + +R$* < @ $=F . $D . > $#local $: $1 use UDB diff --git a/usr.sbin/sendmail/cf/cf/mailspool.cs.mc b/usr.sbin/sendmail/cf/cf/mailspool.cs.mc new file mode 100644 index 000000000000..0493b2dffcf0 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/mailspool.cs.mc @@ -0,0 +1,57 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for a specific +# machine in the Computer Science Division at Berkeley, and should +# not be used elsewhere. It is provided on the sendmail distribution +# as a sample only. +# +# This file is for our mail spool machine. For a while we were using +# "root.machinename" instead of "root+machinename", so this is included +# for back compatibility. +# + +VERSIONID(`@(#)mailspool.cs.mc 8.3 (Berkeley) 8/6/95') +OSTYPE(sunos4.1)dnl +DOMAIN(CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl + +LOCAL_CONFIG +CDroot sys-custodian + +LOCAL_RULE_3 +R$=D . $+ $1 + $2 diff --git a/usr.sbin/sendmail/cf/cf/python.cs.mc b/usr.sbin/sendmail/cf/cf/python.cs.mc new file mode 100644 index 000000000000..3dff97d15300 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/python.cs.mc @@ -0,0 +1,62 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for a specific +# machine in the Computer Science Division at Berkeley, and should +# not be used elsewhere. It is provided on the sendmail distribution +# as a sample only. +# +# This file is for a home machine that wants to masquerade as an +# on-campus machine. Additionally, all addresses without a hostname +# will be forwarded to that machine. +# + +VERSIONID(`@(#)python.cs.mc 8.3 (Berkeley) 8/6/95') +OSTYPE(bsd4.4)dnl +DOMAIN(CS.Berkeley.EDU)dnl +define(`LOCAL_RELAY', vangogh.CS.Berkeley.EDU)dnl +MASQUERADE_AS(vangogh.CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl + +# accept mail sent to the domain head +DDBostic.COM + +LOCAL_RULE_0 +# accept mail sent to the domain head +R< @ $D . > : $* $@ $>7 $1 @here:... -> ... +R$* $=O $* < @ $D . > $@ $>7 $1 $2 $3 ...@here -> ... +R$* < @ $D . > $#local $: $1 user@here -> user diff --git a/usr.sbin/sendmail/cf/cf/s2k-osf1.mc b/usr.sbin/sendmail/cf/cf/s2k-osf1.mc new file mode 100644 index 000000000000..db324ae51561 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/s2k-osf1.mc @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for OSF/1. +# It applies only the the Sequoia 2000 Project at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. To create your own configuration +# file, create an appropriate domain file in ../domain, change the +# `DOMAIN' macro below to reference that file, and copy the result +# to a name of your own choosing. +# + +VERSIONID(`@(#)s2k-osf1.mc 8.3 (Berkeley) 8/6/95') +OSTYPE(osf1)dnl +DOMAIN(S2K.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/s2k-ultrix4.mc b/usr.sbin/sendmail/cf/cf/s2k-ultrix4.mc new file mode 100644 index 000000000000..1404b86393b9 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/s2k-ultrix4.mc @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for Ultrix 4.x. +# It applies only the the Sequoia 2000 Project at Berkeley, +# and should not be used elsewhere. It is provided on the sendmail +# distribution as a sample only. To create your own configuration +# file, create an appropriate domain file in ../domain, change the +# `DOMAIN' macro below to reference that file, and copy the result +# to a name of your own choosing. +# + +VERSIONID(`@(#)s2k-ultrix4.mc 8.3 (Berkeley) 8/6/95') +OSTYPE(ultrix4)dnl +DOMAIN(S2K.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/tcpproto.mc b/usr.sbin/sendmail/cf/cf/tcpproto.mc new file mode 100644 index 000000000000..7f43558ca97d --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/tcpproto.mc @@ -0,0 +1,53 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is the prototype file for a configuration that supports nothing +# but basic SMTP connections via TCP. +# +# You MUST change the `OSTYPE' macro to specify the operating system +# on which this will run; this will set the location of various +# support files for your operating system environment. You MAY +# create a domain file in ../domain and reference it by adding a +# `DOMAIN' macro after the `OSTYPE' macro. I recommend that you +# first copy this to another file name so that new sendmail releases +# will not trash your changes. +# + +VERSIONID(`@(#)tcpproto.mc 8.4 (Berkeley) 8/6/95') +OSTYPE(unknown) +FEATURE(nouucp) +MAILER(local) +MAILER(smtp) diff --git a/usr.sbin/sendmail/cf/cf/ucbarpa.mc b/usr.sbin/sendmail/cf/cf/ucbarpa.mc new file mode 100644 index 000000000000..39d73908cad6 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/ucbarpa.mc @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This machine has been decommissioned at Berkeley, and hence should +# not be considered to be tested. This file is provided as an example +# only, of how you might set up a joint SMTP/UUCP configuration. At +# this point I recommend using `FEATURE(mailertable)' instead of +# `SITECONFIG'. See also ucbvax.mc. +# + +VERSIONID(`@(#)ucbarpa.mc 8.3 (Berkeley) 8/6/95') +DOMAIN(CS.Berkeley.EDU)dnl +OSTYPE(bsd4.4)dnl +MAILER(local)dnl +MAILER(smtp)dnl +MAILER(uucp)dnl +SITECONFIG(uucp.ucbarpa, ucbarpa, U) diff --git a/usr.sbin/sendmail/cf/cf/ucbvax.mc b/usr.sbin/sendmail/cf/cf/ucbvax.mc new file mode 100644 index 000000000000..cc8cd2ce66de --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/ucbvax.mc @@ -0,0 +1,111 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This machine has been decommissioned at Berkeley, and hence should +# not be considered to be tested. This file is provided as an example +# only, of how you might set up a fairly complex configuration. +# Ucbvax was our main relay (both SMTP and UUCP) for many years. +# At this point I recommend using `FEATURE(mailertable)' instead of +# `SITECONFIG' for routing of UUCP within your domain. +# + +VERSIONID(`@(#)ucbvax.mc 8.5 (Berkeley) 8/25/95') +OSTYPE(bsd4.3) +DOMAIN(CS.Berkeley.EDU) +MASQUERADE_AS(CS.Berkeley.EDU) +MAILER(local) +MAILER(smtp) +MAILER(uucp) +undefine(`UUCP_RELAY')dnl + +LOCAL_CONFIG +DDBerkeley.EDU + +# names for which we act as a local forwarding agent +CF CS +FF/etc/sendmail.cw + +# local UUCP connections, and our local uucp name +SITECONFIG(uucp.ucbvax, ucbvax, U) + +# remote UUCP connections, and the machine they are on +SITECONFIG(uucp.ucbarpa, ucbarpa.Berkeley.EDU, W) + +SITECONFIG(uucp.cogsci, cogsci.Berkeley.EDU, X) + +LOCAL_RULE_3 +# map old UUCP names into Internet names +UUCPSMTP(bellcore, bellcore.com) +UUCPSMTP(decvax, decvax.dec.com) +UUCPSMTP(decwrl, decwrl.dec.com) +UUCPSMTP(hplabs, hplabs.hp.com) +UUCPSMTP(lbl-csam, lbl-csam.arpa) +UUCPSMTP(pur-ee, ecn.purdue.edu) +UUCPSMTP(purdue, purdue.edu) +UUCPSMTP(research, research.att.com) +UUCPSMTP(sdcarl, sdcarl.ucsd.edu) +UUCPSMTP(sdcsvax, sdcsvax.ucsd.edu) +UUCPSMTP(ssyx, ssyx.ucsc.edu) +UUCPSMTP(sun, sun.com) +UUCPSMTP(ucdavis, ucdavis.ucdavis.edu) +UUCPSMTP(ucivax, ics.uci.edu) +UUCPSMTP(ucla-cs, cs.ucla.edu) +UUCPSMTP(ucla-se, seas.ucla.edu) +UUCPSMTP(ucsbcsl, ucsbcsl.ucsb.edu) +UUCPSMTP(ucscc, c.ucsc.edu) +UUCPSMTP(ucsd, ucsd.edu) +UUCPSMTP(ucsfcgl, cgl.ucsf.edu) +UUCPSMTP(unmvax, unmvax.cs.unm.edu) +UUCPSMTP(uwvax, spool.cs.wisc.edu) + +LOCAL_RULE_0 + +# make sure we handle the local domain as absolute +R$* < @ $* $D > $* $: $1 < @ $2 $D . > $3 + +# handle names we forward for as though they were local, so we will use UDB +R< @ $=F . $D . > : $* $@ $>7 $2 @here:... -> ... +R< @ $D . > : $* $@ $>7 $1 @here:... -> ... +R$* $=O $* < @ $=F . $D . > $@ $>7 $1 $2 $3 ...@here -> ... +R$* $=O $* < @ $D . > $@ $>7 $1 $2 $3 ...@here -> ... + +R$* < @ $=F . $D . > $#local $: $1 use UDB + +# handle local UUCP connections in the Berkeley.EDU domain +R$+<@cnmat.$D . > $#uucp$@cnmat$:$1 +R$+<@cnmat.CS.$D . > $#uucp$@cnmat$:$1 +R$+<@craig.$D . > $#uucp$@craig$:$1 +R$+<@craig.CS.$D . > $#uucp$@craig$:$1 diff --git a/usr.sbin/sendmail/cf/cf/uucpproto.mc b/usr.sbin/sendmail/cf/cf/uucpproto.mc new file mode 100644 index 000000000000..49c4a0de6562 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/uucpproto.mc @@ -0,0 +1,53 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is the prototype for a configuration that only supports UUCP +# and does not have DNS support at all. +# +# You MUST change the `OSTYPE' macro to specify the operating system +# on which this will run; this will set the location of various +# support files for your operating system environment. You MAY +# create a domain file in ../domain and reference it by adding a +# `DOMAIN' macro after the `OSTYPE' macro. I recommend that you +# first copy this to another file name so that new sendmail releases +# will not trash your changes. +# + +VERSIONID(`@(#)uucpproto.mc 8.5 (Berkeley) 8/6/95') +OSTYPE(unknown) +FEATURE(nodns)dnl +MAILER(local)dnl +MAILER(uucp)dnl diff --git a/usr.sbin/sendmail/cf/cf/vangogh.cs.mc b/usr.sbin/sendmail/cf/cf/vangogh.cs.mc new file mode 100644 index 000000000000..2be3179ea9bf --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/vangogh.cs.mc @@ -0,0 +1,53 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This is a Berkeley-specific configuration file for a specific +# machine in the Computer Science Division at Berkeley, and should +# not be used elsewhere. It is provided on the sendmail distribution +# as a sample only. +# +# This file is for the BSD development machine; it has some parameters +# set up (to stress sendmail) and accepts mail for some other machines. +# + +VERSIONID(`@(#)vangogh.cs.mc 8.4 (Berkeley) 8/6/95') +DOMAIN(CS.Berkeley.EDU)dnl +OSTYPE(bsd4.4)dnl +MAILER(local)dnl +MAILER(smtp)dnl +define(`MCI_CACHE_SIZE', 5) +Cw okeeffe.CS.Berkeley.EDU +Cw python.CS.Berkeley.EDU diff --git a/usr.sbin/sendmail/cf/domain/Berkeley.EDU.m4 b/usr.sbin/sendmail/cf/domain/Berkeley.EDU.m4 new file mode 100644 index 000000000000..2bad42bc3063 --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/Berkeley.EDU.m4 @@ -0,0 +1,45 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +divert(0) +VERSIONID(`@(#)Berkeley.EDU.m4 8.9 (Berkeley) 10/5/95') +DOMAIN(berkeley-only)dnl +define(`BITNET_RELAY', `bitnet-relay.Berkeley.EDU')dnl +define(`UUCP_RELAY', `uucp-relay.Berkeley.EDU')dnl +define(`confFORWARD_PATH', `$z/.forward.$w:$z/.forward')dnl +define(`confCW_FILE', `-o /etc/sendmail.cw')dnl +define(`confDONT_INIT_GROUPS', True)dnl +FEATURE(redirect)dnl +FEATURE(use_cw_file)dnl +FEATURE(stickyhost)dnl diff --git a/usr.sbin/sendmail/cf/domain/CS.Berkeley.EDU.m4 b/usr.sbin/sendmail/cf/domain/CS.Berkeley.EDU.m4 new file mode 100644 index 000000000000..97ccfb208992 --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/CS.Berkeley.EDU.m4 @@ -0,0 +1,40 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +divert(0) +VERSIONID(`@(#)CS.Berkeley.EDU.m4 8.2 (Berkeley) 4/21/95') +DOMAIN(Berkeley.EDU)dnl +HACK(cssubdomain)dnl +define(`confUSERDB_SPEC', + `/usr/sww/share/lib/users.cs.db,/usr/sww/share/lib/users.eecs.db')dnl diff --git a/usr.sbin/sendmail/cf/domain/EECS.Berkeley.EDU.m4 b/usr.sbin/sendmail/cf/domain/EECS.Berkeley.EDU.m4 new file mode 100644 index 000000000000..a41fc7ed823a --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/EECS.Berkeley.EDU.m4 @@ -0,0 +1,38 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +divert(0) +VERSIONID(`@(#)EECS.Berkeley.EDU.m4 8.2 (Berkeley) 4/21/95') +DOMAIN(Berkeley.EDU)dnl +MASQUERADE_AS(EECS.Berkeley.EDU)dnl diff --git a/usr.sbin/sendmail/cf/domain/S2K.Berkeley.EDU.m4 b/usr.sbin/sendmail/cf/domain/S2K.Berkeley.EDU.m4 new file mode 100644 index 000000000000..4aed130b7ba2 --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/S2K.Berkeley.EDU.m4 @@ -0,0 +1,38 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +divert(0) +VERSIONID(`@(#)S2K.Berkeley.EDU.m4 8.2 (Berkeley) 4/21/95') +DOMAIN(CS.Berkeley.EDU)dnl +MASQUERADE_AS(postgres.Berkeley.EDU)dnl diff --git a/usr.sbin/sendmail/cf/domain/berkeley-only.m4 b/usr.sbin/sendmail/cf/domain/berkeley-only.m4 new file mode 100644 index 000000000000..ef710714ea9e --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/berkeley-only.m4 @@ -0,0 +1,40 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +divert(0) +VERSIONID(`@(#)unspecified-domain.m4 8.2 (Berkeley) 4/21/95') +errprint(`*** ERROR: You are trying to use the Berkeley sample configuration') +errprint(` files outside of the Computer Science Division at Berkeley.') +errprint(` The configuration (.mc) files must be customized to reference') +errprint(` domain files appropriate for your environment.') diff --git a/usr.sbin/sendmail/cf/domain/generic.m4 b/usr.sbin/sendmail/cf/domain/generic.m4 new file mode 100644 index 000000000000..6799ff895227 --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/generic.m4 @@ -0,0 +1,48 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# The following is a generic domain file. You should be able to +# use it anywhere. If you want to customize it, copy it to a file +# named with your domain and make the edits; then, copy the appropriate +# .mc files and change `DOMAIN(generic)' to reference your updated domain +# files. +# +divert(0) +VERSIONID(`@(#)generic.m4 8.2 (Berkeley) 4/21/95') +define(`confFORWARD_PATH', `$z/.forward.$w:$z/.forward')dnl +define(`confCW_FILE', `-o /etc/sendmail.cw')dnl +FEATURE(redirect)dnl +FEATURE(use_cw_file)dnl diff --git a/usr.sbin/sendmail/cf/feature/bestmx_is_local.m4 b/usr.sbin/sendmail/cf/feature/bestmx_is_local.m4 new file mode 100644 index 000000000000..23dff8c93eef --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/bestmx_is_local.m4 @@ -0,0 +1,58 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)bestmx_is_local.m4 8.2 (Berkeley) 10/29/95') +divert(-1) + +LOCAL_CONFIG +Kbestmx bestmx + +LOCAL_NET_CONFIG + +# If we are the best MX for a site, then we want to accept +# its mail as local. We assume we've already weeded out mail to +# UUCP sites which are connected to us, which should also have +# listed us as their best MX. +# +# Warning: this may generate a lot of extra DNS traffic -- a +# lower cost method is to list all the expected best MX hosts +# in $=w. This should be fine (and easier to administer) for +# low to medium traffic hosts. + +R$* < @ $* > $* $: $1 < @ $2 @@ $(bestmx $2 $) > $3 +R$* $=O $* < @ $* @@ $=w . > $* $@ $>97 $1 $2 $3 +R$* < @ $* @@ $=w . > $* $#local $: $1 +R$* < @ $* @@ $* > $* $: $1 < @ $2 > $4 diff --git a/usr.sbin/sendmail/cf/feature/local_procmail.m4 b/usr.sbin/sendmail/cf/feature/local_procmail.m4 new file mode 100644 index 000000000000..9087a690d082 --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/local_procmail.m4 @@ -0,0 +1,44 @@ +divert(-1) +# +# Copyright (c) 1994 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)local_procmail.m4 8.3 (Berkeley) 10/29/95') +divert(-1) + +define(`PROCMAIL_PATH', + ifelse(_ARG_, `', `/usr/local/bin/procmail', `_ARG_')) +define(`LOCAL_MAILER_FLAGS', `SPfhn') +define(`LOCAL_MAILER_PATH', PROCMAIL_PATH) +define(`LOCAL_MAILER_ARGS', `procmail -Y -a $h -d $u') diff --git a/usr.sbin/sendmail/cf/feature/masquerade_envelope.m4 b/usr.sbin/sendmail/cf/feature/masquerade_envelope.m4 new file mode 100644 index 000000000000..1e6010856ea6 --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/masquerade_envelope.m4 @@ -0,0 +1,40 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)masquerade_envelope.m4 8.1 (Berkeley) 7/9/95') +divert(-1) + +define(`_MASQUERADE_ENVELOPE_', 1) diff --git a/usr.sbin/sendmail/cf/feature/notsticky.m4 b/usr.sbin/sendmail/cf/feature/notsticky.m4 new file mode 100644 index 000000000000..027b8e3a51c0 --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/notsticky.m4 @@ -0,0 +1,42 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)notsticky.m4 8.3 (Berkeley) 5/29/95') +# +# This is now the default. Use ``FEATURE(stickyhost)'' if you want +# the old default behaviour. +# +divert(-1) diff --git a/usr.sbin/sendmail/cf/feature/nullclient.m4 b/usr.sbin/sendmail/cf/feature/nullclient.m4 new file mode 100644 index 000000000000..7543070f77f7 --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/nullclient.m4 @@ -0,0 +1,71 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +ifdef(`SMTP_MAILER_FLAGS',, `define(`SMTP_MAILER_FLAGS', `')') +define(_NULL_CLIENT_ONLY_, `1') +ifelse(_ARG_, `', `errprint(`Feature "nullclient" requires argument')', + `define(`MAIL_HUB', _ARG_)') +POPDIVERT + +# +# This is used only for relaying mail from a client to a hub when +# that client does absolutely nothing else -- i.e., it is a "null +# mailer". In this sense, it acts like the "R" option in Sun +# sendmail. +# + +VERSIONID(`@(#)nullclient.m4 8.6 (Berkeley) 6/29/95') + +PUSHDIVERT(6) +# hub host (to which all mail is sent) +DH`'ifdef(`MAIL_HUB', MAIL_HUB, + `errprint(`MAIL_HUB not defined for nullclient feature')') +ifdef(`MASQUERADE_NAME',, `define(`MASQUERADE_NAME', MAIL_HUB)')dnl + +# route-addr separators +C: : , +POPDIVERT +PUSHDIVERT(7) +############################################ +### Null Client Mailer specification ### +############################################ + +ifdef(`confRELAY_MAILER',, + `define(`confRELAY_MAILER', `nullclient')')dnl +ifdef(`confFROM_HEADER',, + `define(`confFROM_HEADER', <$g>)')dnl + +Mnullclient, P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS),ifdef(`SMTP_MAILER_MAX', ` M=SMTP_MAILER_MAX,') + A=IPC $h +POPDIVERT diff --git a/usr.sbin/sendmail/cf/feature/redirect.m4 b/usr.sbin/sendmail/cf/feature/redirect.m4 new file mode 100644 index 000000000000..081db113ae01 --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/redirect.m4 @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)redirect.m4 8.4 (Berkeley) 6/25/95') +divert(-1) + + +PUSHDIVERT(3) +# addresses sent to foo@host.REDIRECT will give a 551 error code +R$* < @ $+ .REDIRECT. > $: $1 < @ $2 . REDIRECT . > < ${opMode} > +R$* < @ $+ .REDIRECT. > <i> $: $1 < @ $2 . REDIRECT. > +R$* < @ $+ .REDIRECT. > < $- > $# error $@ 5.1.1 $: "551 User not local; please try " <$1@$2> +POPDIVERT + +PUSHDIVERT(6) +CPREDIRECT +POPDIVERT diff --git a/usr.sbin/sendmail/cf/feature/smrsh.m4 b/usr.sbin/sendmail/cf/feature/smrsh.m4 new file mode 100644 index 000000000000..6b4faab25261 --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/smrsh.m4 @@ -0,0 +1,42 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)smrsh.m4 8.2 (Berkeley) 11/11/95') +divert(-1) + +ifdef(`_MAILER_local_', + `errprint(`*** FEATURE(smrsh) must occur before MAILER(local)')')dnl +define(`LOCAL_SHELL_PATH', ifelse(_ARG_, `', `/usr/local/etc/smrsh', _ARG_)) diff --git a/usr.sbin/sendmail/cf/feature/stickyhost.m4 b/usr.sbin/sendmail/cf/feature/stickyhost.m4 new file mode 100644 index 000000000000..bdd9c9a729f0 --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/stickyhost.m4 @@ -0,0 +1,40 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)stickyhost.m4 8.1 (Berkeley) 11/12/94') +divert(-1) + +define(`_STICKY_LOCAL_DOMAIN_', 1) diff --git a/usr.sbin/sendmail/cf/feature/use_ct_file.m4 b/usr.sbin/sendmail/cf/feature/use_ct_file.m4 new file mode 100644 index 000000000000..c33bbfd7833e --- /dev/null +++ b/usr.sbin/sendmail/cf/feature/use_ct_file.m4 @@ -0,0 +1,46 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)use_ct_file.m4 8.1 (Berkeley) 9/17/95') +divert(-1) + +# if defined, the sendmail.cf will read the /etc/sendmail.ct file +# to find the names of trusted users. There should only be a few +# of these, and normally this is done directly in the .cf file. + +define(`_USE_CT_FILE_', `') + +divert(0) diff --git a/usr.sbin/sendmail/cf/m4/cf.m4 b/usr.sbin/sendmail/cf/m4/cf.m4 new file mode 100644 index 000000000000..4e54f4142898 --- /dev/null +++ b/usr.sbin/sendmail/cf/m4/cf.m4 @@ -0,0 +1,50 @@ +divert(-1) +# +# Copyright (c) 1983, 1995 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# This file is included so that multiple includes of cf.m4 will work +# + +# figure out where the CF files live +ifdef(`_CF_DIR_', `', + `ifelse(__file__, `__file__', + `define(`_CF_DIR_', `../')', + `define(`_CF_DIR_', + substr(__file__, 0, eval(len(__file__) - 8)))')') + +divert(0)dnl +ifdef(`OSTYPE', `dnl', +`include(_CF_DIR_`'m4/cfhead.m4)dnl +VERSIONID(`@(#)cf.m4 8.24 (Berkeley) 8/16/95')') diff --git a/usr.sbin/sendmail/cf/m4/cfhead.m4 b/usr.sbin/sendmail/cf/m4/cfhead.m4 new file mode 100644 index 000000000000..46605e7e34c0 --- /dev/null +++ b/usr.sbin/sendmail/cf/m4/cfhead.m4 @@ -0,0 +1,147 @@ +# +# Copyright (c) 1983, 1995 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +###################################################################### +###################################################################### +##### +##### SENDMAIL CONFIGURATION FILE +##### +define(`TEMPFILE', maketemp(/tmp/cfXXXXXX))dnl +syscmd(sh _CF_DIR_`'sh/makeinfo.sh _CF_DIR_ > TEMPFILE)dnl +include(TEMPFILE)dnl +syscmd(rm -f TEMPFILE)dnl +##### +###################################################################### +###################################################################### + +divert(-1) + +changecom() +undefine(`format') +undefine(`hpux') +ifdef(`pushdef', `', + `errprint(`You need a newer version of M4, at least as new as +System V or GNU') + include(NoSuchFile)') +define(`PUSHDIVERT', `pushdef(`__D__', divnum)divert($1)') +define(`POPDIVERT', `divert(__D__)popdef(`__D__')') +define(`OSTYPE', + `PUSHDIVERT(-1) + ifdef(`__OSTYPE__', `errprint(`duplicate OSTYPE'($1))') + define(`__OSTYPE__', $1) + define(`_ARG_', $2) + include(_CF_DIR_`'ostype/$1.m4)POPDIVERT`'') +define(`MAILER', +`ifdef(`_MAILER_$1_', `dnl`'', +`define(`_MAILER_$1_', `')PUSHDIVERT(7)include(_CF_DIR_`'mailer/$1.m4)POPDIVERT`'')') +define(`DOMAIN', `PUSHDIVERT(-1)define(`_ARG_', $2)include(_CF_DIR_`'domain/$1.m4)POPDIVERT`'') +define(`FEATURE', `PUSHDIVERT(-1)define(`_ARG_', $2)include(_CF_DIR_`'feature/$1.m4)POPDIVERT`'') +define(`HACK', `PUSHDIVERT(-1)define(`_ARG_', $2)include(_CF_DIR_`'hack/$1.m4)POPDIVERT`'') +define(`VERSIONID', ``##### $1 #####'') +define(`LOCAL_RULE_0', `divert(3)') +define(`LOCAL_RULE_1', +`divert(9)dnl +####################################### +### Ruleset 1 -- Sender Rewriting ### +####################################### + +S1 +') +define(`LOCAL_RULE_2', +`divert(9)dnl +########################################## +### Ruleset 2 -- Recipient Rewriting ### +########################################## + +S2 +') +define(`LOCAL_RULE_3', `divert(2)') +define(`LOCAL_CONFIG', `divert(6)') +define(`LOCAL_NET_CONFIG', `define(`_LOCAL_RULES_', 1)divert(1)') +define(`UUCPSMTP', `R DOL(*) < @ $1 .UUCP > DOL(*) DOL(1) < @ $2 > DOL(2)') +define(`CONCAT', `$1$2$3$4$5$6$7') +define(`DOL', ``$'$1') +define(`SITECONFIG', +`CONCAT(D, $3, $2) +define(`_CLASS_$3_', `')dnl +ifelse($3, U, Cw$2 $2.UUCP, `dnl') +define(`SITE', `ifelse(CONCAT($'2`, $3), SU, + CONCAT(CY, $'1`), + CONCAT(C, $3, $'1`))') +sinclude(_CF_DIR_`'siteconfig/$1.m4)') +define(`EXPOSED_USER', `PUSHDIVERT(5)CE$1 +POPDIVERT`'dnl') +define(`LOCAL_USER', `PUSHDIVERT(5)CL$1 +POPDIVERT`'dnl') +define(`MASQUERADE_AS', `define(`MASQUERADE_NAME', $1)') +define(`MASQUERADE_DOMAIN', `PUSHDIVERT(5)CM$1 +POPDIVERT`'dnl') +define(`MASQUERADE_DOMAIN_FILE', `PUSHDIVERT(5)FM$1 +POPDIVERT`'dnl') +define(`_OPTINS', `ifdef(`$1', `$2$1$3')') + +m4wrap(`include(_CF_DIR_`m4/proto.m4')') + +# set up default values for options +define(`confMAILER_NAME', ``MAILER-DAEMON'') +define(`confFROM_LINE', `From $g $d') +define(`confOPERATORS', `.:%@!^/[]+') +define(`confSMTP_LOGIN_MSG', `$j Sendmail $v/$Z; $b') +define(`confRECEIVED_HEADER', `$?sfrom $s $.$?_($?s$|from $.$_) $.by $j ($v/$Z)$?r with $r$. id $i$?u for $u$.; $b') +define(`confSEVEN_BIT_INPUT', `False') +define(`confEIGHT_BIT_HANDLING', `pass8') +define(`confALIAS_WAIT', `10') +define(`confMIN_FREE_BLOCKS', `100') +define(`confBLANK_SUB', `.') +define(`confCON_EXPENSIVE', `False') +define(`confDELIVERY_MODE', `background') +define(`confTEMP_FILE_MODE', `0600') +define(`confMCI_CACHE_SIZE', `2') +define(`confMCI_CACHE_TIMEOUT', `5m') +define(`confUSE_ERRORS_TO', `False') +define(`confLOG_LEVEL', `9') +define(`confCHECK_ALIASES', `False') +define(`confOLD_STYLE_HEADERS', `True') +define(`confPRIVACY_FLAGS', `authwarnings') +define(`confSAFE_QUEUE', `True') +define(`confTO_QUEUERETURN', `5d') +define(`confTO_QUEUEWARN', `4h') +define(`confTIME_ZONE', `USE_SYSTEM') +define(`confDEF_USER_ID', `1:1') +define(`confCW_FILE', `/etc/sendmail.cw') +define(`confMIME_FORMAT_ERRORS', `True') +define(`confFORWARD_PATH', `$z/.forward.$w:$z/.forward') + +divert(0)dnl +VERSIONID(`@(#)cfhead.m4 8.3 (Berkeley) 9/15/95') diff --git a/usr.sbin/sendmail/cf/m4/nullrelay.m4 b/usr.sbin/sendmail/cf/m4/nullrelay.m4 new file mode 100644 index 000000000000..799f3ab79198 --- /dev/null +++ b/usr.sbin/sendmail/cf/m4/nullrelay.m4 @@ -0,0 +1,129 @@ +divert(-1) +# +# Copyright (c) 1983, 1995 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +divert(0) + +VERSIONID(`@(#)nullrelay.m4 8.10 (Berkeley) 9/29/95') + +# +# This configuration applies only to relay-only hosts. They send +# all mail to a hub without consideration of the address syntax +# or semantics, except for adding the hub qualification to the +# addresses. +# +# This is based on a prototype done by Bryan Costales of ICSI. +# + +###################################################################### +###################################################################### +##### +##### REWRITING RULES +##### +###################################################################### +###################################################################### + +########################################### +### Rulset 3 -- Name Canonicalization ### +########################################### +S3 + +# handle null input +R$@ $@ <@> + +# strip group: syntax (not inside angle brackets!) and trailing semicolon +R$* $: $1 <@> mark addresses +R$* < $* > $* <@> $: $1 < $2 > $3 unmark <addr> +R$* :: $* <@> $: $1 :: $2 unmark node::addr +R:`include': $* <@> $: :`include': $1 unmark :`include':... +R$* : $* <@> $: $2 strip colon if marked +R$* <@> $: $1 unmark +R$* ; $: $1 strip trailing semi + +# null input now results from list:; syntax +R$@ $@ :; <@> + +# basic textual canonicalization -- note RFC733 heuristic here +R$*<$*>$*<$*>$* $2$3<$4>$5 strip multiple <> <> +R$*<$*<$+>$*>$* <$3>$5 2-level <> nesting +R$*<>$* $@ <@> MAIL FROM:<> case +R$*<$+>$* $2 basic RFC821/822 parsing + +ifdef(`_NO_CANONIFY_', `dnl', +`# eliminate local host if present +R@ $=w $=: $+ $@ @ $M $2 $3 @thishost ... +R@ $+ $@ @ $1 @somewhere ... + +R$+ @ $=w $@ $1 @ $M ...@thishost +R$+ @ $+ $@ $1 @ $2 ...@somewhere + +R$=w ! $+ $@ $2 @ $M thishost!... +R$+ ! $+ $@ $1 ! $2 @ $M somewhere ! ... + +R$+ % $=w $@ $1 @ $M ...%thishost +R$+ % $+ $@ $1 @ $2 ...%somewhere + +R$+ $@ $1 @ $M unadorned user') + + +###################################### +### Ruleset 0 -- Parse Address ### +###################################### + +S0 + +R$*:;<@> $#error $@ USAGE $: "list:; syntax illegal for recipient addresses" + +# pass everything else to a relay host +R$* $#_RELAY_ $@ $H $: $1 + + +################################################## +### Ruleset 4 -- Final Output Post-rewriting ### +################################################## +S4 + +R$* <@> $@ handle <> and list:; + +# strip trailing dot off before passing to nullclient relay +R$* @ $+ . $1 @ $2 + +# +###################################################################### +###################################################################### +##### +`##### MAILER DEFINITIONS' +##### +###################################################################### +###################################################################### +undivert(7)dnl diff --git a/usr.sbin/sendmail/cf/m4/proto.m4 b/usr.sbin/sendmail/cf/m4/proto.m4 new file mode 100644 index 000000000000..2397c4a7f6f1 --- /dev/null +++ b/usr.sbin/sendmail/cf/m4/proto.m4 @@ -0,0 +1,818 @@ +divert(-1) +# +# Copyright (c) 1983, 1995 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +divert(0) + +VERSIONID(`@(#)proto.m4 8.99 (Berkeley) 11/18/95') + +MAILER(local)dnl + +# level 6 config file format +V6/Berkeley +divert(-1) + +# do some sanity checking +ifdef(`__OSTYPE__',, + `errprint(`*** ERROR: No system type defined (use OSTYPE macro)')') + +# pick our default mailers +ifdef(`confSMTP_MAILER',, `define(`confSMTP_MAILER', `smtp')') +ifdef(`confLOCAL_MAILER',, `define(`confLOCAL_MAILER', `local')') +ifdef(`confRELAY_MAILER',, + `define(`confRELAY_MAILER', + `ifdef(`_MAILER_smtp_', `relay', + `ifdef(`_MAILER_uucp', `uucp-new', `unknown')')')') +ifdef(`confUUCP_MAILER',, `define(`confUUCP_MAILER', `uucp-old')') +define(`_SMTP_', `confSMTP_MAILER')dnl for readability only +define(`_LOCAL_', `confLOCAL_MAILER')dnl for readability only +define(`_RELAY_', `confRELAY_MAILER')dnl for readability only +define(`_UUCP_', `confUUCP_MAILER')dnl for readability only + +# back compatibility with old config files +ifdef(`confDEF_GROUP_ID', + `errprint(`*** confDEF_GROUP_ID is obsolete.') + errprint(` Use confDEF_USER_ID with a colon in the value instead.')') +ifdef(`confREAD_TIMEOUT', + `errprint(`*** confREAD_TIMEOUT is obsolete.') + errprint(` Use individual confTO_<timeout> parameters instead.')') +ifdef(`confMESSAGE_TIMEOUT', + `define(`_ARG_', index(confMESSAGE_TIMEOUT, /)) + ifelse(_ARG_, -1, + `define(`confTO_QUEUERETURN', confMESSAGE_TIMEOUT)', + `define(`confTO_QUEUERETURN', + substr(confMESSAGE_TIMEOUT, 0, _ARG_)) + define(`confTO_QUEUEWARN', + substr(confMESSAGE_TIMEOUT, eval(_ARG_+1)))')') +ifdef(`confMIN_FREE_BLOCKS', `ifelse(index(confMIN_FREE_BLOCKS, /), -1,, + `errprint(`*** compound confMIN_FREE_BLOCKS is obsolete.') + errprint(` Use confMAX_MESSAGE_SIZE for the second part of the value.')')') + +# clean option definitions below.... +define(`_OPTION', `ifdef(`$2', `O $1=$2', `#O $1`'ifelse($3, `',, `=$3')')')dnl + +divert(0)dnl + +################## +# local info # +################## + +Cwlocalhost +ifdef(`USE_CW_FILE', +`# file containing names of hosts for which we receive email +Fw`'confCW_FILE', + `dnl') + +# my official domain name +# ... define this only if sendmail cannot automatically determine your domain +ifdef(`confDOMAIN_NAME', `Dj`'confDOMAIN_NAME', `#Dj$w.Foo.COM') + +ifdef(`_NULL_CLIENT_ONLY_', `divert(-1)')dnl + +CP. + +ifdef(`UUCP_RELAY', +`# UUCP relay host +DY`'UUCP_RELAY +CPUUCP + +')dnl +ifdef(`BITNET_RELAY', +`# BITNET relay host +DB`'BITNET_RELAY +CPBITNET + +')dnl +ifdef(`DECNET_RELAY', +`define(`_USE_DECNET_SYNTAX_', 1)dnl +# DECnet relay host +DC`'DECNET_RELAY +CPDECNET + +')dnl +ifdef(`FAX_RELAY', +`# FAX relay host +DF`'FAX_RELAY +CPFAX + +')dnl +# "Smart" relay host (may be null) +DS`'ifdef(`SMART_HOST', SMART_HOST) + +# place to which unknown users should be forwarded +ifdef(`LUSER_RELAY', `', `#')dnl +Kuser user -m -a<> +ifdef(`LUSER_RELAY', + `DL`'LUSER_RELAY', + `#DLname_of_luser_relay') + +# operators that cannot be in local usernames (i.e., network indicators) +CO @ % ifdef(`_NO_UUCP_', `', `!') + +# a class with just dot (for identifying canonical names) +C.. + +# Mailer table (overriding domains) +ifdef(`MAILER_TABLE', + `Kmailertable MAILER_TABLE', + `#Kmailertable dbm /etc/mailertable') + +# Domain table (adding domains) +ifdef(`DOMAIN_TABLE', + `Kdomaintable DOMAIN_TABLE', + `#Kdomaintable dbm /etc/domaintable') + +# who I send unqualified names to (null means deliver locally) +DR`'ifdef(`LOCAL_RELAY', LOCAL_RELAY) + +# who gets all local email traffic ($R has precedence for unqualified names) +DH`'ifdef(`MAIL_HUB', MAIL_HUB) + +# class L: names that should be delivered locally, even if we have a relay +# class E: names that should be exposed as from this host, even if we masquerade +# class M: domains that should be converted to $M +#CL root +CE root +undivert(5)dnl + +# dequoting map +Kdequote dequote + +divert(0)dnl # end of nullclient diversion +# who I masquerade as (null for no masquerading) (see also $=M) +DM`'ifdef(`MASQUERADE_NAME', MASQUERADE_NAME) + +# my name for error messages +ifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON') + +undivert(6)dnl +include(_CF_DIR_`m4/version.m4') + +############### +# Options # +############### + +# strip message body to 7 bits on input? +_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT') + +# 8-bit data handling +_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', adaptive) + +ifdef(`_NULL_CLIENT_ONLY_', `dnl', ` +# wait for alias file rebuild (default units: minutes) +_OPTION(AliasWait, `confALIAS_WAIT', 5m) + +# location of alias file +O AliasFile=ifdef(`ALIAS_FILE', `ALIAS_FILE', /etc/aliases) +') +# minimum number of free blocks on filesystem +_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', 100) + +# maximum message size +_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', 1000000) + +# substitution for space (blank) characters +_OPTION(BlankSub, `confBLANK_SUB', _) + +# avoid connecting to "expensive" mailers on initial submission? +_OPTION(HoldExpensive, `confCON_EXPENSIVE') + +# checkpoint queue runs after every N successful deliveries +_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', 10) + +# default delivery mode +_OPTION(DeliveryMode, `confDELIVERY_MODE', background) + +# automatically rebuild the alias database? +_OPTION(AutoRebuildAliases, `confAUTO_REBUILD') + +# error message header/file +_OPTION(ErrorHeader, `confERROR_MESSAGE', /etc/sendmail.oE) + +# error mode +_OPTION(ErrorMode, `confERROR_MODE', print) + +# save Unix-style "From_" lines at top of header? +_OPTION(SaveFromLine, `confSAVE_FROM_LINES') + +# temporary file mode +_OPTION(TempFileMode, `confTEMP_FILE_MODE', 0600) + +# match recipients against GECOS field? +_OPTION(MatchGECOS, `confMATCH_GECOS') + +# maximum hop count +_OPTION(MaxHopCount, `confMAX_HOP', 17) + +# location of help file +O HelpFile=ifdef(`HELP_FILE', HELP_FILE, /usr/lib/sendmail.hf) + +# ignore dots as terminators in incoming messages? +_OPTION(IgnoreDots, `confIGNORE_DOTS') + +# name resolver options +_OPTION(ResolverOptions, `confBIND_OPTS', +AAONLY) + +# deliver MIME-encapsulated error messages? +_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS') + +# Forward file search path +_OPTION(ForwardPath, `confFORWARD_PATH', /var/forward/$u:$z/.forward.$w:$z/.forward) + +# open connection cache size +_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', 2) + +# open connection cache timeout +_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', 5m) + +# use Errors-To: header? +_OPTION(UseErrorsTo, `confUSE_ERRORS_TO') + +# log level +_OPTION(LogLevel, `confLOG_LEVEL', 10) + +# send to me too, even in an alias expansion? +_OPTION(MeToo, `confME_TOO') + +# verify RHS in newaliases? +_OPTION(CheckAliases, `confCHECK_ALIASES') + +# default messages to old style headers if no special punctuation? +_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS') + +# SMTP daemon options +_OPTION(DaemonPortOptions, `confDAEMON_OPTIONS', Port=esmtp) + +# privacy flags +_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', authwarnings) + +# who (if anyone) should get extra copies of error messages +_OPTION(PostMasterCopy, `confCOPY_ERRORS_TO', Postmaster) + +# slope of queue-only function +_OPTION(QueueFactor, `confQUEUE_FACTOR', 600000) + +# queue directory +O QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, /var/spool/mqueue) + +# timeouts (many of these) +_OPTION(Timeout.initial, `confTO_INITIAL', 5m) +_OPTION(Timeout.helo, `confTO_HELO', 5m) +_OPTION(Timeout.mail, `confTO_MAIL', 10m) +_OPTION(Timeout.rcpt, `confTO_RCPT', 1h) +_OPTION(Timeout.datainit, `confTO_DATAINIT', 5m) +_OPTION(Timeout.datablock, `confTO_DATABLOCK', 1h) +_OPTION(Timeout.datafinal, `confTO_DATAFINAL', 1h) +_OPTION(Timeout.rset, `confTO_RSET', 5m) +_OPTION(Timeout.quit, `confTO_QUIT', 2m) +_OPTION(Timeout.misc, `confTO_MISC', 2m) +_OPTION(Timeout.command, `confTO_COMMAND', 1h) +_OPTION(Timeout.ident, `confTO_IDENT', 30s) +_OPTION(Timeout.fileopen, `confTO_FILEOPEN', 60s) +_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', 5d) +_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', 5d) +_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', 2d) +_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', 7d) +_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', 4h) +_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', 4h) +_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', 1h) +_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', 12h) + +# should we not prune routes in route-addr syntax addresses? +_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES') + +# queue up everything before forking? +_OPTION(SuperSafe, `confSAFE_QUEUE') + +# status file +O StatusFile=ifdef(`STATUS_FILE', `STATUS_FILE', /etc/sendmail.st) + +# time zone handling: +# if undefined, use system default +# if defined but null, use TZ envariable passed in +# if defined and non-null, use that info +ifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=', + confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=', + `O TimeZoneSpec=confTIME_ZONE') + +# default UID (can be username or userid:groupid) +_OPTION(DefaultUser, `confDEF_USER_ID', nobody) + +# list of locations of user database file (null means no lookup) +_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', /etc/userdb) + +# fallback MX host +_OPTION(FallbackMXhost, `confFALLBACK_MX', fall.back.host.net) + +# if we are the best MX host for a site, try it directly instead of config err +_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST') + +# load average at which we just queue messages +_OPTION(QueueLA, `confQUEUE_LA', 8) + +# load average at which we refuse connections +_OPTION(RefuseLA, `confREFUSE_LA', 12) + +# work recipient factor +_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', 30000) + +# deliver each queued job in a separate process? +_OPTION(ForkEachJob, `confSEPARATE_PROC') + +# work class factor +_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', 1800) + +# work time factor +_OPTION(RetryFactor, `confWORK_TIME_FACTOR', 90000) + +# shall we sort the queue by hostname first? +_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', priority) + +# minimum time in queue before retry +_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', 30m) + +# default character set +_OPTION(DefaultCharSet, `confDEF_CHAR_SET', iso-8859-1) + +# service switch file (ignored on Solaris, Ultrix, OSF/1, others) +_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', /etc/service.switch) + +# dialup line delay on connection failure +_OPTION(DialDelay, `confDIAL_DELAY', 10s) + +# action to take if there are no recipients in the message +_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', add-to-undisclosed) + +# chrooted environment for writing to files +_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', /arch) + +# are colons OK in addresses? +_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR') + +# how many jobs can you process in the queue? +_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', 10000) + +# shall I avoid expanding CNAMEs (violates protocols)? +_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES') + +# SMTP initial login message (old $e macro) +_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG') + +# UNIX initial From header format (old $l macro) +_OPTION(UnixFromLine, `confFROM_LINE') + +# delimiter (operator) characters (old $o macro) +_OPTION(OperatorChars, `confOPERATORS') + +# shall I avoid calling initgroups(3) because of high NIS costs? +_OPTION(DontInitGroups, `confDONT_INIT_GROUPS') + +########################### +# Message precedences # +########################### + +Pfirst-class=0 +Pspecial-delivery=100 +Plist=-30 +Pbulk=-60 +Pjunk=-100 + +##################### +# Trusted users # +##################### + +# this is equivalent to setting class "t" +ifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `/etc/sendmail.ct') +Troot +Tdaemon +Tuucp +ifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl') + +######################### +# Format of headers # +######################### + +ifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl +H?P?Return-Path: $g +HReceived: confRECEIVED_HEADER +H?D?Resent-Date: $a +H?D?Date: $a +H?F?Resent-From: confFROM_HEADER +H?F?From: confFROM_HEADER +H?x?Full-Name: $x +HSubject: +# HPosted-Date: $a +# H?l?Received-Date: $b +H?M?Resent-Message-Id: <$t.$i@$j> +H?M?Message-Id: <$t.$i@$j> +ifdef(`_NULL_CLIENT_ONLY_', + `include(_CF_DIR_`'m4/nullrelay.m4)m4exit', + `dnl') +# +###################################################################### +###################################################################### +##### +##### REWRITING RULES +##### +###################################################################### +###################################################################### + +undivert(9)dnl + +########################################### +### Rulset 3 -- Name Canonicalization ### +########################################### +S3 + +# handle null input (translate to <@> special case) +R$@ $@ <@> + +# strip group: syntax (not inside angle brackets!) and trailing semicolon +R$* $: $1 <@> mark addresses +R$* < $* > $* <@> $: $1 < $2 > $3 unmark <addr> +R$* :: $* <@> $: $1 :: $2 unmark node::addr +R:`include': $* <@> $: :`include': $1 unmark :`include':... +R$* : $* <@> $: $2 strip colon if marked +R$* <@> $: $1 unmark +R$* ; $: $1 strip trailing semi + +# null input now results from list:; syntax +R$@ $@ :; <@> + +# strip angle brackets -- note RFC733 heuristic to get innermost item +R$* $: < $1 > housekeeping <> +R$+ < $* > < $2 > strip excess on left +R< $* > $+ < $1 > strip excess on right +R<> $@ < @ > MAIL FROM:<> case +R< $+ > $: $1 remove housekeeping <> + +# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later +R@ $+ , $+ @ $1 : $2 change all "," to ":" + +# localize and dispose of route-based addresses +R@ $+ : $+ $@ $>96 < @$1 > : $2 handle <route-addr> + +# find focus for list syntax +R $+ : $* ; @ $+ $@ $>96 $1 : $2 ; < @ $3 > list syntax +R $+ : $* ; $@ $1 : $2; list syntax + +# find focus for @ syntax addresses +R$+ @ $+ $: $1 < @ $2 > focus on domain +R$+ < $+ @ $+ > $1 $2 < @ $3 > move gaze right +R$+ < @ $+ > $@ $>96 $1 < @ $2 > already canonical + +# do some sanity checking +R$* < @ $* : $* > $* $1 < @ $2 $3 > $4 nix colons in addrs + +ifdef(`_NO_UUCP_', `dnl', +`# convert old-style addresses to a domain-based address +R$- ! $+ $@ $>96 $2 < @ $1 .UUCP > resolve uucp names +R$+ . $- ! $+ $@ $>96 $3 < @ $1 . $2 > domain uucps +R$+ ! $+ $@ $>96 $2 < @ $1 .UUCP > uucp subdomains +') +ifdef(`_USE_DECNET_SYNTAX_', +`# convert node::user addresses into a domain-based address +R$- :: $+ $@ $>96 $2 < @ $1 .DECNET > resolve DECnet names +R$- . $- :: $+ $@ $>96 $3 < @ $1.$2 .DECNET > numeric DECnet addr +', + `dnl') +# if we have % signs, take the rightmost one +R$* % $* $1 @ $2 First make them all @s. +R$* @ $* @ $* $1 % $2 @ $3 Undo all but the last. +R$* @ $* $@ $>96 $1 < @ $2 > Insert < > and finish + +# else we must be a local name +R$* $@ $>96 $1 + + +################################################ +### Ruleset 96 -- bottom half of ruleset 3 ### +################################################ + +S96 + +# handle special cases for local names +R$* < @ localhost > $* $: $1 < @ $j . > $2 no domain at all +R$* < @ localhost . $m > $* $: $1 < @ $j . > $2 local domain +ifdef(`_NO_UUCP_', `dnl', +`R$* < @ localhost . UUCP > $* $: $1 < @ $j . > $2 .UUCP domain') +R$* < @ [ $+ ] > $* $: $1 < @@ [ $2 ] > $3 mark [a.b.c.d] +R$* < @@ $=w > $* $: $1 < @ $j . > $3 self-literal +R$* < @@ $+ > $* $@ $1 < @ $2 > $3 canon IP addr + +# look up domains in the domain table +ifdef(`DOMAIN_TABLE', `', `#')dnl +R$* < @ $+ > $* $: $1 < @ $(domaintable $2 $) > $3 + +undivert(2)dnl + +ifdef(`_NO_UUCP_', `dnl', +`ifdef(`UUCP_RELAY', +`# pass UUCP addresses straight through +R$* < @ $+ . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', +`# if really UUCP, handle it immediately +ifdef(`_CLASS_U_', +`R$* < @ $=U . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl') +ifdef(`_CLASS_V_', +`R$* < @ $=V . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl') +ifdef(`_CLASS_W_', +`R$* < @ $=W . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl') +ifdef(`_CLASS_X_', +`R$* < @ $=X . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl') +ifdef(`_CLASS_Y_', +`R$* < @ $=Y . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl') + +# try UUCP traffic as a local address +R$* < @ $+ . UUCP > $* $: $1 < @ $[ $2 $] . UUCP . > $3 +R$* < @ $+ . . UUCP . > $* $@ $1 < @ $2 . > $3') +') +ifdef(`_NO_CANONIFY_', `dnl', +`# pass to name server to make hostname canonical +R$* < @ $* $~P > $* $: $1 < @ $[ $2 $3 $] > $4') + +# local host aliases and pseudo-domains are always canonical +R$* < @ $=w > $* $: $1 < @ $2 . > $3 +R$* < @ $* $=P > $* $: $1 < @ $2 $3 . > $4 +R$* < @ $* . . > $* $1 < @ $2 . > $3 + +# if this is the local hostname, make sure we treat is as canonical +R$* < @ $j > $* $: $1 < @ $j . > $2 + + +################################################## +### Ruleset 4 -- Final Output Post-rewriting ### +################################################## +S4 + +R$* <@> $@ handle <> and list:; + +# strip trailing dot off possibly canonical name +R$* < @ $+ . > $* $1 < @ $2 > $3 + +# eliminate internal code -- should never get this far! +R$* < @ *LOCAL* > $* $1 < @ $j > $2 + +# externalize local domain info +R$* < $+ > $* $1 $2 $3 defocus +R@ $+ : @ $+ : $+ @ $1 , @ $2 : $3 <route-addr> canonical +R@ $* $@ @ $1 ... and exit + +ifdef(`_NO_UUCP_', `dnl', +`# UUCP must always be presented in old form +R$+ @ $- . UUCP $2!$1 u@h.UUCP => h!u') + +ifdef(`_USE_DECNET_SYNTAX_', +`# put DECnet back in :: form +R$+ @ $+ . DECNET $2 :: $1 u@h.DECNET => h::u', + `dnl') +# delete duplicate local names +R$+ % $=w @ $=w $1 @ $j u%host@host => u@host + + + +############################################################## +### Ruleset 97 -- recanonicalize and call ruleset zero ### +### (used for recursive calls) ### +############################################################## + +S`'97 +R$* $: $>3 $1 +R$* $@ $>0 $1 + + +###################################### +### Ruleset 0 -- Parse Address ### +###################################### + +S0 + +R<@> $#_LOCAL_ $: <@> special case error msgs +R$* : $* ; <@> $#error $@ 5.1.3 $: "list:; syntax illegal for recipient addresses" +R<@ $+> $#error $@ 5.1.1 $: "user address required" +R$* <$* : $* > $* $#error $@ 5.1.1 $: "colon illegal in host name part" +R$* < @ . > $* $#error $@ 5.1.2 $: "invalid host name" + +ifdef(`_MAILER_smtp_', +`# handle numeric address spec +R$* < @ [ $+ ] > $* $: $>98 $1 < @ [ $2 ] > $3 numeric internet spec +R$* < @ [ $+ ] > $* $#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3 still numeric: send', + `dnl') + +# now delete the local info -- note $=O to find characters that cause forwarding +R$* < @ > $* $@ $>97 $1 user@ => user +R< @ $=w . > : $* $@ $>97 $2 @here:... -> ... +R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here +R$* $=O $* < @ $=w . > $@ $>97 $1 $2 $3 ...@here -> ... + +# handle local hacks +R$* $: $>98 $1 + +# short circuit local delivery so forwarded email works +ifdef(`_MAILER_usenet_', +`R$+ . USENET < @ $=w . > $#usenet $: $1 handle usenet specially', + `dnl') +ifdef(`_STICKY_LOCAL_DOMAIN_', +`R$+ < @ $=w . > $: < $H > $1 < @ $2 . > first try hub +R< $+ > $+ < $+ > $>95 < $1 > $2 < $3 > yep .... +R< > $+ + $* < $+ > $#_LOCAL_ $: $1 + $2 plussed name? +R< > $+ < $+ > $#_LOCAL_ $: @ $1 nope, local address', +`R$=L < @ $=w . > $#_LOCAL_ $: @ $1 special local names +R$+ < @ $=w . > $#_LOCAL_ $: $1 regular local name') + +define(`X', ifdef(`MAILER_TABLE', `', `#'))dnl +# not local -- try mailer table lookup +X`'R$* <@ $+ > $* $: < $2 > $1 < @ $2 > $3 extract host name +X`'R< $+ . > $* $: < $1 > $2 strip trailing dot +X`'R< $+ > $* $: < $(mailertable $1 $) > $2 lookup +X`'R< error : $- $+ > $* $#error $@ $1 $: $2 check -- error? +X`'R< $- : $+ > $* $# $1 $@ $2 $: $3 check -- resolved? +X`'R< $+ > $* $: $>90 <$1> $2 try domain +undefine(`X')dnl +undivert(4)dnl + +ifdef(`_NO_UUCP_', `dnl', +`# resolve remotely connected UUCP links (if any) +ifdef(`_CLASS_V_', +`R$* < @ $=V . UUCP . > $* $: $>95 < $V > $1 <@$2.UUCP.> $3', + `dnl') +ifdef(`_CLASS_W_', +`R$* < @ $=W . UUCP . > $* $: $>95 < $W > $1 <@$2.UUCP.> $3', + `dnl') +ifdef(`_CLASS_X_', +`R$* < @ $=X . UUCP . > $* $: $>95 < $X > $1 <@$2.UUCP.> $3', + `dnl')') + +# resolve fake top level domains by forwarding to other hosts +ifdef(`BITNET_RELAY', +`R$*<@$+.BITNET.>$* $: $>95 < $B > $1 <@$2.BITNET.> $3 user@host.BITNET', + `dnl') +ifdef(`DECNET_RELAY', +`R$*<@$+.DECNET.>$* $: $>95 < $C > $1 <@$2.DECNET.> $3 user@host.DECNET', + `dnl') +ifdef(`_MAILER_pop_', +`R$+ < @ POP. > $#pop $: $1 user@POP', + `dnl') +ifdef(`_MAILER_fax_', +`R$+ < @ $+ .FAX. > $#fax $@ $2 $: $1 user@host.FAX', +`ifdef(`FAX_RELAY', +`R$*<@$+.FAX.>$* $: $>95 < $F > $1 <@$2.FAX.> $3 user@host.FAX', + `dnl')') + +ifdef(`UUCP_RELAY', +`# forward non-local UUCP traffic to our UUCP relay +R$*<@$*.UUCP.>$* $: $>95 < $Y > $1 <@$2.UUCP.> $3 uucp mail', +`ifdef(`_MAILER_uucp_', +`# forward other UUCP traffic straight to UUCP +R$* < @ $+ .UUCP. > $* $#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3 user@host.UUCP', + `dnl')') +ifdef(`_MAILER_usenet_', ` +# addresses sent to net.group.USENET will get forwarded to a newsgroup +R$+ . USENET $#usenet $: $1', + `dnl') + +ifdef(`_LOCAL_RULES_', +`# figure out what should stay in our local mail system +undivert(1)', `dnl') + +# pass names that still have a host to a smarthost (if defined) +R$* < @ $* > $* $: $>95 < $S > $1 < @ $2 > $3 glue on smarthost name + +# deal with other remote names +ifdef(`_MAILER_smtp_', +`R$* < @$* > $* $#_SMTP_ $@ $2 $: $1 < @ $2 > $3 user@host.domain', +`R$* < @$* > $* $#error $@ 5.1.2 $: Unrecognized host name $2') + +# if this is quoted, strip the quotes and try again +R$+ $: $(dequote $1 $) strip quotes +R$+ $=O $+ $@ $>97 $1 $2 $3 try again + +# handle locally delivered names +R$=L $#_LOCAL_ $: @ $1 special local names +R$+ $#_LOCAL_ $: $1 regular local names + +########################################################################### +### Ruleset 5 -- special rewriting after aliases have been expanded ### +########################################################################### + +S5 + +# deal with plussed users so aliases work nicely +R$+ + * $#_LOCAL_ $@ $&h $: $1 +R$+ + $* $#_LOCAL_ $@ $2 $: $1 + * + +# prepend an empty "forward host" on the front +R$+ $: <> $1 + +define(`X', ifdef(`LUSER_RELAY', `', `#'))dnl +# send unrecognized local users to a relay host +X`'R< > $+ + $* $: < $L . > $( user $1 $) + $2 +X`'R< > $+ $: < $L . > $( user $1 $) look up user +X`'R< $* > $+ <> $* $: < > $2 $3 found; strip $L +X`'R< $* . > $+ $: < $1 > $2 strip extra dot +undefine(`X')dnl + +# handle plussed local names +R< > $+ + $* $#_LOCAL_ $@ $2 $: $1 + +# see if we have a relay or a hub +R< > $+ $: < $H > $1 try hub +R< > $+ $: < $R > $1 try relay +R< > $+ $@ $1 nope, give up +R< $- : $+ > $+ $: $>95 < $1 : $2 > $3 < @ $2 > +R< $+ > $+ $@ $>95 < $1 > $2 < @ $1 > + +################################################################### +### Ruleset 90 -- try domain part of mailertable entry ### +################################################################### + +define(`X', ifdef(`MAILER_TABLE', `', `#'))dnl +X`'S90 +X`'R$* <$- . $+ > $* $: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4 +X`'R$* <$- : $+ > $* $# $2 $@ $3 $: $4 check -- resolved? +X`'R$* < . $+ > $* $@ $>90 $1 . <$2> $3 no -- strip & try again +X`'R$* < $* > $* $: < $(mailertable . $@ $1$2 $) > $3 try "." +X`'R<$- : $+ > $* $# $1 $@ $2 $: $3 "." found? +X`'R< $* > $* $@ $2 no mailertable match +undefine(`X')dnl + +################################################################### +### Ruleset 95 -- canonify mailer:host syntax to triple ### +################################################################### + +S95 +R< > $* $@ $1 strip off null relay +R< $- : $+ > $* $# $1 $@ $2 $: $3 try qualified mailer +R< $=w > $* $@ $2 delete local host +R< $+ > $* $#_RELAY_ $@ $1 $: $2 use unqualified mailer + +################################################################### +### Ruleset 93 -- convert header names to masqueraded form ### +################################################################### + +S93 +R$=E < @ *LOCAL* > $@ $1 < @ $j . > leave exposed +R$=E < @ $=M . > $@ $1 < @ $2 . > +ifdef(`_LIMITED_MASQUERADE_', `#')dnl +R$=E < @ $=w . > $@ $1 < @ $2 . > +R$* < @ $=M . > $* $: $1 < @ $2 . @ $M > $3 convert masqueraded doms +ifdef(`_LIMITED_MASQUERADE_', `#')dnl +R$* < @ $=w . > $* $: $1 < @ $2 . @ $M > $3 +R$* < @ *LOCAL* > $* $: $1 < @ $j . @ $M > $2 +R$* < @ $+ @ > $* $@ $1 < @ $2 > $3 $M is null +R$* < @ $+ @ $+ > $* $@ $1 < @ $3 . > $4 $M is not null + +################################################################### +### Ruleset 94 -- convert envelope names to masqueraded form ### +################################################################### + +S94 +ifdef(`_MASQUERADE_ENVELOPE_', `', `#')dnl +R$+ $@ $>93 $1 +ifdef(`_MASQUERADE_ENVELOPE_', `#', `')dnl +R$* < @ *LOCAL* > $* $: $1 < @ $j . > $2 + +################################################################### +### Ruleset 98 -- local part of ruleset zero (can be null) ### +################################################################### + +S98 +undivert(3)dnl +# +###################################################################### +###################################################################### +##### +`##### MAILER DEFINITIONS' +##### +###################################################################### +###################################################################### +undivert(7)dnl diff --git a/usr.sbin/sendmail/cf/m4/version.m4 b/usr.sbin/sendmail/cf/m4/version.m4 new file mode 100644 index 000000000000..d057c1a56899 --- /dev/null +++ b/usr.sbin/sendmail/cf/m4/version.m4 @@ -0,0 +1,39 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +VERSIONID(`@(#)version.m4 8.7.2.2 (Berkeley) 11/20/95') +# +divert(0) +# Configuration version number +DZ8.7.2`'ifdef(`confCF_VERSION', `/confCF_VERSION') diff --git a/usr.sbin/sendmail/cf/mailer/cyrus.m4 b/usr.sbin/sendmail/cf/mailer/cyrus.m4 new file mode 100644 index 000000000000..f5311371b536 --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/cyrus.m4 @@ -0,0 +1,44 @@ +PUSHDIVERT(-1) +# +# (C) Copyright 1995 by Carnegie Mellon University +# +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose and without fee is hereby granted, +# provided that the above copyright notice appear in all copies and that +# both that copyright notice and this permission notice appear in +# supporting documentation, and that the name of CMU not be +# used in advertising or publicity pertaining to distribution of the +# software without specific, written prior permission. +# +# CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +# CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. +# +# Contributed to Berkeley by John Gardiner Myers <jgm+@CMU.EDU>. +# + +ifdef(`CYRUS_MAILER_FLAGS',, `define(`CYRUS_MAILER_FLAGS', `A5@')') +ifdef(`CYRUS_MAILER_PATH',, `define(`CYRUS_MAILER_PATH', /usr/cyrus/bin/deliver)') +ifdef(`CYRUS_MAILER_ARGS',, `define(`CYRUS_MAILER_ARGS', `deliver -e -m $h -- $u')') +ifdef(`CYRUS_BB_MAILER_FLAGS',, `define(`CYRUS_BB_MAILER_FLAGS', `')') +ifdef(`CYRUS_BB_MAILER_ARGS',, `define(`CYRUS_BB_MAILER_ARGS', `deliver -e -m $u')') + +POPDIVERT + +################################################## +### Cyrus Mailer specification ### +################################################## + +VERSIONID(`@(#)cyrus.m4 8.2 (Carnegie Mellon) 9/12/95') + +Mcyrus, P=CYRUS_MAILER_PATH, F=CONCAT(`lsDFMnP', CYRUS_MAILER_FLAGS), S=10, R=20/40, T=X-Unix, + ifdef(`CYRUS_MAILER_MAX', `M=CYRUS_MAILER_MAX, ')A=CYRUS_MAILER_ARGS + +Mcyrusbb, P=CYRUS_MAILER_PATH, F=CONCAT(`lsDFMnP', CYRUS_MAILER_FLAGS), S=10, R=20/40, T=X-Unix, + ifdef(`CYRUS_MAILER_MAX', `M=CYRUS_MAILER_MAX, ')A=CYRUS_BB_MAILER_ARGS diff --git a/usr.sbin/sendmail/cf/mailer/fax.m4 b/usr.sbin/sendmail/cf/mailer/fax.m4 new file mode 100644 index 000000000000..777fe01cf36a --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/fax.m4 @@ -0,0 +1,53 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# This assumes you already have Sam Leffler's FAX software. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +ifdef(`FAX_MAILER_PATH',, + `define(`FAX_MAILER_PATH', /usr/local/lib/fax/mailfax)') +ifdef(`FAX_MAILER_MAX',, + `define(`FAX_MAILER_MAX', 100000)') +POPDIVERT +#################################### +### FAX Mailer specification ### +#################################### + +VERSIONID(`@(#)fax.m4 8.4 (Berkeley) 10/10/95') + +Mfax, P=FAX_MAILER_PATH, F=DFMhu, S=14, R=24, M=FAX_MAILER_MAX, T=X-Phone/X-FAX/X-Unix, + A=mailfax $u $h $f + +LOCAL_CONFIG +CPFAX diff --git a/usr.sbin/sendmail/cf/mailer/local.m4 b/usr.sbin/sendmail/cf/mailer/local.m4 new file mode 100644 index 000000000000..124cbba75282 --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/local.m4 @@ -0,0 +1,94 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `rmn')') +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /bin/mail)') +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail -d $u')') +ifdef(`LOCAL_SHELL_FLAGS',, `define(`LOCAL_SHELL_FLAGS', `eu')') +ifdef(`LOCAL_SHELL_PATH',, `define(`LOCAL_SHELL_PATH', /bin/sh)') +ifdef(`LOCAL_SHELL_ARGS',, `define(`LOCAL_SHELL_ARGS', `sh -c $u')') +ifdef(`LOCAL_SHELL_DIR',, `define(`LOCAL_SHELL_DIR', `$z:/')') +POPDIVERT + +################################################## +### Local and Program Mailer specification ### +################################################## + +VERSIONID(`@(#)local.m4 8.21 (Berkeley) 11/6/95') + +Mlocal, P=LOCAL_MAILER_PATH, F=CONCAT(`lsDFMAw5:/|@', LOCAL_MAILER_FLAGS), S=10/30, R=20/40, + _OPTINS(`LOCAL_MAILER_MAX', `M=', `, ')_OPTINS(`LOCAL_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/X-Unix, + A=LOCAL_MAILER_ARGS +Mprog, P=LOCAL_SHELL_PATH, F=CONCAT(`lsDFMo', LOCAL_SHELL_FLAGS), S=10/30, R=20/40, D=LOCAL_SHELL_DIR, + _OPTINS(`LOCAL_MAILER_MAX', `M=', `, ')T=X-Unix, + A=LOCAL_SHELL_ARGS + +# +# Envelope sender rewriting +# +S10 +R<@> $n errors to mailer-daemon +R$+ $: $>50 $1 add local domain if needed +R$* $: $>94 $1 do masquerading + +# +# Envelope recipient rewriting +# +S20 +R$+ < @ $* > $: $1 strip host part + +# +# Header sender rewriting +# +S30 +R<@> $n errors to mailer-daemon +R$+ $: $>50 $1 add local domain if needed +R$* $: $>93 $1 do masquerading + +# +# Header recipient rewriting +# +S40 +R$+ $: $>50 $1 add local domain if needed +ifdef(`_ALL_MASQUERADE_', `', `#')dnl +R$* $: $>93 $1 do all-masquerading + +# +# Common code to add local domain name (only if always-add-domain) +# +S50 +ifdef(`_ALWAYS_ADD_DOMAIN_', `', `#')dnl +R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified +ifdef(`_ALWAYS_ADD_DOMAIN_', `', `#')dnl +R$+ $@ $1 < @ *LOCAL* > add local qualification diff --git a/usr.sbin/sendmail/cf/mailer/mail11.m4 b/usr.sbin/sendmail/cf/mailer/mail11.m4 new file mode 100644 index 000000000000..21e05dd19fd8 --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/mail11.m4 @@ -0,0 +1,50 @@ +PUSHDIVERT(-1) +# +# Not exciting enough to bother with copyrights and most of the +# rulesets are based from those provided by DEC. +# Barb Dijker, Labyrinth Computer Services, barb@labyrinth.com +# +# This mailer is only useful if you have DECNET and the +# mail11 program - gatekeeper.dec.com:/pub/DEC/gwtools. +# +# For local delivery of DECNET style addresses to the local +# DECNET node, you will need feature(use_cw_file) and put +# your DECNET nodename in in the cw file. +# +ifdef(`MAIL11_MAILER_PATH',, `define(`MAIL11_MAILER_PATH', /usr/etc/mail11)') +ifdef(`MAIL11_MAILER_FLAGS',, `define(`MAIL11_MAILER_FLAGS', nsFx)') +ifdef(`MAIL11_MAILER_ARGS',, `define(`MAIL11_MAILER_ARGS', mail11 $g $x $h $u)') +define(`_USE_DECNET_SYNTAX_') + +POPDIVERT + +PUSHDIVERT(3) +# DECNET delivery +R$* < @ $=w .DECNET. > $#local $: $1 local DECnet +R$+ < @ $+ .DECNET. > $#mail11 $@ $2 $: $1 DECnet user +POPDIVERT + +PUSHDIVERT(6) +CPDECNET +POPDIVERT + +########################################### +### UTK-MAIL11 Mailer specification ### +########################################### + +VERSIONID(`@(#)mail11.m4 8.1 (Berkeley) 5/23/95') + +Mmail11, P=MAIL11_MAILER_PATH, F=MAIL11_MAILER_FLAGS, S=15, R=25, + A=MAIL11_MAILER_ARGS + +S15 +R$+ $: $>25 $1 preprocess +R$w :: $+ $@ $w :: $1 ready to go + +S25 +R$+ < @ $- .UUCP > $: $2 ! $1 back to old style +R$+ < @ $- .DECNET > $: $2 :: $1 convert to DECnet style +R$+ < @ $- .LOCAL > $: $2 :: $1 convert to DECnet style +R$+ < @ $=w. > $: $2 :: $1 convert to DECnet style +R$=w :: $+ $2 strip local names +R$+ :: $+ $@ $1 :: $2 already qualified diff --git a/usr.sbin/sendmail/cf/mailer/phquery.m4 b/usr.sbin/sendmail/cf/mailer/phquery.m4 new file mode 100644 index 000000000000..ee359e09e532 --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/phquery.m4 @@ -0,0 +1,51 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# Contributed by Kimmo Suominen <kim@tac.nyc.ny.us>. +# + +ifdef(`PH_MAILER_PATH',, `define(`PH_MAILER_PATH', /usr/local/etc/phquery)') +ifdef(`PH_MAILER_FLAGS',, `define(`PH_MAILER_FLAGS', `ehmu')') +ifdef(`PH_MAILER_ARGS',, `define(`PH_MAILER_ARGS', `phquery -- $u')') + +POPDIVERT + +#################################### +### PH Mailer specification ### +#################################### + +VERSIONID(`@(#)phquery.m4 8.1 (Berkeley) 8/1/95') + +Mph, P=PH_MAILER_PATH, F=CONCAT(`nrDFM', PH_MAILER_FLAGS), S=10, R=20/40, + A=PH_MAILER_ARGS diff --git a/usr.sbin/sendmail/cf/mailer/pop.m4 b/usr.sbin/sendmail/cf/mailer/pop.m4 new file mode 100644 index 000000000000..210a3c83a6fc --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/pop.m4 @@ -0,0 +1,53 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +ifdef(`POP_MAILER_PATH',, `define(`POP_MAILER_PATH', /usr/lib/mh/spop)') +ifdef(`POP_MAILER_FLAGS',, `define(`POP_MAILER_FLAGS', `Penu')') +ifdef(`POP_MAILER_ARGS',, `define(`POP_MAILER_ARGS', `pop $u')') + +POPDIVERT + +#################################### +### POP Mailer specification ### +#################################### + +VERSIONID(`@(#)pop.m4 8.5 (Berkeley) 4/23/95') + +Mpop, P=POP_MAILER_PATH, F=CONCAT(`lsDFM', POP_MAILER_FLAGS), S=10, R=20/40, T=DNS/RFC822/X-Unix, + A=POP_MAILER_ARGS + +LOCAL_CONFIG +# POP mailer is a pseudo-domain +CPPOP diff --git a/usr.sbin/sendmail/cf/mailer/procmail.m4 b/usr.sbin/sendmail/cf/mailer/procmail.m4 new file mode 100644 index 000000000000..d1293b9ceff6 --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/procmail.m4 @@ -0,0 +1,52 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +ifdef(`PROCMAIL_PATH',, + `define(`PROCMAIL_PATH', /usr/local/bin/procmail)') +ifdef(`PROCMAIL_MAILER_FLAGS',, + `define(`PROCMAIL_MAILER_FLAGS', `Shu')') +ifdef(`PROCMAIL_MAILER_ARGS',, + `define(`PROCMAIL_MAILER_ARGS', `procmail -m $h $f $u')') + +POPDIVERT + +######################*****############## +### PROCMAIL Mailer specification ### +##################*****################## + +VERSIONID(`@(#)procmail.m4 8.4 (Berkeley) 4/23/95') + +Mprocmail, P=PROCMAIL_PATH, F=CONCAT(`DFMm', PROCMAIL_MAILER_FLAGS), S=11/31, R=21/31, T=DNS/RFC822/X-Unix, + ifdef(`PROCMAIL_MAILER_MAX', `M=PROCMAIL_MAILER_MAX, ')A=PROCMAIL_MAILER_ARGS diff --git a/usr.sbin/sendmail/cf/mailer/smtp.m4 b/usr.sbin/sendmail/cf/mailer/smtp.m4 new file mode 100644 index 000000000000..6b59574e61e4 --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/smtp.m4 @@ -0,0 +1,135 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +ifdef(`SMTP_MAILER_FLAGS',, `define(`SMTP_MAILER_FLAGS', `')') +ifdef(`SMTP_MAILER_ARGS',, `define(`SMTP_MAILER_ARGS', `IPC $h')') +ifdef(`ESMTP_MAILER_ARGS',, `define(`ESMTP_MAILER_ARGS', `IPC $h')') +ifdef(`SMTP8_MAILER_ARGS',, `define(`SMTP8_MAILER_ARGS', `IPC $h')') +ifdef(`RELAY_MAILER_ARGS',, `define(`RELAY_MAILER_ARGS', `IPC $h')') +ifdef(`_MAILER_uucp_', + `errprint(`*** MAILER(smtp) must appear before MAILER(uucp)')')dnl +POPDIVERT +##################################### +### SMTP Mailer specification ### +##################################### + +VERSIONID(`@(#)smtp.m4 8.32 (Berkeley) 11/20/95') + +Msmtp, P=[IPC], F=CONCAT(mDFMuX, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `21/31', `21'), E=\r\n, L=990, + _OPTINS(`SMTP_MAILER_MAX', `M=', `, ')_OPTINS(`SMTP_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP, + A=SMTP_MAILER_ARGS +Mesmtp, P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `21/31', `21'), E=\r\n, L=990, + _OPTINS(`SMTP_MAILER_MAX', `M=', `, ')_OPTINS(`SMTP_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP, + A=ESMTP_MAILER_ARGS +Msmtp8, P=[IPC], F=CONCAT(mDFMuX8, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `21/31', `21'), E=\r\n, L=990, + _OPTINS(`SMTP_MAILER_MAX', `M=', `, ')_OPTINS(`SMTP_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP, + A=SMTP8_MAILER_ARGS +Mrelay, P=[IPC], F=CONCAT(mDFMuXa8, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `61/71', `61'), E=\r\n, L=2040, + _OPTINS(`RELAY_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP, + A=RELAY_MAILER_ARGS + +# +# envelope sender rewriting +# +S11 +R$+ $: $>51 $1 sender/recipient common +R$* :; <@> $@ list:; special case +R$* $: $>61 $1 qualify unqual'ed names +R$+ $: $>94 $1 do masquerading + + +# +# envelope recipient rewriting -- +# also header recipient if not masquerading recipients +# +S21 +R$+ $: $>51 $1 sender/recipient common +R$+ $: $>61 $1 qualify unqual'ed names + + +# +# header sender and masquerading header recipient rewriting +# +S31 +R$+ $: $>51 $1 sender/recipient common +R:; <@> $@ list:; special case + +# do special header rewriting +R$* <@> $* $@ $1 <@> $2 pass null host through +R< @ $* > $* $@ < @ $1 > $2 pass route-addr through +R$* $: $>61 $1 qualify unqual'ed names +R$+ $: $>93 $1 do masquerading + + +# +# convert pseudo-domain addresses to real domain addresses +# +S51 + +# pass <route-addr>s through +R< @ $+ > $* $@ < @ $1 > $2 resolve <route-addr> + +# output fake domains as user%fake@relay +ifdef(`BITNET_RELAY', +`R$+ <@ $+ .BITNET. > $: $1 % $2 .BITNET < @ $B > user@host.BITNET +R$+.BITNET <@ $+:$+ > $: $1 .BITNET < @ $3 > strip mailer: part', + `dnl') +ifdef(`_NO_UUCP_', `dnl', ` +# do UUCP heuristics; note that these are shared with UUCP mailers +R$+ < @ $+ .UUCP. > $: < $2 ! > $1 convert to UUCP form +R$+ < @ $* > $* $@ $1 < @ $2 > $3 not UUCP form + +# leave these in .UUCP form to avoid further tampering +R< $&h ! > $- ! $+ $@ $2 < @ $1 .UUCP. > +R< $&h ! > $-.$+ ! $+ $@ $3 < @ $1.$2 > +R< $&h ! > $+ $@ $1 < @ $&h .UUCP. > +R< $+ ! > $+ $: $1 ! $2 < @ *LOCAL* >') + + +# +# common sender and masquerading recipient rewriting +# +S61 + +R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified +R$+ $@ $1 < @ *LOCAL* > add local qualification + + +# +# relay mailer header masquerading recipient rewriting +# +S71 + +R$+ $: $>61 $1 +R$+ $: $>93 $1 diff --git a/usr.sbin/sendmail/cf/mailer/usenet.m4 b/usr.sbin/sendmail/cf/mailer/usenet.m4 new file mode 100644 index 000000000000..2abf3b072dba --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/usenet.m4 @@ -0,0 +1,48 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +ifdef(`USENET_MAILER_PATH',, `define(`USENET_MAILER_PATH', /usr/lib/news/inews)') +ifdef(`USENET_MAILER_FLAGS',, `define(`USENET_MAILER_FLAGS', `rlsDFMmn')') +ifdef(`USENET_MAILER_ARGS',, `define(`USENET_MAILER_ARGS', `inews -m -h -n')') +POPDIVERT +#################################### +### USENET Mailer specification ### +#################################### + +VERSIONID(`@(#)usenet.m4 8.5 (Berkeley) 4/26/95') + +Musenet, P=USENET_MAILER_PATH, F=USENET_MAILER_FLAGS, S=10, R=20, + _OPTINS(`USENET_MAILER_MAX', `M=', `, ')T=X-Usenet/X-Usenet/X-Unix, + A=USENET_MAILER_ARGS $u diff --git a/usr.sbin/sendmail/cf/mailer/uucp.m4 b/usr.sbin/sendmail/cf/mailer/uucp.m4 new file mode 100644 index 000000000000..0b6594971d03 --- /dev/null +++ b/usr.sbin/sendmail/cf/mailer/uucp.m4 @@ -0,0 +1,174 @@ +PUSHDIVERT(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)') +ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -a$g -gC $h!rmail ($u)')') +ifdef(`UUCP_MAILER_FLAGS',, `define(`UUCP_MAILER_FLAGS', `')') +ifdef(`UUCP_MAILER_MAX',, + `define(`UUCP_MAILER_MAX', + `ifdef(`UUCP_MAX_SIZE', `UUCP_MAX_SIZE', 100000)')') +POPDIVERT +##################################### +### UUCP Mailer specification ### +##################################### + +VERSIONID(`@(#)uucp.m4 8.24 (Berkeley) 9/5/95') + +# +# There are innumerable variations on the UUCP mailer. It really +# is rather absurd. +# + +# old UUCP mailer (two names) +Muucp, P=UUCP_MAILER_PATH, F=CONCAT(DFMhuUd, UUCP_MAILER_FLAGS), S=12, R=22/42, M=UUCP_MAILER_MAX, + _OPTINS(`UUCP_MAILER_CHARSET', `C=', `, ')T=X-UUCP/X-UUCP/X-Unix, + A=UUCP_MAILER_ARGS +Muucp-old, P=UUCP_MAILER_PATH, F=CONCAT(DFMhuUd, UUCP_MAILER_FLAGS), S=12, R=22/42, M=UUCP_MAILER_MAX, + _OPTINS(`UUCP_MAILER_CHARSET', `C=', `, ')T=X-UUCP/X-UUCP/X-Unix, + A=UUCP_MAILER_ARGS + +# smart UUCP mailer (handles multiple addresses) (two names) +Msuucp, P=UUCP_MAILER_PATH, F=CONCAT(mDFMhuUd, UUCP_MAILER_FLAGS), S=12, R=22/42, M=UUCP_MAILER_MAX, + _OPTINS(`UUCP_MAILER_CHARSET', `C=', `, ')T=X-UUCP/X-UUCP/X-Unix, + A=UUCP_MAILER_ARGS +Muucp-new, P=UUCP_MAILER_PATH, F=CONCAT(mDFMhuUd, UUCP_MAILER_FLAGS), S=12, R=22/42, M=UUCP_MAILER_MAX, + _OPTINS(`UUCP_MAILER_CHARSET', `C=', `, ')T=X-UUCP/X-UUCP/X-Unix, + A=UUCP_MAILER_ARGS + +ifdef(`_MAILER_smtp_', +`# domain-ized UUCP mailer +Muucp-dom, P=UUCP_MAILER_PATH, F=CONCAT(mDFMhud, UUCP_MAILER_FLAGS), S=52/31, R=ifdef(`_ALL_MASQUERADE_', `21/31', `21'), M=UUCP_MAILER_MAX, + _OPTINS(`UUCP_MAILER_CHARSET', `C=', `, ')T=X-UUCP/X-UUCP/X-Unix, + A=UUCP_MAILER_ARGS + +# domain-ized UUCP mailer with UUCP-style sender envelope +Muucp-uudom, P=UUCP_MAILER_PATH, F=CONCAT(mDFMhud, UUCP_MAILER_FLAGS), S=72/31, R=ifdef(`_ALL_MASQUERADE_', `21/31', `21'), M=UUCP_MAILER_MAX, + _OPTINS(`UUCP_MAILER_CHARSET', `C=', `, ')T=X-UUCP/X-UUCP/X-Unix, + A=UUCP_MAILER_ARGS') + + +# +# envelope and header sender rewriting +# +S12 + +# handle error address as a special case +R<@> $n errors to mailer-daemon + +# list:; syntax should disappear +R:; <@> $@ + +R$* < @ $* . > $* $1 < @ $2 > $3 strip trailing dots +R$* < @ $=w > $1 strip local name +R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format +R<@ $+ > : $+ $1 ! $2 convert to UUCP format +R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format +R$* < @ $+ > $2 ! $1 convert to UUCP format +R$&h ! $+ ! $+ $@ $1 ! $2 $h!...!user => ...!user +R$&h ! $+ $@ $&h ! $1 $h!user => $h!user +R$+ $: $U ! $1 prepend our name +R! $+ $: $k ! $1 in case $U undefined + +# +# envelope recipient rewriting +# +S22 + +# list:; should disappear +R:; <@> $@ + +R$* < @ $* . > $* $1 < @ $2 > $3 strip trailing dots +R$* < @ $j > $1 strip local name +R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format +R<@ $+ > : $+ $1 ! $2 convert to UUCP format +R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format +R$* < @ $+ > $2 ! $1 convert to UUCP format + +# +# header recipient rewriting +# +S42 + +# list:; syntax should disappear +R:; <@> $@ + +R$* < @ $* . > $* $1 < @ $2 > $3 strip trailing dots +R$* < @ $j > $1 strip local name +R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format +R<@ $+ > : $+ $1 ! $2 convert to UUCP format +R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format +R$* < @ $+ > $2 ! $1 convert to UUCP format +R$&h ! $+ ! $+ $@ $1 ! $2 $h!...!user => ...!user +R$&h ! $+ $@ $&h ! $1 $h!user => $h!user +R$+ $: $U ! $1 prepend our name +R! $+ $: $k ! $1 in case $U undefined + + +ifdef(`_MAILER_smtp_', +`# +# envelope sender rewriting for uucp-dom mailer +# +S52 + +# handle error address as a special case +R<@> $n errors to mailer-daemon + +# pass everything to standard SMTP mailer rewriting +R$* $@ $>11 $1 + +# +# envelope sender rewriting for uucp-uudom mailer +# +S72 + +# handle error address as a special case +R<@> $n errors to mailer-daemon + +# do standard SMTP mailer rewriting +R$* $: $>11 $1 + +R$* < @ $* . > $* $1 < @ $2 > $3 strip trailing dots +R<@ $- . UUCP > : $+ $@ $1 ! $2 convert to UUCP format +R<@ $+ > : $+ $@ $1 ! $2 convert to UUCP format +R$* < @ $- . UUCP > $@ $2 ! $1 convert to UUCP format +R$* < @ $+ > $@ $2 ! $1 convert to UUCP format') + + +PUSHDIVERT(4) +# resolve locally connected UUCP links +R$* < @ $=Z . UUCP. > $* $#uucp-uudom $@ $2 $: $1 < @ $2 .UUCP. > $3 +R$* < @ $=Y . UUCP. > $* $#uucp-new $@ $2 $: $1 < @ $2 .UUCP. > $3 +R$* < @ $=U . UUCP. > $* $#uucp-old $@ $2 $: $1 < @ $2 .UUCP. > $3 +POPDIVERT diff --git a/usr.sbin/sendmail/cf/ostype/aix3.m4 b/usr.sbin/sendmail/cf/ostype/aix3.m4 new file mode 100644 index 000000000000..19763422fe3c --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/aix3.m4 @@ -0,0 +1,41 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)aix3.m4 8.5 (Berkeley) 11/13/95') +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /bin/bellmail)')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', mail $u)')dnl +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `mn')')dnl +define(`confTIME_ZONE', `USE_TZ')dnl diff --git a/usr.sbin/sendmail/cf/ostype/amdahl-uts.m4 b/usr.sbin/sendmail/cf/ostype/amdahl-uts.m4 new file mode 100644 index 000000000000..34b352104145 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/amdahl-uts.m4 @@ -0,0 +1,44 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)amdahl-uts.m4 8.2 (Berkeley) 11/13/95') +divert(-1) + +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /etc/mail/aliases)') +ifdef(`HELP_FILE',, `define(`HELP_FILE', /etc/mail/sendmail.hf)') +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /usr/lib/sendmail.st)') +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `fSn')') +define(`confCW_FILE', /etc/mail/sendmail.cw) diff --git a/usr.sbin/sendmail/cf/ostype/aux.m4 b/usr.sbin/sendmail/cf/ostype/aux.m4 new file mode 100644 index 000000000000..3c60eb13a62a --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/aux.m4 @@ -0,0 +1,43 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)aux.m4 8.2 (Berkeley) 11/13/95') +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /usr/lib/aliases)')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /usr/lib/sendmail.st)')dnl +ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)')dnl +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', mn)')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail -d -r $f $u')')dnl diff --git a/usr.sbin/sendmail/cf/ostype/bsd4.3.m4 b/usr.sbin/sendmail/cf/ostype/bsd4.3.m4 new file mode 100644 index 000000000000..546fd376c93c --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/bsd4.3.m4 @@ -0,0 +1,39 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)bsd4.3.m4 8.4 (Berkeley) 11/13/95') +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl +ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -z -a$g $h!rmail ($u)')')dnl diff --git a/usr.sbin/sendmail/cf/ostype/bsd4.4.m4 b/usr.sbin/sendmail/cf/ostype/bsd4.4.m4 new file mode 100644 index 000000000000..835e4d89c6c1 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/bsd4.4.m4 @@ -0,0 +1,42 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +divert(0) +VERSIONID(`@(#)bsd4.4.m4 8.4 (Berkeley) 11/13/95') +ifdef(`HELP_FILE',, `define(`HELP_FILE', /usr/share/misc/sendmail.hf)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /var/log/sendmail.st)')dnl +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /usr/libexec/mail.local)')dnl +ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -z -a$g $h!rmail ($u)')')dnl diff --git a/usr.sbin/sendmail/cf/ostype/bsdi1.0.m4 b/usr.sbin/sendmail/cf/ostype/bsdi1.0.m4 new file mode 100644 index 000000000000..8bc3c218b41e --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/bsdi1.0.m4 @@ -0,0 +1,38 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)bsdi1.0.m4 8.2 (Berkeley) 8/16/95')dnl +include(_CF_DIR_`'ostype/bsd4.4.m4)dnl diff --git a/usr.sbin/sendmail/cf/ostype/bsdi2.0.m4 b/usr.sbin/sendmail/cf/ostype/bsdi2.0.m4 new file mode 100644 index 000000000000..a98ddc0d45c6 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/bsdi2.0.m4 @@ -0,0 +1,38 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)bsdi2.0.m4 8.1 (Berkeley) 8/16/95')dnl +include(_CF_DIR_`'ostype/bsd4.4.m4)dnl diff --git a/usr.sbin/sendmail/cf/ostype/dgux.m4 b/usr.sbin/sendmail/cf/ostype/dgux.m4 new file mode 100644 index 000000000000..e78ce3bca5aa --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/dgux.m4 @@ -0,0 +1,39 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)dgux.m4 8.2 (Berkeley) 11/13/95') +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', m)')dnl +define(`confTIME_ZONE', `USE_TZ')dnl diff --git a/usr.sbin/sendmail/cf/ostype/domainos.m4 b/usr.sbin/sendmail/cf/ostype/domainos.m4 new file mode 100644 index 000000000000..65329f3e1728 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/domainos.m4 @@ -0,0 +1,42 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)domainos.m4 8.2 (Berkeley) 11/13/95') +divert(-1) + +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /usr/lib/aliases)') +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /usr/lib/sendmail.st)') +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)') diff --git a/usr.sbin/sendmail/cf/ostype/dynix3.2.m4 b/usr.sbin/sendmail/cf/ostype/dynix3.2.m4 new file mode 100644 index 000000000000..149f6ad3a6fc --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/dynix3.2.m4 @@ -0,0 +1,39 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)dynix3.2.m4 8.2 (Berkeley) 11/13/95') +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /usr/lib/aliases)')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl diff --git a/usr.sbin/sendmail/cf/ostype/hpux10.m4 b/usr.sbin/sendmail/cf/ostype/hpux10.m4 new file mode 100644 index 000000000000..7c8ba4090dce --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/hpux10.m4 @@ -0,0 +1,51 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)hpux10.m4 8.6 (Berkeley) 11/13/95') + +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /var/spool/mqueue)')dnl +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /etc/mail/aliases)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /etc/mail/sendmail.st)')dnl +ifdef(`HELP_FILE',, `define(`HELP_FILE', /usr/share/lib/sendmail.hf)')dnl +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /usr/bin/rmail)')dnl +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `m')')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `rmail -d $u')')dnl +ifdef(`LOCAL_SHELL_PATH',, `define(`LOCAL_SHELL_PATH', /usr/bin/sh)')dnl +ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -a$g -gC $h!rmail ($u)')')dnl +define(`confTIME_ZONE', `USE_TZ')dnl +dnl +dnl For maximum compability with HP-UX, use: +dnl define(`confME_TOO', True)dnl diff --git a/usr.sbin/sendmail/cf/ostype/hpux9.m4 b/usr.sbin/sendmail/cf/ostype/hpux9.m4 new file mode 100644 index 000000000000..7a120052e424 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/hpux9.m4 @@ -0,0 +1,49 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)hpux9.m4 8.10 (Berkeley) 11/13/95') + +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /usr/lib/aliases)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /usr/lib/sendmail.st)')dnl +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', `/bin/rmail')')dnl +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `m')')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `rmail -d $u')')dnl +ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -a$g -gC $h!rmail ($u)')')dnl +define(`confTIME_ZONE', `USE_TZ')dnl +dnl +dnl For maximum compability with HP-UX, use: +dnl define(`confME_TOO', True)dnl diff --git a/usr.sbin/sendmail/cf/ostype/irix4.m4 b/usr.sbin/sendmail/cf/ostype/irix4.m4 new file mode 100644 index 000000000000..e24b008823e4 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/irix4.m4 @@ -0,0 +1,41 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)irix4.m4 8.5 (Berkeley) 11/13/95') +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', Ehm)')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /usr/lib/aliases)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /usr/lib/sendmail.st)')dnl diff --git a/usr.sbin/sendmail/cf/ostype/irix5.m4 b/usr.sbin/sendmail/cf/ostype/irix5.m4 new file mode 100644 index 000000000000..79843da6dbeb --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/irix5.m4 @@ -0,0 +1,61 @@ +divert(-1) +# +# Copyright (c) 1995 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Contributed by Kari E. Hurtta <Kari.Hurtta@dionysos.fmi.fi> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# Notes: +# - SGI's /etc/sendmail.cf defines also 'u' for local mailer flags -- you +# perhaps don't want it. +# - Perhaps is should also add define(`LOCAL_MAILER_CHARSET', iso-8859-1) +# put some Asian sites may prefer otherwise -- or perhaps not. +# - SGI's /etc/sendmail.cf seems use: A=mail -s -d $u +# It seems work without that -s however. +# - SGI's /etc/sendmail.cf set's default uid and gid to 998 (guest) +# - In SGI seems that TZ variable is needed that correct time is marked to +# syslog +# - helpfile is in /etc/sendmail.hf in SGI's /etc/sendmail.cf +# + +divert(0) +VERSIONID(`@(#)irix5.m4 8.2 (Berkeley) 11/13/95') +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', Ehmu)')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail -s -d $u')')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /var/spool/mqueue)')dnl +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /etc/aliases)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /var/sendmail.st)')dnl +ifdef(`HELP_FILE',, `define(`HELP_FILE', /etc/sendmail.hf)')dnl +define(`confDEF_USER_ID', `998:998')dnl +define(`confTIME_ZONE', USE_TZ)dnl diff --git a/usr.sbin/sendmail/cf/ostype/isc4.1.m4 b/usr.sbin/sendmail/cf/ostype/isc4.1.m4 new file mode 100644 index 000000000000..258f5450bb93 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/isc4.1.m4 @@ -0,0 +1,48 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +divert(0) +VERSIONID(`@(#)isc4.1.m4 8.2 (Berkeley) 11/13/95') +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /usr/lib/aliases)')dnl +ifdef(`HELP_FILE',, `define(`HELP_FILE', /usr/lib/sendmail.hf)')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `lmail -s $u')')dnl +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `humS')')dnl +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /bin/lmail)')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /usr/lib/sendmail.st)')dnl +ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -gC $h!rmail ($u)')')dnl +ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)')dnl +define(`confTIME_ZONE', `USE_TZ')dnl diff --git a/usr.sbin/sendmail/cf/ostype/nextstep.m4 b/usr.sbin/sendmail/cf/ostype/nextstep.m4 new file mode 100644 index 000000000000..515757aaf82b --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/nextstep.m4 @@ -0,0 +1,44 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)nextstep.m4 8.5 (Berkeley) 11/13/95') +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /etc/sendmail/aliases)')dnl +ifdef(`HELP_FILE',, `define(`HELP_FILE', /usr/lib/sendmail.hf)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /etc/sendmail/sendmail.st)')dnl +ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `rmnP')')dnl +ifdef(`LOCAL_SHELL_FLAGS',, `define(`LOCAL_SHELL_FLAGS', `euP')')dnl diff --git a/usr.sbin/sendmail/cf/ostype/osf1.m4 b/usr.sbin/sendmail/cf/ostype/osf1.m4 new file mode 100644 index 000000000000..107cd7507171 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/osf1.m4 @@ -0,0 +1,40 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)osf1.m4 8.3 (Berkeley) 11/13/95') +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /usr/adm/sendmail/aliases)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /usr/adm/sendmail/sendmail.st)')dnl +ifdef(`HELP_FILE',, `define(`HELP_FILE', /usr/share/lib/sendmail.hf)')dnl diff --git a/usr.sbin/sendmail/cf/ostype/ptx2.m4 b/usr.sbin/sendmail/cf/ostype/ptx2.m4 new file mode 100644 index 000000000000..365d21a1bbdd --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/ptx2.m4 @@ -0,0 +1,45 @@ +divert(-1) +# +# Copyright (c) 1994 Eric P. Allman +# Copyright (c) 1994 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# Support for DYNIX/ptx 2.x. + +divert(0) +VERSIONID(`@(#)ptx2.m4 8.1 (Berkeley) 12/4/94') +ifdef(`ALIAS_FILE',,`define(`ALIAS_FILE', /usr/lib/aliases)')dnl +ifdef(`HELP_FILE',,`define(`HELP_FILE', /usr/lib/sendmail.hf)')dnl +ifdef(`STATUS_FILE',,`define(`STATUS_FILE', /usr/lib/sendmail.st)')dnl +define(`LOCAL_MAILER_PATH', `/bin/mail')dnl +define(`LOCAL_MAILER_FLAGS', `rmn')dnl +define(`LOCAL_SHELL_FLAGS', `e')dnl diff --git a/usr.sbin/sendmail/cf/ostype/riscos4.5.m4 b/usr.sbin/sendmail/cf/ostype/riscos4.5.m4 new file mode 100644 index 000000000000..7e8f382d0e0e --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/riscos4.5.m4 @@ -0,0 +1,42 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)riscos4.5.m4 8.3 (Berkeley) 11/13/95') + +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `rmail -d $u')')dnl +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', `/usr/lib/aliases')')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', `/usr/spool/mqueue')')dnl +ifdef(`HELP_FILE',, `define(`HELP_FILE', `/usr/lib/sendmail.hf')')dnl diff --git a/usr.sbin/sendmail/cf/ostype/sco3.2.m4 b/usr.sbin/sendmail/cf/ostype/sco3.2.m4 new file mode 100644 index 000000000000..06fc050197c3 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/sco3.2.m4 @@ -0,0 +1,45 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)sco3.2.m4 8.2 (Berkeley) 11/13/95') +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /usr/lib/mail/aliases)')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /usr/lib/sendmail.st)')dnl +ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)')dnl +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /usr/bin/lmail)')dnl +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', PuhCE)')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `lmail $u')')dnl +ifdef(`LOCAL_SHELL_FLAGS',, `define(`LOCAL_SHELL_FLAGS', Peu)')dnl diff --git a/usr.sbin/sendmail/cf/ostype/solaris2.m4 b/usr.sbin/sendmail/cf/ostype/solaris2.m4 new file mode 100644 index 000000000000..9a7b0703ecbb --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/solaris2.m4 @@ -0,0 +1,45 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)solaris2.m4 8.6 (Berkeley) 11/13/95') +divert(-1) + +ifdef(`ALIAS_FILE',, `define(`ALIAS_FILE', /etc/mail/aliases)') +ifdef(`HELP_FILE',, `define(`HELP_FILE', /etc/mail/sendmail.hf)') +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /etc/mail/sendmail.st)') +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `SnE')') +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail -f $g -d $u')') +define(`confCW_FILE', /etc/mail/sendmail.cw) diff --git a/usr.sbin/sendmail/cf/ostype/svr4.m4 b/usr.sbin/sendmail/cf/ostype/svr4.m4 new file mode 100644 index 000000000000..ae18c1038b7e --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/svr4.m4 @@ -0,0 +1,45 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)svr4.m4 8.2 (Berkeley) 5/26/95') + +ifdef(`ALIAS_FILE',,`define(`ALIAS_FILE', /usr/ucblib/aliases)')dnl +ifdef(`HELP_FILE',,`define(`HELP_FILE', /usr/ucblib/sendmail.hf)')dnl +ifdef(`STATUS_FILE',,`define(`STATUS_FILE', /usr/ucblib/sendmail.st)')dnl +define(`LOCAL_MAILER_PATH', `/usr/ucblib/binmail')dnl +define(`LOCAL_MAILER_FLAGS', `rmn')dnl +define(`LOCAL_SHELL_FLAGS', `ehuP')dnl +define(`UUCP_MAILER_ARGS', `uux - -r -a$g -gmedium $h!rmail ($u)')dnl diff --git a/usr.sbin/sendmail/cf/ostype/ultrix4.m4 b/usr.sbin/sendmail/cf/ostype/ultrix4.m4 new file mode 100644 index 000000000000..f6998e1c5cab --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/ultrix4.m4 @@ -0,0 +1,37 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)ultrix4.m4 8.2 (Berkeley) 7/2/94') diff --git a/usr.sbin/sendmail/cf/ostype/unknown.m4 b/usr.sbin/sendmail/cf/ostype/unknown.m4 new file mode 100644 index 000000000000..7aadbb505d4b --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/unknown.m4 @@ -0,0 +1,41 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)unknown.m4 8.1 (Berkeley) 4/21/95') +errprint(`*** ERROR: You have not specified a valid operating system type.') +errprint(` Use the OSTYPE macro to select a valid system type. This') +errprint(` is necessary in order to get the proper pathnames and flags') +errprint(` appropriate for your environment.') diff --git a/usr.sbin/sendmail/cf/sh/makeinfo.sh b/usr.sbin/sendmail/cf/sh/makeinfo.sh new file mode 100644 index 000000000000..68b85d30c6a2 --- /dev/null +++ b/usr.sbin/sendmail/cf/sh/makeinfo.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# @(#)makeinfo.sh 8.6 (Berkeley) 8/6/95 +# + +usewhoami=0 +usehostname=0 +for p in `echo $PATH | sed 's/:/ /g'` +do + if [ "x$p" = "x" ] + then + p="." + fi + if [ -f $p/whoami ] + then + usewhoami=1 + if [ $usehostname -ne 0 ] + then + break; + fi + fi + if [ -f $p/hostname ] + then + usehostname=1 + if [ $usewhoami -ne 0 ] + then + break; + fi + fi +done +if [ $usewhoami -ne 0 ] +then + user=`whoami` +else + user=$LOGNAME +fi + +if [ $usehostname -ne 0 ] +then + host=`hostname` +else + host=`uname -n` +fi +echo '#####' built by $user@$host on `date` +echo '#####' in `pwd` | sed 's/\/tmp_mnt//' +echo '#####' using $1 as configuration include directory | sed 's/\/tmp_mnt//' +echo "define(\`__HOST__', $host)dnl" diff --git a/usr.sbin/sendmail/contrib/bitdomain.c b/usr.sbin/sendmail/contrib/bitdomain.c new file mode 100644 index 000000000000..52d6d2187c3f --- /dev/null +++ b/usr.sbin/sendmail/contrib/bitdomain.c @@ -0,0 +1,409 @@ +/* + * By John G. Myers, jgm+@cmu.edu + * Version 1.2 + * + * Process a BITNET "internet.listing" file, producing output + * suitable for input to makemap. + * + * The input file can be obtained via anonymous FTP to bitnic.educom.edu. + * Change directory to "netinfo" and get the file internet.listing + * The file is updated monthly. + * + * Feed the output of this program to "makemap hash /etc/bitdomain.db" + * to create the table used by the "FEATURE(bitdomain)" config file macro. + * If your sendmail does not have the db library compiled in, you can instead + * use "makemap dbm /etc/bitdomain" and + * "FEATURE(bitdomain,`dbm -o /etc/bitdomain')" + * + * The bitdomain table should be rebuilt monthly. + */ + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +#include <netdb.h> +#include <ctype.h> +#include <string.h> + +/* don't use sizeof because sizeof(long) is different on 64-bit machines */ +#define SHORTSIZE 2 /* size of a short (really, must be 2) */ +#define LONGSIZE 4 /* size of a long (really, must be 4) */ + +typedef union +{ + HEADER qb1; + char qb2[PACKETSZ]; +} querybuf; + +extern int h_errno; +extern char *malloc(); +extern char *optarg; +extern int optind; + +char *lookup(); + +main(argc, argv) +int argc; +char **argv; +{ + int opt; + + while ((opt = getopt(argc, argv, "o:")) != EOF) { + switch (opt) { + case 'o': + if (!freopen(optarg, "w", stdout)) { + perror(optarg); + exit(1); + } + break; + + default: + fprintf(stderr, "usage: %s [-o outfile] [internet.listing]\n", + argv[0]); + exit(1); + } + } + + if (optind < argc) { + if (!freopen(argv[optind], "r", stdin)) { + perror(argv[optind]); + exit(1); + } + } + readfile(stdin); + finish(); + exit(0); +} + +/* + * Parse and process an input file + */ +readfile(infile) +FILE *infile; +{ + int skippingheader = 1; + char buf[1024], *node, *hostname, *p; + + while (fgets(buf, sizeof(buf), infile)) { + for (p = buf; *p && isspace(*p); p++); + if (!*p) { + skippingheader = 0; + continue; + } + if (skippingheader) continue; + + node = p; + for (; *p && !isspace(*p); p++) { + if (isupper(*p)) *p = tolower(*p); + } + if (!*p) { + fprintf(stderr, "%-8s: no domain name in input file\n", node); + continue; + } + *p++ = '\0'; + + for (; *p && isspace(*p); p++) ; + if (!*p) { + fprintf(stderr, "%-8s no domain name in input file\n", node); + continue; + } + + hostname = p; + for (; *p && !isspace(*p); p++) { + if (isupper(*p)) *p = tolower(*p); + } + *p = '\0'; + + /* Chop off any trailing .bitnet */ + if (strlen(hostname) > 7 && + !strcmp(hostname+strlen(hostname)-7, ".bitnet")) { + hostname[strlen(hostname)-7] = '\0'; + } + entry(node, hostname, sizeof(buf)-(hostname - buf)); + } +} + +/* + * Process a single entry in the input file. + * The entry tells us that "node" expands to "domain". + * "domain" can either be a domain name or a bitnet node name + * The buffer pointed to by "domain" may be overwritten--it + * is of size "domainlen". + */ +entry(node, domain, domainlen) +char *node; +char *domain; +char *domainlen; +{ + char *otherdomain, *p, *err; + + /* See if we have any remembered information about this node */ + otherdomain = lookup(node); + + if (otherdomain && strchr(otherdomain, '.')) { + /* We already have a domain for this node */ + if (!strchr(domain, '.')) { + /* + * This entry is an Eric Thomas FOO.BITNET kludge. + * He doesn't want LISTSERV to do transitive closures, so we + * do them instead. Give the the domain expansion for "node" + * (which is in "otherdomian") to FOO (which is in "domain") + * if "domain" doesn't have a domain expansion already. + */ + p = lookup(domain); + if (!p || !strchr(p, '.')) remember(domain, otherdomain); + } + } + else { + if (!strchr(domain, '.') || valhost(domain, domainlen)) { + remember(node, domain); + if (otherdomain) { + /* + * We previously mapped the node "node" to the node + * "otherdomain". If "otherdomain" doesn't already + * have a domain expansion, give it the expansion "domain". + */ + p = lookup(otherdomain); + if (!p || !strchr(p, '.')) remember(otherdomain, domain); + } + } + else { + switch (h_errno) { + case HOST_NOT_FOUND: + err = "not registered in DNS"; + break; + + case TRY_AGAIN: + err = "temporary DNS lookup failure"; + break; + + case NO_RECOVERY: + err = "non-recoverable nameserver error"; + break; + + case NO_DATA: + err = "registered in DNS, but not mailable"; + break; + + default: + err = "unknown nameserver error"; + break; + } + + fprintf(stderr, "%-8s %s %s\n", node, domain, err); + } + } +} + +/* + * Validate whether the mail domain "host" is registered in the DNS. + * If "host" is a CNAME, it is expanded in-place if the expansion fits + * into the buffer of size "hbsize". Returns nonzero if it is, zero + * if it is not. A BIND error code is left in h_errno. + */ +int +valhost(host, hbsize) + char *host; + int hbsize; +{ + register u_char *eom, *ap; + register int n; + HEADER *hp; + querybuf answer; + int ancount, qdcount; + int ret; + int type; + int qtype; + char nbuf[1024]; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) + return (0); + + _res.options &= ~(RES_DNSRCH|RES_DEFNAMES); + _res.retrans = 30; + _res.retry = 10; + + qtype = T_ANY; + + for (;;) { + h_errno = NO_DATA; + ret = res_querydomain(host, "", C_IN, qtype, + &answer, sizeof(answer)); + if (ret <= 0) + { + if (errno == ECONNREFUSED || h_errno == TRY_AGAIN) + { + /* the name server seems to be down */ + h_errno = TRY_AGAIN; + return 0; + } + + if (h_errno != HOST_NOT_FOUND) + { + /* might have another type of interest */ + if (qtype == T_ANY) + { + qtype = T_A; + continue; + } + else if (qtype == T_A) + { + qtype = T_MX; + continue; + } + } + + /* otherwise, no record */ + return 0; + } + + /* + ** This might be a bogus match. Search for A, MX, or + ** CNAME records. + */ + + hp = (HEADER *) &answer; + ap = (u_char *) &answer + sizeof(HEADER); + eom = (u_char *) &answer + ret; + + /* skip question part of response -- we know what we asked */ + for (qdcount = ntohs(hp->qdcount); qdcount--; ap += ret + QFIXEDSZ) + { + if ((ret = dn_skipname(ap, eom)) < 0) + { + return 0; /* ???XXX??? */ + } + } + + for (ancount = ntohs(hp->ancount); --ancount >= 0 && ap < eom; ap += n) + { + n = dn_expand((u_char *) &answer, eom, ap, + (u_char *) nbuf, sizeof nbuf); + if (n < 0) + break; + ap += n; + GETSHORT(type, ap); + ap += SHORTSIZE + LONGSIZE; + GETSHORT(n, ap); + switch (type) + { + case T_MX: + case T_A: + return 1; + + case T_CNAME: + /* value points at name */ + if ((ret = dn_expand((u_char *)&answer, + eom, ap, (u_char *)nbuf, sizeof(nbuf))) < 0) + break; + if (strlen(nbuf) < hbsize) { + (void)strcpy(host, nbuf); + } + return 1; + + default: + /* not a record of interest */ + continue; + } + } + + /* + ** If this was a T_ANY query, we may have the info but + ** need an explicit query. Try T_A, then T_MX. + */ + + if (qtype == T_ANY) + qtype = T_A; + else if (qtype == T_A) + qtype = T_MX; + else + return 0; + } +} + +struct entry { + struct entry *next; + char *node; + char *domain; +}; +struct entry *firstentry; + +/* + * Find any remembered information about "node" + */ +char *lookup(node) +char *node; +{ + struct entry *p; + + for (p = firstentry; p; p = p->next) { + if (!strcmp(node, p->node)) { + return p->domain; + } + } + return 0; +} + +/* + * Mark the node "node" as equivalent to "domain". "domain" can either + * be a bitnet node or a domain name--if it is the latter, the mapping + * will be written to stdout. + */ +remember(node, domain) +char *node; +char *domain; +{ + struct entry *p; + + if (strchr(domain, '.')) { + fprintf(stdout, "%-8s %s\n", node, domain); + } + + for (p = firstentry; p; p = p->next) { + if (!strcmp(node, p->node)) { + p->domain = malloc(strlen(domain)+1); + if (!p->domain) { + goto outofmemory; + } + strcpy(p->domain, domain); + return; + } + } + + p = (struct entry *)malloc(sizeof(struct entry)); + if (!p) goto outofmemory; + + p->next = firstentry; + firstentry = p; + p->node = malloc(strlen(node)+1); + p->domain = malloc(strlen(domain)+1); + if (!p->node || !p->domain) goto outofmemory; + strcpy(p->node, node); + strcpy(p->domain, domain); + return; + + outofmemory: + fprintf(stderr, "Out of memory\n"); + exit(1); +} + +/* + * Walk through the database, looking for any cases where we know + * node FOO is equivalent to node BAR and node BAR has a domain name. + * For those cases, give FOO the same domain name as BAR. + */ +finish() +{ + struct entry *p; + char *domain; + + for (p = firstentry; p; p = p->next) { + if (!strchr(p->domain, '.') && (domain = lookup(p->domain))) { + remember(p->node, domain); + } + } +} + diff --git a/usr.sbin/sendmail/contrib/bsdi.mc b/usr.sbin/sendmail/contrib/bsdi.mc new file mode 100644 index 000000000000..231a7bc77ac6 --- /dev/null +++ b/usr.sbin/sendmail/contrib/bsdi.mc @@ -0,0 +1,191 @@ +Return-Path: sanders@austin.BSDI.COM +Received: from hofmann.CS.Berkeley.EDU (hofmann.CS.Berkeley.EDU [128.32.34.35]) by orodruin.CS.Berkeley.EDU (8.6.9/8.7.0.Beta0) with ESMTP id KAA28278 for <eric@orodruin.CS.Berkeley.EDU>; Sat, 10 Dec 1994 10:49:08 -0800 +Received: from austin.BSDI.COM (austin.BSDI.COM [137.39.95.2]) by hofmann.CS.Berkeley.EDU (8.6.9/8.6.6.Beta11) with ESMTP id KAA09482 for <eric@cs.berkeley.edu>; Sat, 10 Dec 1994 10:49:03 -0800 +Received: from austin.BSDI.COM (sanders@localhost [127.0.0.1]) by austin.BSDI.COM (8.6.9/8.6.9) with ESMTP id MAA14919 for <eric@cs.berkeley.edu>; Sat, 10 Dec 1994 12:49:01 -0600 +Message-Id: <199412101849.MAA14919@austin.BSDI.COM> +To: Eric Allman <eric@cs.berkeley.edu> +Subject: Re: sorting mailings lists with fastest delivery users first +In-reply-to: Your message of Sat, 10 Dec 1994 08:25:30 PST. +References: <199412101625.IAA15407@mastodon.CS.Berkeley.EDU> +From: Tony Sanders <sanders@bsdi.com> +Organization: Berkeley Software Design, Inc. +Date: Sat, 10 Dec 1994 12:49:00 -0600 +Sender: sanders@austin.BSDI.COM + +(some random text deleted) + +I'll send you something else I've hacked up. You are free to use this +or do with it as you like (I hereby make all my parts public domain). +It's a sample .mc file that has comments (mostly taken from the README) +and examples describing most of the common things people need to setup. + +# +# /usr/share/sendmail/cf/sample.mc +# +# Do not edit /etc/sendmail.cf directly unless you cannot do what you +# want in the master config file (/usr/share/sendmail/cf/sample.mc). +# To create /etc/sendmail.cf from the master: +# cd /usr/share/sendmail/cf +# mv /etc/sendmail.cf /etc/sendmail.cf.save +# m4 < sample.mc > /etc/sendmail.cf +# +# Then kill and restart sendmail: +# sh -c 'set `cat /var/run/sendmail.pid`; kill $1; shift; eval "$@"' +# +# See /usr/share/sendmail/README for help in building a configuration file. +# +include(`../m4/cf.m4') +VERSIONID(`@(#)$Id$') + +dnl # Specify your OS type below +OSTYPE(`bsd4.4') + +dnl # NOTE: `dnl' is the m4 command for delete-to-newline; these are +dnl # used to prevent those lines from appearing in the sendmail.cf. +dnl # +dnl # UUCP-only sites should configure FEATURE(`nodns') and SMART_HOST. +dnl # The uucp-dom mailer requires MAILER(smtp). For more info, see +dnl # `UUCP Config' at the end of this file. + +dnl # If you are not running DNS at all, it is important to use +dnl # FEATURE(nodns) to avoid having sendmail queue everything +dnl # waiting for the name server to come up. +dnl # Example: +dnl FEATURE(`nodns') + +dnl # Use FEATURE(`nocanonify') to skip address canonification via $[ ... $]. +dnl # This would generally only be used by sites that only act as mail gateways +dnl # or which have user agents that do full canonification themselves. +dnl # You may also want to use: +dnl # define(`confBIND_OPTS',`-DNSRCH -DEFNAMES') +dnl # to turn off the usual resolver options that do a similar thing. +dnl # Examples: +dnl FEATURE(`nocanonify') +dnl define(`confBIND_OPTS',`-DNSRCH -DEFNAMES') + +dnl # If /bin/hostname is not set to the FQDN (Full Qualified Domain Name; +dnl # for example, foo.bar.com) *and* you are not running a nameserver +dnl # (that is, you do not have an /etc/resolv.conf and are not running +dnl # named) *and* the canonical name for your machine in /etc/hosts +dnl # (the canonical name is the first name listed for a given IP Address) +dnl # is not the FQDN version then define NEED_DOMAIN and specify your +dnl # domain using `DD' (for example, if your hostname is `foo.bar.com' +dnl # then use DDbar.com). If in doubt, just define it anyway; doesn't hurt. +dnl # Examples: +dnl define(`NEED_DOMAIN', `1') +dnl DDyour.site.domain + +dnl # Define SMART_HOST if you want all outgoing mail to go to a central +dnl # site. SMART_HOST applies to names qualified with non-local names. +dnl # Example: +dnl define(`SMART_HOST', `smtp:firewall.bar.com') + +dnl # Define MAIL_HUB if you want all incoming mail sent to a +dnl # centralized hub, as for a shared /var/spool/mail scheme. +dnl # MAIL_HUB applies to names qualified with the name of the +dnl # local host (e.g., "eric@foo.bar.com"). +dnl # Example: +dnl define(`MAIL_HUB', `smtp:mailhub.bar.com') + +dnl # LOCAL_RELAY is a site that will handle unqualified names, this is +dnl # basically for site/company/department wide alias forwarding. By +dnl # default mail is delivered on the local host. +dnl # Example: +dnl define(`LOCAL_RELAY', `smtp:mailgate.bar.com') + +dnl # Relay hosts for fake domains: .UUCP .BITNET .CSNET +dnl # Examples: +dnl define(`UUCP_RELAY', `mailer:your_relay_host') +dnl define(`BITNET_RELAY', `mailer:your_relay_host') +dnl define(`CSNET_RELAY', `mailer:your_relay_host') + +dnl # Define `MASQUERADE_AS' is used to hide behind a gateway. +dnl # add any accounts you wish to be exposed (i.e., not hidden) to the +dnl # `EXPOSED_USER' list. +dnl # Example: +dnl MASQUERADE_AS(`some.other.host') + +dnl # If masquerading, EXPOSED_USER defines the list of accounts +dnl # that retain the local hostname in their address. +dnl # Example: +dnl EXPOSED_USER(`postmaster hostmaster webmaster') + +dnl # If masquerading is enabled (using MASQUERADE_AS above) then +dnl # FEATURE(allmasquerade) will cause recipient addresses to +dnl # masquerade as being from the masquerade host instead of +dnl # getting the local hostname. Although this may be right for +dnl # ordinary users, it breaks local aliases that aren't exposed +dnl # using EXPOSED_USER. +dnl # Example: +dnl FEATURE(allmasquerade) + +dnl # Include any required mailers +MAILER(local) +MAILER(smtp) +MAILER(uucp) + +LOCAL_CONFIG +# If this machine should be accepting mail as local for other hostnames +# that are MXed to this hostname then add those hostnames below using +# a line like: +# Cw bar.com +# The most common case where you need this is if this machine is supposed +# to be accepting mail for the domain. That is, if this machine is +# foo.bar.com and you have an MX record in the DNS that looks like: +# bar.com. IN MX 0 foo.bar.com. +# Then you will need to add `Cw bar.com' to the config file for foo.bar.com. +# DO NOT add Cw entries for hosts whom you simply store and forward mail +# for or else it will attempt local delivery. So just because bubba.bar.com +# is MXed to your machine you should not add a `Cw bubba.bar.com' entry +# unless you want local delivery and your machine is the highest-priority +# MX entry (that is is has the lowest preference value in the DNS. + +LOCAL_RULE_0 +# `LOCAL_RULE_0' can be used to introduce alternate delivery rules. +# For example, let's say you accept mail via an MX record for widgets.com +# (don't forget to add widgets.com to your Cw list, as above). +# +# If wigets.com only has an AOL address (widgetsinc) then you could use: +# R$+ <@ widgets.com.> $#smtp $@aol.com. $:widgetsinc<@aol.com.> +# +# Or, if widgets.com was connected to you via UUCP as the UUCP host +# widgets you might have: +# R$+ <@ widgets.com.> $#uucp $@widgets $:$1<@widgets.com.> + +dnl ### +dnl ### UUCP Config +dnl ### + +dnl # `SITECONFIG(site_config_file, name_of_site, connection)' +dnl # site_config_file the name of a file in the cf/siteconfig +dnl # directory (less the `.m4') +dnl # name_of_site the actual name of your UUCP site +dnl # connection one of U, W, X, or Y; where U means the sites listed +dnl # in the config file are connected locally; W, X, and Y +dnl # build remote UUCP hub classes ($=W, etc). +dnl # You will need to create the specific site_config_file in +dnl # /usr/share/sendmail/siteconfig/site_config_file.m4 +dnl # The site_config_file contains a list of directly connected UUCP hosts, +dnl # e.g., if you only connect to UUCP site gargoyle then you could just: +dnl # echo 'SITE(gargoyle)' > /usr/share/sendmail/siteconfig/uucp.foobar.m4 +dnl # Example: +dnl SITECONFIG(`uucp.foobar', `foobar', U) + +dnl # If you are on a local SMTP-based net that connects to the outside +dnl # world via UUCP, you can use LOCAL_NET_CONFIG to add appropriate rules. +dnl # For example: +dnl # define(`SMART_HOST', suucp:uunet) +dnl # LOCAL_NET_CONFIG +dnl # R$* < @ $* .$m. > $* $#smtp $@ $2.$m. $: $1 < @ $2.$m. > $3 +dnl # This will cause all names that end in your domain name ($m) to be sent +dnl # via SMTP; anything else will be sent via suucp (smart UUCP) to uunet. +dnl # If you have FEATURE(nocanonify), you may need to omit the dots after +dnl # the $m. +dnl # +dnl # If you are running a local DNS inside your domain which is not +dnl # otherwise connected to the outside world, you probably want to use: +dnl # define(`SMART_HOST', smtp:fire.wall.com) +dnl # LOCAL_NET_CONFIG +dnl # R$* < @ $* . > $* $#smtp $@ $2. $: $1 < @ $2. > $3 +dnl # That is, send directly only to things you found in your DNS lookup; +dnl # anything else goes through SMART_HOST. diff --git a/usr.sbin/sendmail/contrib/expn.pl b/usr.sbin/sendmail/contrib/expn.pl new file mode 100755 index 000000000000..270f483bc6f3 --- /dev/null +++ b/usr.sbin/sendmail/contrib/expn.pl @@ -0,0 +1,1367 @@ +#!/usr/bin/perl +'di '; +'ds 00 \\"'; +'ig 00 '; +# +# THIS PROGRAM IS ITS OWN MANUAL PAGE. INSTALL IN man & bin. +# + +# hardcoded constants, should work fine for BSD-based systems +require 'sys/socket.ph'; +$sockaddr = 'S n a4 x8'; + +# system requirements: +# must have 'nslookup' and 'hostname' programs. + +# $Header: /home/muir/bin/RCS/expn,v 3.9 1995/10/02 17:51:35 muir Exp muir $ + +# TODO: +# less magic should apply to command-line addresses +# less magic should apply to local addresses +# add magic to deal with cross-domain cnames + +# Checklist: (hard addresses) +# 250 Kimmo Suominen <"|/usr/local/mh/lib/slocal -user kim"@grendel.tac.nyc.ny.us> +# harry@hofmann.cs.Berkeley.EDU -> harry@tenet (.berkeley.edu) [dead] +# bks@cs.berkeley.edu -> shiva.CS (.berkeley.edu) [dead] +# dan@tc.cornell.edu -> brown@tiberius (.tc.cornell.edu) + +############################################################################# +# +# Copyright (c) 1993 David Muir Sharnoff +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the David Muir Sharnoff. +# 4. The name of David Sharnoff may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE DAVID MUIR SHARNOFF ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL DAVID MUIR SHARNOFF BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This copyright notice derrived from material copyrighted by the Regents +# of the University of California. +# +# Contributions accepted. +# +############################################################################# + +# overall structure: +# in an effort to not trace each address individually, but rather +# ask each server in turn a whole bunch of questions, addresses to +# be expanded are queued up. +# +# This means that all accounting w.r.t. an address must be stored in +# various arrays. Generally these arrays are indexed by the +# string "$addr *** $server" where $addr is the address to be +# expanded "foo" or maybe "foo@bar" and $server is the hostname +# of the SMTP server to contact. +# + +# important global variables: +# +# @hosts : list of servers still to be contacted +# $server : name of the current we are currently looking at +# @users = $users{@hosts[0]} : addresses to expand at this server +# $u = $users[0] : the current address being expanded +# $names{"$users[0] *** $server"} : the 'name' associated with the address +# $mxbacktrace{"$users[0] *** $server"} : record of mx expansion +# $mx_secondary{$server} : other mx relays at the same priority +# $domainify_fallback{"$users[0] *** $server"} : alternative names to try +# instead of $server if $server doesn't work +# $temporary_redirect{"$users[0] *** $server"} : when trying alternates, +# temporarily channel all tries along current path +# $giveup{$server} : do not bother expanding addresses at $server +# $verbose : -v +# $watch : -w +# $vw : -v or -w +# $debug : -d +# $valid : -a +# $levels : -1 +# S : the socket connection to $server + +$have_nslookup = 1; # we have the nslookup program +$port = 'smtp'; +$av0 = $0; +$ENV{'PATH'} .= ":/usr/etc" unless $ENV{'PATH'} =~ m,/usr/etc,; +$ENV{'PATH'} .= ":/usr/ucb" unless $ENV{'PATH'} =~ m,/usr/ucb,; +select(STDERR); + +$0 = "$av0 - running hostname"; +chop($name = `hostname || uname -n`); + +$0 = "$av0 - lookup host FQDN and IP addr"; +($hostname,$aliases,$type,$len,$thisaddr) = gethostbyname($name); + +$0 = "$av0 - parsing args"; +$usage = "Usage: $av0 [-1avwd] user[\@host] [user2[host2] ...]"; +for $a (@ARGV) { + die $usage if $a eq "-"; + while ($a =~ s/^(-.*)([1avwd])/$1/) { + eval '$'."flag_$2 += 1"; + } + next if $a eq "-"; + die $usage if $a =~ /^-/; + &expn(&parse($a,$hostname,undef,1)); +} +$verbose = $flag_v; +$watch = $flag_w; +$vw = $flag_v + $flag_w; +$debug = $flag_d; +$valid = $flag_a; +$levels = $flag_1; + +die $usage unless @hosts; +if ($valid) { + if ($valid == 1) { + $validRequirement = 0.8; + } elsif ($valid == 2) { + $validRequirement = 1.0; + } elsif ($valid == 3) { + $validRequirement = 0.9; + } else { + $validRequirement = (1 - (1/($valid-3))); + print "validRequirement = $validRequirement\n" if $debug; + } +} + +$0 = "$av0 - building local socket"; +($name,$aliases,$proto) = getprotobyname('tcp'); +($name,$aliases,$port) = getservbyname($port,'tcp') + unless $port =~ /^\d+/; +$this = pack($sockaddr, &AF_INET, 0, $thisaddr); + +HOST: +while (@hosts) { + $server = shift(@hosts); + @users = split(' ',$users{$server}); + delete $users{$server}; + + # is this server already known to be bad? + $0 = "$av0 - looking up $server"; + if ($giveup{$server}) { + &giveup('mx domainify',$giveup{$server}); + next; + } + + # do we already have an mx record for this host? + next HOST if &mxredirect($server,*users); + + # look it up, or try for an mx. + $0 = "$av0 - gethostbyname($server)"; + + ($name,$aliases,$type,$len,$thataddr) = gethostbyname($server); + # if we can't get an A record, try for an MX record. + unless($thataddr) { + &mxlookup(1,$server,"$server: could not resolve name",*users); + next HOST; + } + + # get a connection, or look for an mx + $0 = "$av0 - socket to $server"; + $that = pack($sockaddr, &AF_INET, $port, $thataddr); + socket(S, &AF_INET, &SOCK_STREAM, $proto) + || die "socket: $!"; + $0 = "$av0 - bind to $server"; + bind(S, $this) + || die "bind $hostname,0: $!"; + $0 = "$av0 - connect to $server"; + print "debug = $debug server = $server\n" if $debug > 8; + if (! connect(S, $that) || ($debug == 10 && $server =~ /relay\d.UU.NET$/i)) { + $0 = "$av0 - $server: could not connect: $!\n"; + $emsg = $!; + unless (&mxlookup(0,$server,"$server: could not connect: $!",*users)) { + &giveup('mx',"$server: Could not connect: $emsg"); + } + next HOST; + } + select((select(S),$| = 1)[0]); # don't buffer output to S + + # read the greeting + $0 = "$av0 - talking to $server"; + &alarm("greeting with $server",''); + while(<S>) { + alarm(0); + print if $watch; + if (/^(\d+)([- ])/) { + if ($1 != 220) { + $0 = "$av0 - bad numeric response from $server"; + &alarm("giving up after bad response from $server",''); + &read_response($2,$watch); + alarm(0); + print STDERR "$server: NOT 220 greeting: $_" + if ($debug || $vw); + if (&mxlookup(0,$server,"$server: did not respond with a 220 greeting",*users)) { + close(S); + next HOST; + } + } + last if ($2 eq " "); + } else { + $0 = "$av0 - bad response from $server"; + print STDERR "$server: NOT 220 greeting: $_" + if ($debug || $vw); + unless (&mxlookup(0,$server,"$server: did not respond with SMTP codes",*users)) { + &giveup('',"$server: did not talk SMTP"); + } + close(S); + next HOST; + } + &alarm("greeting with $server",''); + } + alarm(0); + + # if this causes problems, remove it + $0 = "$av0 - sending helo to $server"; + &alarm("sending helo to $server",""); + &ps("helo $hostname"); + while(<S>) { + print if $watch; + last if /^\d+ /; + } + alarm(0); + + # try the users, one by one + USER: + while(@users) { + $u = shift(@users); + $0 = "$av0 - expanding $u [\@$server]"; + + # do we already have a name for this user? + $oldname = $names{"$u *** $server"}; + + print &compact($u,$server)." ->\n" if ($verbose && ! $valid); + if ($valid) { + # + # when running with -a, we delay taking any action + # on the results of our query until we have looked + # at the complete output. @toFinal stores expansions + # that will be final if we take them. @toExpn stores + # expnansions that are not final. @isValid keeps + # track of our ability to send mail to each of the + # expansions. + # + @isValid = (); + @toFinal = (); + @toExpn = (); + } + +# ($ecode,@expansion) = &expn_vrfy($u,$server); + (@foo) = &expn_vrfy($u,$server); + ($ecode,@expansion) = @foo; + if ($ecode) { + &giveup('',$ecode,$u); + last USER; + } + + for $s (@expansion) { + $s =~ s/[\n\r]//g; + $0 = "$av0 - parsing $server: $s"; + + $skipwatch = $watch; + + if ($s =~ /^[25]51([- ]).*<(.+)>/) { + print "$s" if $watch; + print "(pretending 250$1<$2>)" if ($debug && $watch); + print "\n" if $watch; + $s = "250$1<$2>"; + $skipwatch = 0; + } + + if ($s =~ /^250([- ])(.+)/) { + print "$s\n" if $skipwatch; + ($done,$addr) = ($1,$2); + ($newhost, $newaddr, $newname) = &parse($addr,$server,$oldname, $#expansion == 0); + print "($newhost, $newaddr, $newname) = &parse($addr, $server, $oldname)\n" if $debug; + if (! $newhost) { + # no expansion is possible w/o a new server to call + if ($valid) { + push(@isValid, &validAddr($newaddr)); + push(@toFinal,$newaddr,$server,$newname); + } else { + &verbose(&final($newaddr,$server,$newname)); + } + } else { + $newmxhost = &mx($newhost,$newaddr); + print "$newmxhost = &mx($newhost)\n" + if ($debug && $newhost ne $newmxhost); + $0 = "$av0 - parsing $newaddr [@$newmxhost]"; + print "levels = $levels, level{$u *** $server} = ".$level{"$u *** $server"}."\n" if ($debug > 1); + # If the new server is the current one, + # it would have expanded things for us + # if it could have. Mx records must be + # followed to compare server names. + # We are also done if the recursion + # count has been exceeded. + if (&trhost($newmxhost) eq &trhost($server) || ($levels && $level{"$u *** $server"} >= $levels)) { + if ($valid) { + push(@isValid, &validAddr($newaddr)); + push(@toFinal,$newaddr,$newmxhost,$newname); + } else { + &verbose(&final($newaddr,$newmxhost,$newname)); + } + } else { + # more work to do... + if ($valid) { + push(@isValid, &validAddr($newaddr)); + push(@toExpn,$newmxhost,$newaddr,$newname,$level{"$u *** $server"}); + } else { + &verbose(&expn($newmxhost,$newaddr,$newname,$level{"$u *** $server"})); + } + } + } + last if ($done eq " "); + next; + } + # 550 is a known code... Should the be + # included in -a output? Might be a bug + # here. Does it matter? Can assume that + # there won't be UNKNOWN USER responses + # mixed with valid users? + if ($s =~ /^(550)([- ])/) { + if ($valid) { + print STDERR "\@$server:$u ($oldname) USER UNKNOWN\n"; + } else { + &verbose(&final($u,$server,$oldname,"USER UNKNOWN")); + } + last if ($2 eq " "); + next; + } + # 553 is a known code... + if ($s =~ /^(553)([- ])/) { + if ($valid) { + print STDERR "\@$server:$u ($oldname) USER AMBIGUOUS\n"; + } else { + &verbose(&final($u,$server,$oldname,"USER AMBIGUOUS")); + } + last if ($2 eq " "); + next; + } + # 252 is a known code... + if ($s =~ /^(252)([- ])/) { + if ($valid) { + print STDERR "\@$server:$u ($oldname) REFUSED TO VRFY\n"; + } else { + &verbose(&final($u,$server,$oldname,"REFUSED TO VRFY")); + } + last if ($2 eq " "); + next; + } + &giveup('',"$server: did not grok '$s'",$u); + last USER; + } + + if ($valid) { + # + # now we decide if we are going to take these + # expansions or roll them back. + # + $avgValid = &average(@isValid); + print "avgValid = $avgValid\n" if $debug; + if ($avgValid >= $validRequirement) { + print &compact($u,$server)." ->\n" if $verbose; + while (@toExpn) { + &verbose(&expn(splice(@toExpn,0,4))); + } + while (@toFinal) { + &verbose(&final(splice(@toFinal,0,3))); + } + } else { + print "Tossing some valid to avoid invalid ".&compact($u,$server)."\n" if ($avgValid > 0.0 && ($vw || $debug)); + print &compact($u,$server)." ->\n" if $verbose; + &verbose(&final($u,$server,$newname)); + } + } + } + + &alarm("sending 'quit' to $server",''); + $0 = "$av0 - sending 'quit' to $server"; + &ps("quit"); + while(<S>) { + print if $watch; + last if /^\d+ /; + } + close(S); + alarm(0); +} + +$0 = "$av0 - printing final results"; +print "----------\n" if $vw; +select(STDOUT); +for $f (sort @final) { + print "$f\n"; +} +unlink("/tmp/expn$$"); +exit(0); + + +# abandon all attempts deliver to $server +# register the current addresses as the final ones +sub giveup +{ + local($redirect_okay,$reason,$user) = @_; + local($us,@so,$nh,@remaining_users); + local($pk,$file,$line); + ($pk, $file, $line) = caller; + + $0 = "$av0 - giving up on $server: $reason"; + # + # add back a user if we gave up in the middle + # + push(@users,$user) if $user; + # + # don't bother with this system anymore + # + unless ($giveup{$server}) { + $giveup{$server} = $reason; + print STDERR "$reason\n"; + } + print "Giveup at $file:$line!!! redirect okay = $redirect_okay; $reason\n" if $debug; + # + # Wait! + # Before giving up, see if there is a chance that + # there is another host to redirect to! + # (Kids, don't do this at home! Hacking is a dangerous + # crime and you could end up behind bars.) + # + for $u (@users) { + if ($redirect_okay =~ /\bmx\b/) { + next if &try_fallback('mx',$u,*server, + *mx_secondary, + *already_mx_fellback); + } + if ($redirect_okay =~ /\bdomainify\b/) { + next if &try_fallback('domainify',$u,*server, + *domainify_fallback, + *already_domainify_fellback); + } + push(@remaining_users,$u); + } + @users = @remaining_users; + for $u (@users) { + print &compact($u,$server)." ->\n" if ($verbose && $valid && $u); + &verbose(&final($u,$server,$names{"$u *** $server"},$reason)); + } +} +# +# This routine is used only within &giveup. It checks to +# see if we really have to giveup or if there is a second +# chance because we did something before that can be +# backtracked. +# +# %fallback{"$user *** $host"} tracks what is able to fallback +# %fellback{"$user *** $host"} tracks what has fallen back +# +# If there is a valid backtrack, then queue up the new possibility +# +sub try_fallback +{ + local($method,$user,*host,*fall_table,*fellback) = @_; + local($us,$fallhost,$oldhost,$ft,$i); + + if ($debug > 8) { + print "Fallback table $method:\n"; + for $i (sort keys %fall_table) { + print "\t'$i'\t\t'$fall_table{$i}'\n"; + } + print "Fellback table $method:\n"; + for $i (sort keys %fellback) { + print "\t'$i'\t\t'$fellback{$i}'\n"; + } + print "U: $user H: $host\n"; + } + + $us = "$user *** $host"; + if (defined $fellback{$us}) { + # + # Undo a previous fallback so that we can try again + # Nested fallbacks are avoided because they could + # lead to infinite loops + # + $fallhost = $fellback{$us}; + print "Already $method fell back from $us -> \n" if $debug; + $us = "$user *** $fallhost"; + $oldhost = $fallhost; + } elsif (($method eq 'mx') && (defined $mxbacktrace{$us}) && (defined $mx_secondary{$mxbacktrace{$us}})) { + print "Fallback an MX expansion $us -> \n" if $debug; + $oldhost = $mxbacktrace{$us}; + } else { + print "Oldhost($host, $us) = " if $debug; + $oldhost = $host; + } + print "$oldhost\n" if $debug; + if (((defined $fall_table{$us}) && ($ft = $us)) || ((defined $fall_table{$oldhost}) && ($ft = $oldhost))) { + print "$method Fallback = ".$fall_table{$ft}."\n" if $debug; + local(@so,$newhost); + @so = split(' ',$fall_table{$ft}); + $newhost = shift(@so); + print "Falling back ($method) $us -> $newhost (from $oldhost)\n" if $debug; + if ($method eq 'mx') { + if (! defined ($mxbacktrace{"$user *** $newhost"})) { + if (defined $mxbacktrace{"$user *** $oldhost"}) { + print "resetting oldhost $oldhost to the original: " if $debug; + $oldhost = $mxbacktrace{"$user *** $oldhost"}; + print "$oldhost\n" if $debug; + } + $mxbacktrace{"$user *** $newhost"} = $oldhost; + print "mxbacktrace $user *** $newhost -> $oldhost\n" if $debug; + } + $mx{&trhost($oldhost)} = $newhost; + } else { + $temporary_redirect{$us} = $newhost; + } + if (@so) { + print "Can still $method $us: @so\n" if $debug; + $fall_table{$ft} = join(' ',@so); + } else { + print "No more fallbacks for $us\n" if $debug; + delete $fall_table{$ft}; + } + if (defined $create_host_backtrack{$us}) { + $create_host_backtrack{"$user *** $newhost"} + = $create_host_backtrack{$us}; + } + $fellback{"$user *** $newhost"} = $oldhost; + &expn($newhost,$user,$names{$us},$level{$us}); + return 1; + } + delete $temporary_redirect{$us}; + $host = $oldhost; + return 0; +} +# return 1 if you could send mail to the address as is. +sub validAddr +{ + local($addr) = @_; + $res = &do_validAddr($addr); + print "validAddr($addr) = $res\n" if $debug; + $res; +} +sub do_validAddr +{ + local($addr) = @_; + local($urx) = "[-A-Za-z_.0-9+]+"; + + # \u + return 0 if ($addr =~ /^\\/); + # ?@h + return 1 if ($addr =~ /.\@$urx$/); + # @h:? + return 1 if ($addr =~ /^\@$urx\:./); + # h!u + return 1 if ($addr =~ /^$urx!./); + # u + return 1 if ($addr =~ /^$urx$/); + # ? + print "validAddr($addr) = ???\n" if $debug; + return 0; +} +# Some systems use expn and vrfy interchangeably. Some only +# implement one or the other. Some check expn against mailing +# lists and vrfy against users. It doesn't appear to be +# consistent. +# +# So, what do we do? We try everything! +# +# +# Ranking of result codes: good: 250, 251/551, 252, 550, anything else +# +# Ranking of inputs: best: user@host.domain, okay: user +# +# Return value: $error_string, @responses_from_server +sub expn_vrfy +{ + local($u,$server) = @_; + local(@c) = ('expn', 'vrfy'); + local(@try_u) = $u; + local(@ret,$code); + + if (($u =~ /(.+)@(.+)/) && (&trhost($2) eq &trhost($server))) { + push(@try_u,$1); + } + + TRY: + for $c (@c) { + for $try_u (@try_u) { + &alarm("${c}'ing $try_u on $server",'',$u); + &ps("$c $try_u"); + alarm(0); + $s = <S>; + if ($s eq '') { + return "$server: lost connection"; + } + if ($s !~ /^(\d+)([- ])/) { + return "$server: garbled reply to '$c $try_u'"; + } + if ($1 == 250) { + $code = 250; + @ret = ("",$s); + push(@ret,&read_response($2,$debug)); + return (@ret); + } + if ($1 == 551 || $1 == 251) { + $code = $1; + @ret = ("",$s); + push(@ret,&read_response($2,$debug)); + next; + } + if ($1 == 252 && ($code == 0 || $code == 550)) { + $code = 252; + @ret = ("",$s); + push(@ret,&read_response($2,$watch)); + next; + } + if ($1 == 550 && $code == 0) { + $code = 550; + @ret = ("",$s); + push(@ret,&read_response($2,$watch)); + next; + } + &read_response($2,$watch); + } + } + return "$server: expn/vrfy not implemented" unless @ret; + return @ret; +} +# sometimes the old parse routine (now parse2) didn't +# reject funky addresses. +sub parse +{ + local($oldaddr,$server,$oldname,$one_to_one) = @_; + local($newhost, $newaddr, $newname, $um) = &parse2($oldaddr,$server,$oldname,$one_to_one); + if ($newaddr =~ m,^["/],) { + return (undef, $oldaddr, $newname) if $valid; + return (undef, $um, $newname); + } + return ($newhost, $newaddr, $newname); +} + +# returns ($new_smtp_server,$new_address,$new_name) +# given a response from a SMTP server ($newaddr), the +# current host ($server), the old "name" and a flag that +# indicates if it is being called during the initial +# command line parsing ($parsing_args) +sub parse2 +{ + local($newaddr,$context_host,$old_name,$parsing_args) = @_; + local(@names) = $old_name; + local($urx) = "[-A-Za-z_.0-9+]+"; + local($unmangle); + + # + # first, separate out the address part. + # + + # + # [NAME] <ADDR [(NAME)]> + # [NAME] <[(NAME)] ADDR + # ADDR [(NAME)] + # (NAME) ADDR + # [(NAME)] <ADDR> + # + if ($newaddr =~ /^\<(.*)\>$/) { + print "<A:$1>\n" if $debug; + ($newaddr) = &trim($1); + print "na = $newaddr\n" if $debug; + } + if ($newaddr =~ /^([^\<\>]*)\<([^\<\>]*)\>([^\<\>]*)$/) { + # address has a < > pair in it. + print "N:$1 <A:$2> N:$3\n" if $debug; + ($newaddr) = &trim($2); + unshift(@names, &trim($3,$1)); + print "na = $newaddr\n" if $debug; + } + if ($newaddr =~ /^([^\(\)]*)\(([^\(\)]*)\)([^\(\)]*)$/) { + # address has a ( ) pair in it. + print "A:$1 (N:$2) A:$3\n" if $debug; + unshift(@names,&trim($2)); + local($f,$l) = (&trim($1),&trim($3)); + if (($f && $l) || !($f || $l)) { + # address looks like: + # foo (bar) baz or (bar) + # not allowed! + print STDERR "Could not parse $newaddr\n" if $vw; + return(undef,$newaddr,&firstname(@names)); + } + $newaddr = $f if $f; + $newaddr = $l if $l; + print "newaddr now = $newaddr\n" if $debug; + } + # + # @foo:bar + # j%k@l + # a@b + # b!a + # a + # + $unmangle = $newaddr; + if ($newaddr =~ /^\@($urx)\:(.+)$/) { + print "(\@:)" if $debug; + # this is a bit of a cheat, but it seems necessary + return (&domainify($1,$context_host,$2),$2,&firstname(@names),$unmangle); + } + if ($newaddr =~ /^(.+)\@($urx)$/) { + print "(\@)" if $debug; + return (&domainify($2,$context_host,$newaddr),$newaddr,&firstname(@names),$unmangle); + } + if ($parsing_args) { + if ($newaddr =~ /^($urx)\!(.+)$/) { + return (&domainify($1,$context_host,$newaddr),$newaddr,&firstname(@names),$unmangle); + } + if ($newaddr =~ /^($urx)$/) { + return ($context_host,$newaddr,&firstname(@names),$unmangle); + } + print STDERR "Could not parse $newaddr\n"; + } + print "(?)" if $debug; + return(undef,$newaddr,&firstname(@names),$unmangle); +} +# return $u (@$server) unless $u includes reference to $server +sub compact +{ + local($u, $server) = @_; + local($se) = $server; + local($sp); + $se =~ s/(\W)/\\$1/g; + $sp = " (\@$server)"; + if ($u !~ /$se/i) { + return "$u$sp"; + } + return $u; +} +# remove empty (spaces don't count) members from an array +sub trim +{ + local(@v) = @_; + local($v,@r); + for $v (@v) { + $v =~ s/^\s+//; + $v =~ s/\s+$//; + push(@r,$v) if ($v =~ /\S/); + } + return(@r); +} +# using the host part of an address, and the server name, add the +# servers' domain to the address if it doesn't already have a +# domain. Since this sometimes fails, save a back reference so +# it can be unrolled. +sub domainify +{ + local($host,$domain_host,$u) = @_; + local($domain,$newhost); + + # cut of trailing dots + $host =~ s/\.$//; + $domain_host =~ s/\.$//; + + if ($domain_host !~ /\./) { + # + # domain host isn't, keep $host whatever it is + # + print "domainify($host,$domain_host) = $host\n" if $debug; + return $host; + } + + # + # There are several weird situtations that need to be + # accounted for. They have to do with domain relay hosts. + # + # Examples: + # host server "right answer" + # + # shiva.cs cs.berkeley.edu shiva.cs.berkeley.edu + # shiva cs.berkeley.edu shiva.cs.berekley.edu + # cumulus reed.edu @reed.edu:cumulus.uucp + # tiberius tc.cornell.edu tiberius.tc.cornell.edu + # + # The first try must always be to cut the domain part out of + # the server and tack it onto the host. + # + # A reasonable second try is to tack the whole server part onto + # the host and for each possible repeated element, eliminate + # just that part. + # + # These extra "guesses" get put into the %domainify_fallback + # array. They will be used to give addresses a second chance + # in the &giveup routine + # + + local(%fallback); + + local($long); + $long = "$host $domain_host"; + $long =~ tr/A-Z/a-z/; + print "long = $long\n" if $debug; + if ($long =~ s/^([^ ]+\.)([^ ]+) \2(\.[^ ]+\.[^ ]+)/$1$2$3/) { + # matches shiva.cs cs.berkeley.edu and returns shiva.cs.berkeley.edu + print "condensed fallback $host $domain_host -> $long\n" if $debug; + $fallback{$long} = 9; + } + + local($fh); + $fh = $domain_host; + while ($fh =~ /\./) { + print "FALLBACK $host.$fh = 1\n" if $debug > 7; + $fallback{"$host.$fh"} = 1; + $fh =~ s/^[^\.]+\.//; + } + + $fallback{"$host.$domain_host"} = 2; + + ($domain = $domain_host) =~ s/^[^\.]+//; + $fallback{"$host$domain"} = 6 + if ($domain =~ /\./); + + if ($host =~ /\./) { + # + # Host is already okay, but let's look for multiple + # interpretations + # + print "domainify($host,$domain_host) = $host\n" if $debug; + delete $fallback{$host}; + $domainify_fallback{"$u *** $host"} = join(' ',sort {$fallback{$b} <=> $fallback{$a};} keys %fallback) if %fallback; + return $host; + } + + $domain = ".$domain_host" + if ($domain !~ /\..*\./); + $newhost = "$host$domain"; + + $create_host_backtrack{"$u *** $newhost"} = $domain_host; + print "domainify($host,$domain_host) = $newhost\n" if $debug; + delete $fallback{$newhost}; + $domainify_fallback{"$u *** $newhost"} = join(' ',sort {$fallback{$b} <=> $fallback{$a};} keys %fallback) if %fallback; + if ($debug) { + print "fallback = "; + print $domainify_fallback{"$u *** $newhost"} + if defined($domainify_fallback{"$u *** $newhost"}); + print "\n"; + } + return $newhost; +} +# return the first non-empty element of an array +sub firstname +{ + local(@names) = @_; + local($n); + while(@names) { + $n = shift(@names); + return $n if $n =~ /\S/; + } + return undef; +} +# queue up more addresses to expand +sub expn +{ + local($host,$addr,$name,$level) = @_; + if ($host) { + $host = &trhost($host); + + if (($debug > 3) || (defined $giveup{$host})) { + unshift(@hosts,$host) unless $users{$host}; + } else { + push(@hosts,$host) unless $users{$host}; + } + $users{$host} .= " $addr"; + $names{"$addr *** $host"} = $name; + $level{"$addr *** $host"} = $level + 1; + print "expn($host,$addr,$name)\n" if $debug; + return "\t$addr\n"; + } else { + return &final($addr,'NONE',$name); + } +} +# compute the numerical average value of an array +sub average +{ + local(@e) = @_; + return 0 unless @e; + local($e,$sum); + for $e (@e) { + $sum += $e; + } + $sum / @e; +} +# print to the server (also to stdout, if -w) +sub ps +{ + local($p) = @_; + print ">>> $p\n" if $watch; + print S "$p\n"; +} +# return case-adjusted name for a host (for comparison purposes) +sub trhost +{ + # treat foo.bar as an alias for Foo.BAR + local($host) = @_; + local($trhost) = $host; + $trhost =~ tr/A-Z/a-z/; + if ($trhost{$trhost}) { + $host = $trhost{$trhost}; + } else { + $trhost{$trhost} = $host; + } + $trhost{$trhost}; +} +# re-queue users if an mx record dictates a redirect +# don't allow a user to be redirected more than once +sub mxredirect +{ + local($server,*users) = @_; + local($u,$nserver,@still_there); + + $nserver = &mx($server); + + if (&trhost($nserver) ne &trhost($server)) { + $0 = "$av0 - mx redirect $server -> $nserver\n"; + for $u (@users) { + if (defined $mxbacktrace{"$u *** $nserver"}) { + push(@still_there,$u); + } else { + $mxbacktrace{"$u *** $nserver"} = $server; + print "mxbacktrace{$u *** $nserver} = $server\n" + if ($debug > 1); + &expn($nserver,$u,$names{"$u *** $server"}); + } + } + @users = @still_there; + if (! @users) { + return $nserver; + } else { + return undef; + } + } + return undef; +} +# follow mx records, return a hostname +# also follow temporary redirections comming from &domainify and +# &mxlookup +sub mx +{ + local($h,$u) = @_; + + for (;;) { + if (defined $mx{&trhost($h)} && $h ne $mx{&trhost($h)}) { + $0 = "$av0 - mx expand $h"; + $h = $mx{&trhost($h)}; + return $h; + } + if ($u) { + if (defined $temporary_redirect{"$u *** $h"}) { + $0 = "$av0 - internal redirect $h"; + print "Temporary redirect taken $u *** $h -> " if $debug; + $h = $temporary_redirect{"$u *** $h"}; + print "$h\n" if $debug; + next; + } + $htr = &trhost($h); + if (defined $temporary_redirect{"$u *** $htr"}) { + $0 = "$av0 - internal redirect $h"; + print "temporary redirect taken $u *** $h -> " if $debug; + $h = $temporary_redirect{"$u *** $htr"}; + print "$h\n" if $debug; + next; + } + } + return $h; + } +} +# look up mx records with the name server. +# re-queue expansion requests if possible +# optionally give up on this host. +sub mxlookup +{ + local($lastchance,$server,$giveup,*users) = @_; + local(*T); + local(*NSLOOKUP); + local($nh, $pref,$cpref); + local($o0) = $0; + local($nserver); + local($name,$aliases,$type,$len,$thataddr); + local(%fallback); + + return 1 if &mxredirect($server,*users); + + if ((defined $mx{$server}) || (! $have_nslookup)) { + return 0 unless $lastchance; + &giveup('mx domainify',$giveup); + return 0; + } + + $0 = "$av0 - nslookup of $server"; + open(T,">/tmp/expn$$") || die "open > /tmp/expn$$: $!\n"; + print T "set querytype=MX\n"; + print T "$server\n"; + close(T); + $cpref = 1.0E12; + undef $nserver; + open(NSLOOKUP,"nslookup < /tmp/expn$$ 2>&1 |") || die "open nslookup: $!"; + while(<NSLOOKUP>) { + print if ($debug > 2); + if (/mail exchanger = ([-A-Za-z_.0-9+]+)/) { + $nh = $1; + if (/preference = (\d+)/) { + $pref = $1; + if ($pref < $cpref) { + $nserver = $nh; + $cpref = $pref; + } elsif ($pref) { + $fallback{$pref} .= " $nh"; + } + } + } + if (/Non-existent domain/) { + # + # These addresss are hosed. Kaput! Dead! + # However, if we created the address in the + # first place then there is a chance of + # salvation. + # + 1 while(<NSLOOKUP>); + close(NSLOOKUP); + return 0 unless $lastchance; + &giveup('domainify',"$server: Non-existent domain",undef,1); + return 0; + } + + } + close(NSLOOKUP); + unlink("/tmp/expn$$"); + unless ($nserver) { + $0 = "$o0 - finished mxlookup"; + return 0 unless $lastchance; + &giveup('mx domainify',"$server: Could not resolve address"); + return 0; + } + + # provide fallbacks in case $nserver doesn't work out + if (defined $fallback{$cpref}) { + $mx_secondary{$server} = $fallback{$cpref}; + } + + $0 = "$av0 - gethostbyname($nserver)"; + ($name,$aliases,$type,$len,$thataddr) = gethostbyname($nserver); + + unless ($thataddr) { + $0 = $o0; + return 0 unless $lastchance; + &giveup('mx domainify',"$nserver: could not resolve address"); + return 0; + } + print "MX($server) = $nserver\n" if $debug; + print "$server -> $nserver\n" if $vw && !$debug; + $mx{&trhost($server)} = $nserver; + # redeploy the users + unless (&mxredirect($server,*users)) { + return 0 unless $lastchance; + &giveup('mx domainify',"$nserver: only one level of mx redirect allowed"); + return 0; + } + $0 = "$o0 - finished mxlookup"; + return 1; +} +# if mx expansion did not help to resolve an address +# (ie: foo@bar became @baz:foo@bar, then undo the +# expansion). +# this is only used by &final +sub mxunroll +{ + local(*host,*addr) = @_; + local($r) = 0; + print "looking for mxbacktrace{$addr *** $host}\n" + if ($debug > 1); + while (defined $mxbacktrace{"$addr *** $host"}) { + print "Unrolling MX expnasion: \@$host:$addr -> " + if ($debug || $verbose); + $host = $mxbacktrace{"$addr *** $host"}; + print "\@$host:$addr\n" + if ($debug || $verbose); + $r = 1; + } + return 1 if $r; + $addr = "\@$host:$addr" + if ($host =~ /\./); + return 0; +} +# register a completed expnasion. Make the final address as +# simple as possible. +sub final +{ + local($addr,$host,$name,$error) = @_; + local($he); + local($hb,$hr); + local($au,$ah); + + if ($error =~ /Non-existent domain/) { + # + # If we created the domain, then let's undo the + # damage... + # + if (defined $create_host_backtrack{"$addr *** $host"}) { + while (defined $create_host_backtrack{"$addr *** $host"}) { + print "Un&domainifying($host) = " if $debug; + $host = $create_host_backtrack{"$addr *** $host"}; + print "$host\n" if $debug; + } + $error = "$host: could not locate"; + } else { + # + # If we only want valid addresses, toss out + # bad host names. + # + if ($valid) { + print STDERR "\@$host:$addr ($name) Non-existent domain\n"; + return ""; + } + } + } + + MXUNWIND: { + $0 = "$av0 - final parsing of \@$host:$addr"; + ($he = $host) =~ s/(\W)/\\$1/g; + if ($addr !~ /@/) { + # addr does not contain any host + $addr = "$addr@$host"; + } elsif ($addr !~ /$he/i) { + # if host part really something else, use the something + # else. + if ($addr =~ m/(.*)\@([^\@]+)$/) { + ($au,$ah) = ($1,$2); + print "au = $au ah = $ah\n" if $debug; + if (defined $temporary_redirect{"$addr *** $ah"}) { + $addr = "$au\@".$temporary_redirect{"$addr *** $ah"}; + print "Rewrite! to $addr\n" if $debug; + next MXUNWIND; + } + } + # addr does not contain full host + if ($valid) { + if ($host =~ /^([^\.]+)(\..+)$/) { + # host part has a . in it - foo.bar + ($hb, $hr) = ($1, $2); + if ($addr =~ /\@([^\.\@]+)$/ && ($1 eq $hb)) { + # addr part has not . + # and matches beginning of + # host part -- tack on a + # domain name. + $addr .= $hr; + } else { + &mxunroll(*host,*addr) + && redo MXUNWIND; + } + } else { + &mxunroll(*host,*addr) + && redo MXUNWIND; + } + } else { + $addr = "${addr}[\@$host]" + if ($host =~ /\./); + } + } + } + $name = "$name " if $name; + $error = " $error" if $error; + if ($valid) { + push(@final,"$name<$addr>"); + } else { + push(@final,"$name<$addr>$error"); + } + "\t$name<$addr>$error\n"; +} + +sub alarm +{ + local($alarm_action,$alarm_redirect,$alarm_user) = @_; + alarm(3600); + $SIG{ALRM} = 'handle_alarm'; +} +# this involves one great big ugly hack. +# the "next HOST" unwinds the stack! +sub handle_alarm +{ + &giveup($alarm_redirect,"Timed out during $alarm_action",$alarm_user); + next HOST; +} + +# read the rest of the current smtp daemon's response (and toss it away) +sub read_response +{ + local($done,$watch) = @_; + local(@resp); + print $s if $watch; + while(($done eq "-") && ($s = <S>) && ($s =~ /^\d+([- ])/)) { + print $s if $watch; + $done = $1; + push(@resp,$s); + } + return @resp; +} +# print args if verbose. Return them in any case +sub verbose +{ + local(@tp) = @_; + print "@tp" if $verbose; +} +# to pass perl -w: +@tp; +$flag_a; +$flag_d; +$flag_1; +%already_domainify_fellback; +%already_mx_fellback; +&handle_alarm; +################### BEGIN PERL/TROFF TRANSITION +.00 ; + +'di +.nr nl 0-1 +.nr % 0 +.\\"'; __END__ +.\" ############## END PERL/TROFF TRANSITION +.TH EXPN 1 "March 11, 1993" +.AT 3 +.SH NAME +expn \- recursively expand mail aliases +.SH SYNOPSIS +.B expn +.RI [ -a ] +.RI [ -v ] +.RI [ -w ] +.RI [ -d ] +.RI [ -1 ] +.IR user [@ hostname ] +.RI [ user [@ hostname ]]... +.SH DESCRIPTION +.B expn +will use the SMTP +.B expn +and +.B vrfy +commands to expand mail aliases. +It will first look up the addresses you provide on the command line. +If those expand into addresses on other systems, it will +connect to the other systems and expand again. It will keep +doing this until no further expansion is possible. +.SH OPTIONS +The default output of +.B expn +can contain many lines which are not valid +email addresses. With the +.I -aa +flag, only expansions that result in legal addresses +are used. Since many mailing lists have an illegal +address or two, the single +.IR -a , +address, flag specifies that a few illegal addresses can +be mixed into the results. More +.I -a +flags vary the ratio. Read the source to track down +the formula. With the +.I -a +option, you should be able to construct a new mailing +list out of an existing one. +.LP +If you wish to limit the number of levels deep that +.B expn +will recurse as it traces addresses, use the +.I -1 +option. For each +.I -1 +another level will be traversed. So, +.I -111 +will traverse no more than three levels deep. +.LP +The normal mode of operation for +.B expn +is to do all of its work silently. +The following options make it more verbose. +It is not necessary to make it verbose to see what it is +doing because as it works, it changes its +.BR argv [0] +variable to reflect its current activity. +To see how it is expanding things, the +.IR -v , +verbose, flag will cause +.B expn +to show each address before +and after translation as it works. +The +.IR -w , +watch, flag will cause +.B expn +to show you its conversations with the mail daemons. +Finally, the +.IR -d , +debug, flag will expose many of the inner workings so that +it is possible to eliminate bugs. +.SH ENVIRONMENT +No enviroment variables are used. +.SH FILES +.PD 0 +.B /tmp/expn$$ +.B temporary file used as input to +.BR nslookup . +.SH SEE ALSO +.BR aliases (5), +.BR sendmail (8), +.BR nslookup (8), +RFC 823, and RFC 1123. +.SH BUGS +Not all mail daemons will implement +.B expn +or +.BR vrfy . +It is not possible to verify addresses that are served +by such daemons. +.LP +When attempting to connect to a system to verify an address, +.B expn +only tries one IP address. Most mail daemons +will try harder. +.LP +It is assumed that you are running domain names and that +the +.BR nslookup (8) +program is available. If not, +.B expn +will not be able to verify many addresses. It will also pause +for a long time unless you change the code where it says +.I $have_nslookup = 1 +to read +.I $have_nslookup = +.IR 0 . +.LP +Lastly, +.B expn +does not handle every valid address. If you have an example, +please submit a bug report. +.SH CREDITS +In 1986 or so, Jon Broome wrote a program of the same name +that did about the same thing. It has since suffered bit rot +and Jon Broome has dropped off the face of the earth! +(Jon, if you are out there, drop me a line) +.SH AVAILABILITY +The latest version of +.B expn +is available through anonymous ftp at +.IR ftp://ftp.idiom.com/pub/muir-programs/expn . +.SH AUTHOR +.I David Muir Sharnoff\ \ \ \ <muir@idiom.com> diff --git a/usr.sbin/sendmail/contrib/mailprio b/usr.sbin/sendmail/contrib/mailprio new file mode 100644 index 000000000000..cdbc3b06c264 --- /dev/null +++ b/usr.sbin/sendmail/contrib/mailprio @@ -0,0 +1,297 @@ +Message-Id: <199412081919.NAA23234@austin.BSDI.COM> +To: Eric Allman <eric@cs.berkeley.edu> +Subject: Re: sorting mailings lists with fastest delivery users first +In-reply-to: Your message of Thu, 08 Dec 1994 06:08:33 PST. +References: <199412081408.GAA06210@mastodon.CS.Berkeley.EDU> +From: Tony Sanders <sanders@bsdi.com> +Organization: Berkeley Software Design, Inc. +Date: Thu, 08 Dec 1994 13:19:39 -0600 +Sender: sanders@austin.BSDI.COM + +Eric Allman writes: +> Nope, that's a new one, so far as I know. Any interest in +> contributing it? For small lists it seems overkill, but for +> large lists it could be a major win. + +Sure, I will contribute it; after I sent you mail last night I went ahead +and finished up what I thought needed to be done. I would like to get +some feedback from you on a few items, if you have time. + +There are two programs, mailprio_mkdb and mailprio (source below). + +mailprio_mkdb reads maillog files and creates a DB file of address vs. +delay. I'm not too happy with how it does the averages right now but this +is just a quick hack. However, it should at least order sites that take +days vs. those that deliver on the first pass through. One thing that +would make this information a lot more accurate is if sendmail could log +a "transaction delay" (on failures also), as well as total delivery delay. +Perhaps, as an option, it could maintain the DB file itself? + +mailprio then simply reads a list of addresses from stdin (the mailing +list), and tries to prioritize them according to the info the database. +It collects comment lines and other junk at the top of the file; all +mailprio does is reorder lines, the actual text of the file should +be unchanged to the extent that you can verify it with: + sort sorted_list > checkit; sort mailing-list | diff - checkit +Users with no delay information are put next. The prioritized list is last. +Of course, this function could also be built-into sendmail (eventually). + +Putting "new account" info at the top with the current averaging function +probably adversly affects the prioritized list (at least in the short +term), but putting it at the bottom would not really give the new accounts +a fair chance. I suspect this isn't that big of a problem. I'm running +this here on a list with 461 accounts and about 10 messages per day so +I'll see how it goes. I'll keep some stats on delay times and see what +happens. + +Another thing that would help this situation, is if sendmail had the queue +ordered by site (but you already know this). If you ever get to do per +site queuing you should consider "blocking" a queue for some short period +of time if a connection fails to that site [sendmail does this inside a +single process on a per account basis now right?]; this would allow multiple +sendmails to quickly skip over those sites for people like me that run: + + for i in 1 2 3 4 5 6 7 8 ; do daemon sendmail -q; done + +to flush a queue that has gotten behind. You could also do this inside +sendmail with a parallelism option (when it is time to run the queue, how +many processes to start). + +#! /bin/sh +# This is a shell archive. Remove anything before this line, then unpack +# it by saving it into a file and typing "sh file". To overwrite existing +# files, type "sh file -c". You can also feed this as standard input via +# unshar, or by typing "sh <file", e.g.. If this archive is complete, you +# will see the following message at the end: +# "End of shell archive." +# Contents: mailprio mailprio_mkdb +# Wrapped by sanders@austin.BSDI.COM on Fri Dec 9 18:07:02 1994 +PATH=/bin:/usr/bin:/usr/ucb ; export PATH +if test -f 'mailprio' -a "${1}" != "-c" ; then + echo shar: Will not clobber existing file \"'mailprio'\" +else +echo shar: Extracting \"'mailprio'\" \(3093 characters\) +sed "s/^X//" >'mailprio' <<'END_OF_FILE' +X#!/usr/bin/perl +X# +X# mailprio -- setup mail priorities for a mailing list +X# +X# Sort mailing list by mailprio database: +X# mailprio < mailing-list > sorted_list +X# Double check against orig: +X# sort sorted_list > checkit; sort mailing-list | diff - checkit +X# If it checks out, install it. +X# +X# TODO: +X# option to process mqueue files so we can reorder files in the queue! +X$usage = "Usage: mailprio [-p priodb]\n"; +X$home = "/home/sanders/lists"; +X$priodb = "$home/mailprio"; +X +Xif ($main'ARGV[0] =~ /^-/) { +X $args = shift; +X if ($args =~ m/\?/) { print $usage; exit 0; } +X if ($args =~ m/p/) { +X $priodb = shift || die $usage, "-p requires argument\n"; } +X} +X +X# In shell script, it goes something like this: +X# old_mailprio > /tmp/a +X# fgrep -f lists/inet-access /tmp/a | sed -e 's/^.......//' > /tmp/b +X# ; /tmp/b contains list of known users, faster delivery first +X# fgrep -v -f /tmp/b lists/inet-access > /tmp/c +X# ; put all unknown stuff at the top of new list for now +X# echo '# -----' >> /tmp/c +X# cat /tmp/b >> /tmp/c +X +X# Setup %list and @list +Xlocal($addr, $canon); +Xwhile ($addr = <STDIN>) { +X chop $addr; +X next if $addr =~ /^# ----- /; # that's our line +X push(@list, $addr), next if $addr =~ /^\s*#/; # save comments +X $canon = &canonicalize((&simplify_address($addr))[0]); +X unless (defined $canon) { +X warn "no address found: $addr\n"; +X push(@list, $addr); # save it anyway +X next; +X } +X if (defined $list{$canon}) { +X warn "duplicate: ``$addr -> $canon''\n"; +X push(@list, $addr); # save it anyway +X next; +X } +X $list{$canon} = $addr; +X} +X +Xlocal(*prio); +Xdbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n"; +Xforeach $to (keys %list) { +X if (defined $prio{$to}) { +X # add to list of found users (%userprio) and remove from %list +X # so that we know what users were not yet prioritized +X $userprio{$to} = $prio{$to}; # priority +X $useracct{$to} = $list{$to}; # string +X delete $list{$to}; +X } +X} +Xdbmclose(%prio); +X +X# Put all the junk we found at the very top +X# (this might not always be a feature) +Xprint join("\n", @list), "\n"; +X +X# unprioritized users go next, slow accounts will get moved down quickly +Xprint '# ----- unprioritized users', "\n"; +Xforeach $to (keys %list) { print $list{$to}, "\n"; } +X +X# finally, our prioritized list of users +Xprint '# ----- prioritized users', "\n"; +Xforeach $to (sort { $userprio{$a} <=> $userprio{$b}; } keys %userprio) { +X die "Opps! Something is seriously wrong with useracct: $to\n" +X unless defined $useracct{$to}; +X print $useracct{$to}, "\n"; +X} +X +Xexit(0); +X +X# REPL-LIB --------------------------------------------------------------- +X +Xsub canonicalize { +X local($addr) = @_; +X # lowercase, strip leading/trailing whitespace +X $addr =~ y/A-Z/a-z/; $addr =~ s/^\s+//; $addr =~ s/\s+$//; $addr; +X} +X +X# @addrs = simplify_address($addr); +Xsub simplify_address { +X local($_) = shift; +X 1 while s/\([^\(\)]*\)//g; # strip comments +X 1 while s/"[^"]*"//g; # strip comments +X split(/,/); # split into parts +X foreach (@_) { +X 1 while s/.*<(.*)>.*/\1/; +X s/^\s+//; +X s/\s+$//; +X } +X @_; +X} +END_OF_FILE +if test 3093 -ne `wc -c <'mailprio'`; then + echo shar: \"'mailprio'\" unpacked with wrong size! +fi +chmod +x 'mailprio' +# end of 'mailprio' +fi +if test -f 'mailprio_mkdb' -a "${1}" != "-c" ; then + echo shar: Will not clobber existing file \"'mailprio_mkdb'\" +else +echo shar: Extracting \"'mailprio_mkdb'\" \(3504 characters\) +sed "s/^X//" >'mailprio_mkdb' <<'END_OF_FILE' +X#!/usr/bin/perl +X# +X# mailprio_mkdb -- make mail priority database based on delay times +X# +X$usage = "Usage: mailprio_mkdb [-l maillog] [-p priodb]\n"; +X$home = "/home/sanders/lists"; +X$maillog = "/var/log/maillog"; +X$priodb = "$home/mailprio"; +X +Xif ($main'ARGV[0] =~ /^-/) { +X $args = shift; +X if ($args =~ m/\?/) { print $usage; exit 0; } +X if ($args =~ m/l/) { +X $maillog = shift || die $usage, "-l requires argument\n"; } +X if ($args =~ m/p/) { +X $priodb = shift || die $usage, "-p requires argument\n"; } +X} +X +Xlocal(*prio); +X# We'll merge with existing information if it's already there. +Xdbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n"; +X&getlog_stats($maillog, *prio); +X# foreach $addr (sort { $prio{$a} <=> $prio{$b}; } keys %prio) { +X# printf("%06d %s\n", $prio{$addr}, $addr); } +Xdbmclose(%prio); +Xexit(0); +X +Xsub getlog_stats { +X local($maillog, *stats) = @_; +X local($to, $delay); +X local($h, $m, $s); +X open(MAILLOG, "< $maillog") || die "$maillog: $!\n"; +X while (<MAILLOG>) { +X ($delay) = (m/, delay=([^,]*), /); +X $delay || next; +X ($h, $m, $s) = split(/:/, $delay); +X $delay = ($h * 60 * 60) + ($m * 60) + $s; +X +X # deleting everything after ", " seems safe enough, though +X # it is possible that it was inside "..."'s and that we will +X # miss some addresses because of it. However, I'm not willing +X # to do full parsing just for that case. If this bothers you +X # you could do something like: s/, (delay|ctladdr)=.*//; +X # but you have to make sure you catch all the possible names. +X $to = $_; $to =~ s/^.* to=//; $to =~ s/, .*//; +X foreach $addr (&simplify_address($to)) { +X next unless $addr; +X $addr = &canonicalize($addr); +X # print $delay, " ", $addr, "\n"; +X $stats{$addr} = $delay unless defined $stats{$addr}; # init +X +X # This average function moves the value around quite rapidly +X # which may or may not be a feature. +X # +X # This has at least one odd behavior because we currently only +X # use the delay information from maillog which is only logged +X # on actual delivery. This works backwards from what we really +X # want to happen when a fast host goes down for a while and then +X # comes back up. +X # +X # I spoke with Eric and he suggested adding an xdelay statistic +X # for a per transaction delay which would help that situation +X # a lot. What I believe you want in that cases something like: +X # delay fast, xdelay fast: smokin', these hosts go first +X # delay slow, xdelay fast: put host high on the list (back up?) +X # delay fast, xdelay slow: host is down/having problems/slow +X # delay slow, xdelay slow: poorly connected sites, very last +X # Of course, you have to reorder the distribution list fairly +X # often for that to help. Come to think of it, you should +X # also reorder /var/spool/mqueue files also (if they aren't +X # locked of course). Hmmm.... +X $stats{$addr} = int(($stats{$addr} + $delay) / 2); +X } +X } +X close(MAILLOG); +X} +X +X# REPL-LIB --------------------------------------------------------------- +X +Xsub canonicalize { +X local($addr) = @_; +X # lowercase, strip leading/trailing whitespace +X $addr =~ y/A-Z/a-z/; $addr =~ s/^\s+//; $addr =~ s/\s+$//; $addr; +X} +X +X# @addrs = simplify_address($addr); +Xsub simplify_address { +X local($_) = shift; +X 1 while s/\([^\(\)]*\)//g; # strip comments +X 1 while s/"[^"]*"//g; # strip comments +X split(/,/); # split into parts +X foreach (@_) { +X 1 while s/.*<(.*)>.*/\1/; +X s/^\s+//; +X s/\s+$//; +X } +X @_; +X} +END_OF_FILE +if test 3504 -ne `wc -c <'mailprio_mkdb'`; then + echo shar: \"'mailprio_mkdb'\" unpacked with wrong size! +fi +chmod +x 'mailprio_mkdb' +# end of 'mailprio_mkdb' +fi +echo shar: End of shell archive. +exit 0 diff --git a/usr.sbin/sendmail/contrib/rmail.oldsys.patch b/usr.sbin/sendmail/contrib/rmail.oldsys.patch new file mode 100644 index 000000000000..856fcf1f93eb --- /dev/null +++ b/usr.sbin/sendmail/contrib/rmail.oldsys.patch @@ -0,0 +1,108 @@ +From: Bill Gianopoulos <wag@sccux1.msd.ray.com> +Message-Id: <199405191527.LAA03463@sccux1.msd.ray.com> +Subject: Patch to rmail to elliminate need for snprintf +To: sendmail@CS.Berkeley.EDU +Date: Thu, 19 May 1994 11:27:16 -0400 (EDT) + +I have written the following patch to rmail which removes the requirement +for snprintf while maintaining the protection from buffer overruns. It also +fixes it to compile with compilers which don't understand ANSI function +prototypes. Perhaps this should be included in the next version? + +*** rmail/rmail.c.orig Mon May 31 18:10:44 1993 +--- rmail/rmail.c Thu May 19 11:04:50 1994 +*************** +*** 78,86 **** +--- 78,109 ---- + #include <sysexits.h> + #include <unistd.h> + ++ #ifdef __STDC__ + void err __P((int, const char *, ...)); + void usage __P((void)); ++ #else ++ void err (); ++ void usage (); ++ #endif + ++ #define strdup(s) strcpy(xalloc(strlen(s) + 1), s) ++ ++ char * ++ xalloc(sz) ++ register int sz; ++ { ++ register char *p; ++ ++ /* some systems can't handle size zero mallocs */ ++ if (sz <= 0) ++ sz = 1; ++ ++ p = malloc((unsigned) sz); ++ if (p == NULL) ++ err(EX_UNAVAILABLE, "Out of memory!!"); ++ return (p); ++ } ++ + int + main(argc, argv) + int argc; +*************** +*** 230,250 **** + args[i++] = "-oi"; /* Ignore '.' on a line by itself. */ + + if (from_sys != NULL) { /* Set sender's host name. */ +! if (strchr(from_sys, '.') == NULL) +! (void)snprintf(buf, sizeof(buf), + "-oMs%s.%s", from_sys, domain); +! else +! (void)snprintf(buf, sizeof(buf), "-oMs%s", from_sys); + if ((args[i++] = strdup(buf)) == NULL) + err(EX_TEMPFAIL, NULL); + } + /* Set protocol used. */ +! (void)snprintf(buf, sizeof(buf), "-oMr%s", domain); + if ((args[i++] = strdup(buf)) == NULL) + err(EX_TEMPFAIL, NULL); + + /* Set name of ``from'' person. */ +! (void)snprintf(buf, sizeof(buf), "-f%s%s", + from_path ? from_path : "", from_user); + if ((args[i++] = strdup(buf)) == NULL) + err(EX_TEMPFAIL, NULL); +--- 253,285 ---- + args[i++] = "-oi"; /* Ignore '.' on a line by itself. */ + + if (from_sys != NULL) { /* Set sender's host name. */ +! if (strchr(from_sys, '.') == NULL) { +! if ((strlen(from_sys) + strlen(domain) + 6) +! > sizeof(buf)) +! err(EX_DATAERR, "sender hostname too long"); +! (void)sprintf(buf, + "-oMs%s.%s", from_sys, domain); +! } +! else { +! if ((strlen(from_sys) + 5) > sizeof(buf)) +! err(EX_DATAERR ,"sender hostname too long"); +! (void)sprintf(buf, "-oMs%s", from_sys); +! } + if ((args[i++] = strdup(buf)) == NULL) + err(EX_TEMPFAIL, NULL); + } + /* Set protocol used. */ +! if ((strlen(domain) + 5) > sizeof(buf)) +! err(EX_DATAERR, "protocol name too long"); +! (void)sprintf(buf, "-oMr%s", domain); + if ((args[i++] = strdup(buf)) == NULL) + err(EX_TEMPFAIL, NULL); + + /* Set name of ``from'' person. */ +! if (((from_path ? strlen(from_path) : 0) + strlen(from_user) + 3) +! > sizeof(buf)) +! err(EX_DATAERR, "from address too long"); +! (void)sprintf(buf, "-f%s%s", + from_path ? from_path : "", from_user); + if ((args[i++] = strdup(buf)) == NULL) + err(EX_TEMPFAIL, NULL); +-- +William A. Gianopoulos; Raytheon Missile Systems Division +wag@sccux1.msd.ray.com diff --git a/usr.sbin/sendmail/doc/changes/changes.me b/usr.sbin/sendmail/doc/changes/changes.me new file mode 100644 index 000000000000..ee838bd40d78 --- /dev/null +++ b/usr.sbin/sendmail/doc/changes/changes.me @@ -0,0 +1,997 @@ +.\" Copyright (c) 1994 Eric P. Allman +.\" Copyright (c) 1988, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)changes.me 8.2 (Berkeley) 5/3/95 +.\" +.\" ditroff -me -Pxx changes.me +.eh '%''Changes in Sendmail Version 8' +.oh 'Changes in Sendmail Version 8''%' +.nr si 3n +.if n .ls 2 +.+c +.(l C +.sz 14 +Changes in Sendmail Version 8* +.sz +.sp +Eric Allman +.sp 0.5 +.i +University of California, Berkeley +Mammoth Project +.)l +.(f +*An earlier version of this paper was printed in the +Proceedings of the 1994 AUUG Queensland Summer Technical Conference, +Gateway Hotel, Brisbane, March 1994. +.)f +.sp +.(l F +.ce +ABSTRACT +.sp \n(psu +Version 8 of +.i sendmail +includes a number of major changes from previous versions. +This paper gives a very short history of +.i sendmail , +a summary of the major differences between version 5 +(the last publically available version) +and version 8, +and some discussion of future directions. +.)l +.sp 2 +.pp +In 1987, the author stopped major work on +.i sendmail +due to other time committments, +only to return to active work in 1991. +This paper explores why work resumed +and what changes have been made. +.pp +Section 1 gives a short history of +.i sendmail +through version 5 and the motivation behind working on version 8. +Section 2 has +a rather detailed description of what has changed +between version 5 and version 8. +The paper finishes off with some thoughts +about what still needs to be done. +.sh 1 "HISTORY" +.pp +As discussed elsewhere, +[Allman83a, Allman83b, Allman&Amos85] +sendmail has existed in various forms since 1980. +It was released under the name +.i delivermail +in 4BSD and 4.1BSD, and as +.i sendmail +in 4.2BSD. +.\"4.0BSD delivermail 1.10 +.\"4.1BSD delivermail 1.10 +.\"4.2BSD sendmail 4.12 +.\"4.3BSD sendmail 5.52 +It quickly became the dominant mail system for networked UNIX systems. +.pp +Prior the release of 4.3BSD in November 1986, +the author had left the University for private industry, +but continued to do some work on +.i sendmail +with activity slowly trailing off +until effectively stopping after February 1987. +There was minimal support done by many people for several years, +until July of 1991 when the original author, +who had returned the University, +started active work on it again. +.pp +There were several reasons for renewed work on +.i sendmail . +There was a desire at Berkeley to convert to a subdomained structure +so that individuals were identified by their subdomain +rather than by their individual workstation; +although possible in the old code, there were some problems, +and the author was the obvious person to address them. +The Computer Systems Research Group (CSRG), +the group that produced the Berkeley Software Distributions, +was working on 4.4BSD, +and wanted an update to the mail system. +Bryan Costales was working on a book on +.i sendmail +that was being reviewed by the author, +which encouraged him to make some revisions. +And the author wanted to try to unify some of the disparate versions of +.i sendmail +that had been permitted to proliferate. +.pp +During the 1987\-91 fallow period, +many vendors and outside volunteers +had produced variants of +.i sendmail . +Perhaps the best known is the IDA version +[IDA87]. +Originally intended to be a new set of configuration files, +IDA expanded into a fairly large set of patches for the code. +Originally produced in Sweden, +IDA development passed to the University of Illinois, +and was widely used by the fairly large set of people +who prefer to get and compile their own source code +rather than use vendor-supplied binaries. +.pp +In about the same time frame, +attempts were made to clean up and extend the Simple Mail Transport Protocol +(SMTP) +[RFC821]. +This involved clarifications of some ambiguities in the protocol, +and correction of some problem areas +[RFC1123], +as well as extensions for additional functionality +(dubbed Extended Simple Mail Transport Protocol, or ESMTP) +[RFC1425, RFC1426, RFC1427] +and a richer set of semantics in the body of messages +(the Multipurpose Internet Mail Extensions, a.k.a. MIME) +[RFC1521, RFC1344]. +Neither the IDA group nor most vendors +were modifying +.i sendmail +to conform to these new standards. +It seemed clear that these were ``good things'' +that should be encouraged. +However, since no one was working on a publically available version of +.i sendmail +with these updates, +they were unlikely to be widely deployed any time in the near future. +.pp +There are, of course, other mail transport agents available, +such as +.i MMDF +.\"[ref], +.i zmailer +.\"[ref], +.i smail +.\"[ref], +and +.i PP +.\"[ref]. +However, none of these seemed to be gaining the prominence of +.i sendmail ; +it appeared that most companies would not convert to another +mail transport agent any time in the forseeable future. +However, they might be persuaded to convert to a newer version of +.i sendmail . +.pp +All of these convinced the author +to work on a updated version of +.i sendmail +for public distribution. +.pp +The new version of +.i sendmail +is referred to as version eight (V8). +Versions six and seven were skipped +because of an agreement +that all files in 4.4BSD would be numbered as +.q 8.1 . +Rather than have an external version number +that differed from the file version numbers, +.i sendmail +just jumped directly to V8. +.sh 1 "CHANGES IN VERSION EIGHT" +.pp +The following is a summary of the changes between the last commonly +available version of sendmail from Berkeley (5.67) and the latest +version (8.6.6). +.pp +Many of these are ideas that had been tried in IDA, +but many of them were generalized in V8. +.sh 2 "Performance Enhancements" +.pp +Instead of closing SMTP connections immediately, open connections are +cached for possible future use. There is a limit to the number of +simultaneous open connections and the idle time of any individual +connection. +.pp +This is of best help during queue processing (since there is the +potential of many different messages going to one site), although +it can also help when processing MX records which aren't handled +by MX Piggybacking. +.pp +If two hosts with different names in a single message happen to +have the same set of MX hosts, they can be sent in the same +transaction. Version 8 notices this and tries to batch the messages. +.pp +For example, if two sites ``foo.com'' and ``bar.com'' are both +served by UUNET, they will have the same set of MX hosts and will +be sent in one transaction. UUNET will then split the message +and send it to the two individual hosts. +.sh 2 "RFC 1123 Changes" +.pp +A number of changes have been made to make sendmail ``conditionally +compliant'' (that is, it satisfies all of the MUST clauses and most +but not all of the SHOULD clauses in RFC 1123). +.pp +The major areas of change are (numbers are RFC 1123 section numbers): +.nr ii 0.75i +.ip \(sc5.2.7 +Response to RCPT command is fast. Previously, sendmail +expanded all aliases as far as it could \*- this could +take a very long time, particularly if there were +name server delays. Version 8 only checks for the +existence of an alias and does the expansion later. +It does still do a DNS lookup if there is an explicit host name +in the RCPT command, +but this time is bounded. +.ip \(sc5.2.8 +Numeric IP addresses are logged in Received: lines. +This helps tracing spoofed messages. +.ip \(sc5.2.17 +Self domain literal is properly handled. Previously, +if someone sent to user@[1.2.3.4], where 1.2.3.4 is +your IP address, the mail would probably be rejected +with a ``configuration error''. +Version 8 can handle these addresses. +.ip \(sc5.3.2 +Better control over individual timeouts. RFC 821 specified +no timeouts. Older versions of sendmail had a single +timeout, typically set to two hours. Version 8 allows +the configuration file to set timeouts for various +SMTP commands individually. +.ip \(sc5.3.3 +Error messages are sent as From:<>. This was urged by +RFC 821 and reiterated by RFC 1123, but older versions +of sendmail never really did it properly. Version 8 +does. However, some systems cannot handle this +perfectly legal address; if necessary, you can create +a special mailer that uses the `g' flag to disable this. +.ip \(sc5.3.3 +Error messages are never sent to <>. Previously, +sendmail was happy to send responses-to-responses which +sometimes resulted in responses-to-responses-to-responses +which resulted in .... you get the idea. +.ip \(sc5.3.3 +Route-addrs (the ugly ``<@hosta,@hostb:user@hostc>'' +syntax) are pruned. RFC 821 urged the use of this +bletcherous syntax. RFC 1123 has seen the light and +officially deprecates them, further urging that you +eliminate all but ``user@hostc'' should you receive +one of these things. Version 8 is slightly more generous +than the standards suggest; instead of stripping off all +the route addressees, it only strips hosts off up to +the one before the last one known to DNS, thus allowing +you to have pseudo-hosts such as foo.BITNET. The `R' +option will turn this off. +.lp +The areas in which sendmail is not ``unconditionally compliant'' are: +.ip \(sc5.2.6 +Sendmail does do header munging. +.ip \(sc5.2.10 +Sendmail doesn't always use the exact SMTP message +text from RFC 821. This is a rather silly requirement. +.ip \(sc5.3.1.1 +Sendmail doesn't guarantee only one connect for each +host on queue runs. Connection caching gives you most +of this, but it does not provide a guarantee. +.ip \(sc5.3.1.1 +Sendmail doesn't always provide an adequate limit +on concurrency. That is, there can be several +independent sendmails running at once. My feeling +is that doing an absolute limit would be a mistake +(it might result in lost mail). However, if you use +the XLA contributed software, most of this will be +guaranteed (but I don't guarantee the guarantee). +.sh 2 "Extended SMTP Support +.pp +Version 8 includes both sending and receiving support for Extended +SMTP support as defined by RFC 1425 (basic) and RFC 1427 (SIZE); +and limited support for RFC 1426 (BODY). +The body support is minimal because the +.q 8BITMIME +body type is not currently advertised. +Although such a body type will be accepted, +it will not be correctly converted to 7 bits +if speaking to a non-8-bit-MIME aware SMTP server. +.pp +.i Sendmail +tries to speak ESMTP if you have the `a' flag set +in the flags for the mailer descriptor, +or if the other end advertises the fact that it speaks ESMTP. +This is a non-standard advertisement: +.i sendmail +announces +.q "ESMTP spoken here" +during the initial connection message, +and client sendmails search for this message. +This creates some problems for some PC-based mailers, +which do not understand two-line greeting messages +as required by RFC 821. +.sh 2 "Eight-Bit Clean +.pp +Previous versions of sendmail used the 0200 bit for quoting. This +version avoids that use. +However, you can set option `7' to get seven bit stripping +for compatibility with RFC 821, +which is a 7-bit protocol. +This option says ``strip to 7 bits on input''. +.pp +Individual mailers can still produce seven bit out put using the +`7' mailer flag. +This flag says ``strip to 7 bits on output''. +.sh 2 "User Database" +.pp +The User Database (UDB) is an as-yet experimental attempt to provide +unified large-site name support. +We are installing it at Berkeley; +future versions may show significant modifications. +Briefly, UDB contains a database that is intended to contain +all the per-user information for your workgroup, +such as people's full names, their .plan information, +their outgoing mail name, and their mail drop. +.pp +The user database allows you to map both incoming and outgoing +addresses, much like IDA. However, the interface is still +better with IDA; +in particular, the alias file with incoming/outgoing marks +provides better locality of information. +.sh 2 "Improved BIND Support" +.pp +The BIND support, particularly for MX records, had a number of +annoying ``features'' which have been removed in this release. In +particular, these more tightly bind (pun intended) the name server +to sendmail, so that the name server resolution rules are incorporated +directly into sendmail. +.pp +The major change has been that the $[ ... $] operator didn't fully +qualify names that were in DNS as A or MX records. Version 8 does +this qualification. +.pp +This has proven to be an annoyance in Sun shops, +who often still run without BIND support. +However, it is really critical that this be supported, +since MX records are mandatory. +In SunOS you can choose either MX support or NIS support, +but not both. +This is fixed in Solaris, +and some +.i sendmail +support to allow this in SunOS should be forthcoming in a future release. +.sh 2 "Keyed Files" +.pp +Generalized keyed files is an idea taken directly from IDA sendmail +(albeit with a completely different implementation). +They can be useful on large sites. +.pp +Version 8 includes the following built-in map classes: +.ip dbm +Support for the ndbm(3) library. +.ip hash +Support for the ``Hash'' type from the new Berkeley db(3) library. +this library provides substantially better database support +than ndbm(3), +including in-memory caching, +arbitrarily long keys and values, +and better disk utilization. +.ip btree +Support for the ``B-Tree'' type from the new Berkeley db(3) library. +B-Trees provide better clustering than Hashed files +if you are fetching lots of records that have similar keys, +such as searching a dictionary for words beginning with ``detr''. +.ip nis +Support for NIS (a.k.a. YP) maps. +NIS+ is not supported in this version. +.ip host +Support for DNS lookups. +.ip dequote +A ``pseudo-map'' (that is, once that does not have any external data) +that allows a configuration file to break apart a quoted string +in the address. +This is necessary primarily for DECnet addresses, +which often have quoted addresses that need to be unwrapped on gateways. +.sh 2 "Multi-Word Classes & Macros in Classes" +.pp +Classes can now be multiple words. For example, +.(b +CShofmann.CS.Berkeley.EDU +.)b +allows you to match the entire string ``hofmann.CS.Berkeley.EDU'' +using the single construct ``$=S''. +.pp +Class definitions are now allowed to include macros \*- for example: +.(b +Cw$k +.)b +is legal. +.sh 2 "IDENT Protocol Support" +.pp +The IDENT protocol as defined in RFC 1413 [RFC1413] is supported. +However, many systems have a TCP/IP bug that renders this useless, +and the feature must be turned off. +Roughly, if one of these system receives a +.q "No route to host" +message (ICMP message ICMP_UNREACH_HOST) on +.i any +connection, all connections to that host are closed. +Some firewalls return this error if you try to connect +to the IDENT port, +so you can't receive email from these hosts on these systems. +It's possible that if the firewall used a more specific message +(such as ICMP_UNREACH_PROTOCOL, ICMP_UNREACH_PORT or ICMP_UNREACH_NET_PROHIB) +it would work, but this hasn't been verified. +.pp +IDENT protocol support cannot be used on +4.3BSD, +Apollo DomainOS, +Apple A/UX, +ConvexOS, +Data General DG/UX, +HP-UX, +Sequent Dynix, +or +Ultrix 4.x, x \(<= 3. +It seems to work on +4.4BSD, +IBM AIX 3.x, +OSF/1, +SGI IRIX, +Solaris, +SunOS, +and Ultrix 4.4. +.sh 2 "Separate Envelope/Header Processing +.pp +Since the From: line is passed in separately from the envelope +sender, these have both been made visible; the $g macro is set to +the envelope sender during processing of mailer argument vectors +and the header sender during processing of headers. +.pp +It is also possible to specify separate per-mailer envelope and +header processing. The SenderRWSet and RecipientRWset arguments +for mailers can be specified as ``envelope/header'' to give different +rewritings for envelope versus header addresses. +.sh 2 "Owner-List Propagates to Envelope +.pp +When an alias has an associated owner-list name, that alias is used +to change the envelope sender address. This will cause downstream +errors to be returned to that owner. +.pp +Some people find this confusing +because the envelope sender is what appears in the first +``From_'' line in UNIX messages +(that is, the line beginning ``From<space>'' +instead of ``From:''; +the latter is the header from, which +.i does +indicate the sender of the message). +In previous versions, +.i sendmail +has tried to avoid changing the envelope sender +for back compatibility with UNIX convention; +at this point that back compatibility is creating too many problems, +and it is necessary to move forward into the 1980s. +.sh 2 "Command Line Flags" +.pp +The +.b \-B +flag has been added to pass in body type information. +.pp +The +.b \-p +flag has been added to pass in protocol information +that was previously passed in by defining the +.b $r +and +.b $s +macros. +.pp +The +.b \-X +flag has been added to allow logging of all protocol in and +out of sendmail for debugging. +You can set +.q "\-X filename" +and a complete transcript will be logged in that file. +This gets big fast: the option is only for debugging. +.pp +The +.b \-q +flag can limit limit a queue run to specific recipients, +senders, or queue ids using \-qRsubstring, \-qSsubstring, or +\-qIsubstring respectively. +.sh 2 "New Configuration Line Types +.pp +The `T' (Trusted users) configuration line has been deleted. It +will still be accepted but will be ignored. +.pp +The `K' line has been added to declare database maps. +.pp +The `V' line has been added to declare the configuration version +level. +.pp +The `M' (mailer) line takes a D= field to specify execution +directory. +.sh 2 "New and Extended Options" +.pp +Several new options have been added, many to support new features, +others to allow tuning that was previously available only by +recompiling. Briefly: +.nr ii 0.5i +.ip A +The alias file specification can now be a list of alias files. +Also, the configuration can specify a class of file. +For example, to search the NIS aliases, use +.q OAnis:mail.aliases . +.ip b +Insist on a minimum number of disk blocks. +.ip C +Delivery checkpoint interval. Checkpoint the queue (to avoid +duplicate deliveries) every C addresses. +.ip E +Default error message. This message (or the contents of the +indicated file) are prepended to error messages. +.ip G +Enable GECOS matching. If you can't find a local user name +and this option is enabled, do a sequential scan of the passwd +file to match against full names. Previously a compile option. +.ip h +Maximum hop count. Previously this was compiled in. +.ip I +This option has been extended to allow setting of resolver parameters. +.ip j +Send errors in MIME-encapsulated format. +.ip J +Forward file path. Where to search for .forward files \*- defaults +to $HOME/.forward. +.ip k +Connection cache size. The total number of connections that will +be kept open at any time. +.ip K +Connection cache lifetime. The amount of time any connection +will be permitted to sit idle. +.ip l +Enable Errors-To: header. These headers violate RFC 1123; +this option is included to provide back compatibility with +old versions of sendmail. +.ip O +Incoming daemon options (e.g., use alternate SMTP port). +.ip p +Privacy options. These can be used to make your SMTP server +less friendly. +.ip r +This option has been extended to allow finer grained control +over timeouts. +For example, you can set the timeout for SMTP commands individually. +.ip R +Don't prune route-addrs. Normally, if version 8 sees an address +like "<@hostA,@hostB:user@hostC>, sendmail will try to strip off +as much as it can (up to user@hostC) as suggested by RFC 1123. +This option disables that behaviour. +.ip T +The +.q "Return To Sender" +timeout has been extended +to allow specification of a warning message interval, +typically something on the order of four hours. +If a message cannot be delivered in that interval, +a warning message is sent back to the sender +but the message continues to be tried. +.ip U +User database spec. This is still experimental. +.ip V +Fallback ``MX'' host. This can be thought of as an MX host +that applies to all addresses that has a very high preference +value (that is, use it only if everything else fails). +.ip w +If set, assume that if you are the best MX host for a host, +you should send directly to that host. This is intended +for compatibility with UIUC sendmail, and may have some +use on firewalls. +.ip 7 +Do not run eight bit clean. Technically, you have to assert +this option to be RFC 821 compatible. +.sh 2 "New Mailer Definitions" +.ip L= +Set the allowable line length. In V5, the L mailer flag implied +a line length limit of 990 characters; this is now settable to +an arbitrary value. +.ip F=a +Try to use ESMTP. It will fall back to SMTP if the initial +EHLO packet is rejected. +.ip F=b +Ensure a blank line at the end of messages. Useful on the +*file* mailer. +.ip F=c +Strip all comments from addresses; this should only be used as +a last resort when dealing with cranky mailers. +.ip F=g +Never use the null sender as the envelope sender, even when +running SMTP. This violates RFC 1123. +.ip F=7 +Strip all output to this mailer to 7 bits. +.ip F=L +Used to set the line limit to 990 bytes for SMTP compatibility. +It now does that only if the L= keyletter is not specified. +This flag is obsolete and should not be used. +.sh 2 "New or Changed Pre-Defined Macros" +.ip $k +UUCP node name from uname(2). +.ip $m +Domain part of our full hostname. +.ip $_ +RFC 1413-provided sender address. +.ip $w +Previously was sometimes the full domain name, sometimes +just the first word. Now guaranteed to be the first word +of the domain name (i.e., the host name). +.ip $j +Previously had to be defined \*- it is now predefined to be +the full domain name, if that can be determined. That is, +it is equivalent to $w.$m. +.sh 2 "New and Changed Classes" +.ip $=k +Initialized to contain $k. +.ip $=w +Now includes +.q [1.2.3.4] +(where 1.2.3.4 is your IP address) +to allow the configuration file to recognize your own IP address. +.sh 2 "New Rewriting Tokens" +.pp +The +.b $& +construct has been adopted from IDA to defer macro evaluation. +Normally, macros in rulesets are bound when the rule is first parsed +during startup. +Some macros change during processing and are uninteresting during startup. +However, that macro can be referenced using +.q $&x +to defer the evaulation of +$x +until the rule is processed. +.pp +The tokens +.b $( +and +.b $) +have been added to allow specification of map rewriting. +.pp +Version 8 allows +.b $@ +on the Left Hand Side of an `R' line to match +zero tokens. +This is intended to be used to match the null input. +.sh 2 "Bigger Defaults +.pp +Version 8 allows up to 100 rulesets instead of 30. It is recommended +that rulesets 0\-9 be reserved for sendmail's dedicated use in future +releases. +.pp +The total number of MX records that can be used has been raised to +20. +.pp +The number of queued messages that can be handled at one time has +been raised from 600 to 1000. +.sh 2 "Different Default Tuning Parameters +.pp +Version 8 has changed the default parameters for tuning queue costs +to make the number of recipients more important than the size of +the message (for small messages). This is reasonable if you are +connected with reasonably fast links. +.sh 2 "Auto-Quoting in Addresses +.pp +Previously, the ``Full Name <email address>'' syntax would generate +incorrect protocol output if ``Full Name'' had special characters +such as dot. This version puts quotes around such names. +.sh 2 "Symbolic Names On Error Mailer +.pp +Several names have been built in to the $@ portion of the $#error +mailer. For example: +.(b +$#error $@NOHOST $: Host unknown +.)b +Prints the indicated message +and sets the exit status of +.i sendmail +to +.sm EX_NOHOST . +.sh 2 "New Built-In Mailers" +.pp +Two new mailers, *file* and *include*, are included to define options +when mailing to a file or a :include: file respectively. Previously +these were overloaded on the local mailer. +.sh 2 "SMTP VRFY Doesn't Expand +.pp +Previous versions of sendmail treated VRFY and EXPN the same. In +this version, VRFY doesn't expand aliases or follow .forward files. +.pp +As an optimization, if you run with your default delivery mode +being queue-only, the RCPT command will also not chase aliases and +\&.forward files. +It will chase them when it processes the queue. +This speeds up RCPT processing. +.sh 2 "[IPC] Mailers Allow Multiple Hosts +.pp +When an address resolves to a mailer that has ``[IPC]'' as its +``Path'', the $@ part (host name) can be a colon-separated list of +hosts instead of a single hostname. This asks sendmail to search +the list for the first entry that is available exactly as though +it were an MX record. The intent is to route internal traffic +through internal networks without publishing an MX record to the +net. MX expansion is still done on the individual items. +.sh 2 "Aliases Extended" +.pp +The implementation has been merged with maps. Among other things, +this supports multiple alias files and NIS-based aliases. For +example: +.(b +OA/etc/aliases,nis:mail.aliases +.)b +will search first the local database +.q /etc/aliases +followed by the NIS map + +.sh 2 "Portability and Security Enhancements +.pp +A number of internal changes have been made to enhance portability. +.pp +Several fixes have been made to increase the paranoia factor. +.pp +In particular, the permissions required for .forward and :include: +files have been tightened up considerably. V5 would pretty much +read any file it could get to as root, which exposed some security +holes. V8 insists that all directories leading up to the .forward +or :include: file be searchable ("x" permission) by the controlling +user" (defined below), that the file itself be readable by the +controlling user, and that .forward files be owned by the user +who is being forwarded to or root. +.pp +The "controlling user" is the user on whose behalf the mail is +being delivered. For example, if you mail to "user1" then the +controlling user for ~user1/.forward and any mailers invoked +by that .forward file, including :include: files. +.pp +Previously, anyone who had a home directory could create a .forward +could forward to a program. Now, sendmail checks to make sure +that they have an "approved shell", that is, a shell listed in +the /etc/shells file. +.sh 2 "Miscellaneous Fixes and Enhancements" +.pp +A number of small bugs having to do with things like backslash-escaped +quotes inside of comments have been fixed. +.pp +The fixed size limit on header lines +(such as +.q To: +and +.q Cc: ) +has been eliminated; +those buffers are dynamically allocated now. +.pp +Sendmail writes a /etc/sendmail.pid file with the current process id +and the current invocation flags. +.pp +Two people using the same program (e.g., submit) are considered +"different" so that duplicate elimination doesn't delete one of +them. For example, two people forwarding their email to +|submit will be treated as two recipients. +.pp +The mailstats program prints mailer names and gets the location of +the sendmail.st file from /etc/sendmail.cf. +.pp +Many minor bugs have been fixed, such as handling of backslashes +inside of quotes. +.pp +A hook has been added to allow rewriting of local addresses after +aliasing. +.sh 1 "FUTURE WORK" +.pp +The previous section describes +.i sendmail +as of version 8.6.6. +There is still much to be done. +Some high points are described below. +This list is by no means exhaustive. +.sh 2 "Full MIME Support" +.pp +Currently +.i sendmail +only supports seven bit MIME messages. +Although it can pass eight bit MIME messages, +it cannot advertise that fact because the standards say +that the mail agent must be able to do 8- to 7-bit conversion +to have full 8-bit support. +This requires far more extensive modification of the message body +than is currently supported. +.pp +The best way to do this would be to support the general concept +of an external +``message filter'' +that could do arbitrary modifications of the message. +This would allow MIME conversion as well as such things as +automatic encryption of messages sent over external links. +This is probably an extremely non-trivial change. +.sh 2 "Service Switch Abstraction" +.pp +Most modern systems include some concept of a +.q "service switch" +\*- for example, to look up host names you can try +DNS, NIS, NIS+, text tables, NetInfo, +or other services in some arbitrary order. +This is currently very clumsy in +.i sendmail , +with only limited control of the services provided. +.sh 2 "More Control of Local Addresses" +.pp +Currently some addresses are declared as +.q local +and are handled specially \*- +for example, they may have .forward files, +may be translated into program calls or file deliveries, +and so forth. +These should be broken out into separate flags +to allow the local system administrator +to have more fine-grained control over operations. +.sh 2 "More Run-Time Configuration Options" +.pp +There are many options that are configured at compile time, +such as the method of file locking +and the use of the IDENT protocol +[RFC1413]. +These should be transfered to run time +by adding new options. +.pp +Similarly, some options are currently overloaded, +that is, a single option controls more than one thing. +These should probably be broken out into separate options. +.pp +This implies that options will change from single characters +to words. +.sh 2 "More Configuration Control Over Errors" +.pp +Currently, +the configuration file can generate an error message during parsing. +However, +it cannot tweak other operations, +such as issuing a warning message to the system postmaster. +Similarly, +some errors should not be triggered if they are in aliases +during an alias file rebuild, +but should be triggered if that alias is actually used. +.sh 2 "Long Term Host State" +.pp +Currently, +.i sendmail +only remembers host status during a single queue run. +This should be converted to long term status +stored on disk +so it can be shared between instantiations of +.i sendmail . +Entries will have to be timestamped +so they can time out. +This will allow +.i sendmail +to implement exponential backoff on queue runs +on a per-host basis. +.sh 2 "Connection Control" +.pp +Modern networks have different types of connectivity +than the past. +In particular, the rising prominence of dialup IP +has created certain challenges for automated servers. +It is not uncommon to try to make a connection to a host +and have it fail, even though if you tried again it would succeed. +The connection management could be a bit cleverer +to try to adapt to such situations. +.sh 2 "Other Caching" +.pp +When you do an MX record lookup, +the name server automatically returns the IP addresses +of the associated MX servers. +This information is currently ignored, +and another query is done to get this information. +It should be cached to avoid excess name server traffic. +.sh 1 "REFERENCES" +.ip [Allman83a] +.q "Sendmail \*- An Internetwork Mail Router." +E. Allman. +In +.ul +Unix Programmers's Manual, +4.2 Berkeley Software Distribution, +volume 2C. +August 1983. +.ip [Allman83b] +.q "Mail Systems and Addressing in 4.2BSD." +E. Allman +In +.ul +UNICOM Conference Proceedings. +San Diego, California. +January 1983. +.ip [Allman&Amos85] +``Sendmail Revisited.'' +E. Allman and M. Amos. +In +.ul +Usenix Summer 1985 Conference Proceedings. +Portland, Oregon. +June 1985. +.ip [IDA87] +.ul 3 +Electronic Mail Addressing in Theory and Practice +with the IDA Sendmail Enhancement Kit +(or The Postmaster's Last Will and Testament). +Lennart Lo\*:vstrand. +Department of Computer and Information Science, +University of Linko\*:ping, +Sweden, +Report no. LiTH-IDA-Ex-8715. +May 1987. +.ip [RFC821] +.ul +Simple Mail Transport Protocol. +J. Postel. +August 1982. +.ip [RFC1123] +.ul +Requirements for Internet Hosts \*- Application and Support. +Internet Engineering Task Force, +R. Braden, Editor. +October 1989. +.ip [RFC1344] +.ul +Implications of MIME for Internet Mail Gateways. +N. Borenstein. +June 1992. +.ip [RFC1413] +.ul +Identification Protocol. +M. St. Johns. +February 1993. +.ip [RFC1425] +.ul +SMTP Service Extensions. +J. Klensin, N. Freed, M. Rose, E. Stefferud, and D. Crocker. +February 1993. +.ip [RFC1426] +.ul +SMTP Service Extension for 8bit-MIMEtransport. +J. Klensin, N. Freed, M. Rose, E. Stefferud, and D. Crocker. +February 1993. +.ip [RFC1427] +.ul +SMTP Service Extension for Message Size Declaration. +J. Klensin, N. Freed, and K. Moore. +February 1993. +.ip [RFC1521] +.ul 3 +MIME (Multipurpose Internet Mail Extensions) Part One: +Mechanisms for Specifying and Describing +the Format of Internet Message Bodies. +N. Borenstein and N. Freed. +September 1993. diff --git a/usr.sbin/sendmail/doc/changes/changes.ps b/usr.sbin/sendmail/doc/changes/changes.ps new file mode 100644 index 000000000000..5ba54a43edec --- /dev/null +++ b/usr.sbin/sendmail/doc/changes/changes.ps @@ -0,0 +1,1092 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.08 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Italic +%%+ font Times-Bold +%%+ font Symbol +%%DocumentSuppliedResources: procset grops 1.08 0 +%%Pages: 11 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.08 0 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Italic +%%IncludeResource: font Times-Bold +%%IncludeResource: font Symbol +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL +792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron +/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space +/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft +/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four +/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C +/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash +/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q +/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase +/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger +/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus +/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu +/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright +/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde +/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute +/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls +/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute +/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve +/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex +/udieresis/yacute/thorn/ydieresis]def/Times-Bold@0 ENC0/Times-Bold RE +/Times-Italic@0 ENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 14/Times-Roman@0 SF(Changes in Sendmail V)196.615 141 Q(ersion 8*)-1.554 E +/F1 10/Times-Roman@0 SF(Eric Allman)263.42 165 Q/F2 10/Times-Italic@0 SF +(Univer)220.2 183 Q(sity of California, Berk)-.1 E(ele)-.1 E(y)-.3 E +(Mammoth Pr)251.98 195 Q(oject)-.45 E F1(ABSTRA)262.085 227.4 Q(CT)-.4 E -1.11 +(Ve)112 243.6 S 1.709(rsion 8 of)1.11 F F2(sendmail)4.209 E F1 1.709 +(includes a number of major changes from pre)4.209 F 1.71(vious v)-.25 F +(ersions.)-.15 E .701(This paper gi)112 255.6 R -.15(ve)-.25 G 3.201(sav).15 G +.701(ery short history of)194.794 255.6 R F2(sendmail)3.201 E F1 3.201(,as)C .7 +(ummary of the major dif)329.82 255.6 R(ferences)-.25 E .953(between v)112 +267.6 R .954(ersion 5 \(the last publically a)-.15 F -.25(va)-.2 G .954 +(ilable v).25 F .954(ersion\) and v)-.15 F .954(ersion 8, and some dis-)-.15 F +(cussion of future directions.)112 279.6 Q .48 +(In 1987, the author stopped major w)97 324 R .48(ork on)-.1 F F2(sendmail)2.98 +E F1 .48(due to other time committments, only to return)2.98 F(to acti)72 336 Q +.3 -.15(ve w)-.25 H(ork in 1991.).05 E(This paper e)5 E(xplores wh)-.15 E 2.5 +(yw)-.05 G(ork resumed and what changes ha)277 336 Q .3 -.15(ve b)-.2 H +(een made.).15 E .58(Section 1 gi)97 352.2 R -.15(ve)-.25 G 3.08(sas).15 G .58 +(hort history of)173.36 352.2 R F2(sendmail)3.08 E F1 .58(through v)3.08 F .58 +(ersion 5 and the moti)-.15 F -.25(va)-.25 G .58(tion behind w).25 F .58 +(orking on)-.1 F -.15(ve)72 364.2 S .126(rsion 8.).15 F .126 +(Section 2 has a rather detailed description of what has changed between v) +5.126 F .125(ersion 5 and v)-.15 F .125(ersion 8.)-.15 F +(The paper \214nishes of)72 376.2 Q 2.5(fw)-.25 G +(ith some thoughts about what still needs to be done.)168.95 376.2 Q/F3 10 +/Times-Bold@0 SF 2.5(1. HIST)72 400.2 R(OR)-.18 E(Y)-.35 E F1 .151 +(As discussed else)112 416.4 R .151 +(where, [Allman83a, Allman83b, Allman&Amos85] sendmail has e)-.25 F .151 +(xisted in v)-.15 F(ar)-.25 E(-)-.2 E .405(ious forms since 1980.)87 428.4 R +.405(It w)5.405 F .405(as released under the name)-.1 F F2(delivermail)2.905 E +F1 .404(in 4BSD and 4.1BSD, and as)2.905 F F2(send-)2.904 E(mail)87 440.4 Q F1 +(in 4.2BSD.)2.5 E(It quickly became the dominant mail system for netw)5 E(ork) +-.1 E(ed UNIX systems.)-.1 E 1.569(Prior the release of 4.3BSD in No)112 456.6 +R -.15(ve)-.15 G 1.569(mber 1986, the author had left the Uni).15 F -.15(ve) +-.25 G 1.57(rsity for pri).15 F -.25(va)-.25 G(te).25 E(industry)87 468.6 Q +3.347(,b)-.65 G .847(ut continued to do some w)129.777 468.6 R .847(ork on)-.1 +F F2(sendmail)3.347 E F1 .847(with acti)3.347 F .846(vity slo)-.25 F .846 +(wly trailing of)-.25 F 3.346(fu)-.25 G .846(ntil ef)445.204 468.6 R(fecti)-.25 +E -.15(ve)-.25 G(ly).15 E .255(stopping after February 1987.)87 480.6 R .255 +(There w)5.255 F .255(as minimal support done by man)-.1 F 2.756(yp)-.15 G .256 +(eople for se)389.796 480.6 R -.15(ve)-.25 G .256(ral years, until).15 F +(July of 1991 when the original author)87 492.6 Q 2.5(,w)-.4 G +(ho had returned the Uni)249.36 492.6 Q -.15(ve)-.25 G(rsity).15 E 2.5(,s)-.65 +G(tarted acti)379.4 492.6 Q .3 -.15(ve w)-.25 H(ork on it ag).05 E(ain.)-.05 E +1.271(There were se)112 508.8 R -.15(ve)-.25 G 1.271(ral reasons for rene).15 F +1.271(wed w)-.25 F 1.271(ork on)-.1 F F2(sendmail)3.771 E F1 6.271(.T)C 1.271 +(here w)369.549 508.8 R 1.27(as a desire at Berk)-.1 F(ele)-.1 E 3.77(yt)-.15 G +(o)499 508.8 Q(con)87 520.8 Q -.15(ve)-.4 G .097 +(rt to a subdomained structure so that indi).15 F .098 +(viduals were identi\214ed by their subdomain rather than by)-.25 F 1.758 +(their indi)87 532.8 R 1.758(vidual w)-.25 F 1.758(orkstation; although possib\ +le in the old code, there were some problems, and the)-.1 F .66(author w)87 +544.8 R .66(as the ob)-.1 F .66(vious person to address them.)-.15 F .66 +(The Computer Systems Research Group \(CSRG\), the)5.66 F 1.89 +(group that produced the Berk)87 556.8 R(ele)-.1 E 4.39(yS)-.15 G(oftw)238.12 +556.8 Q 1.89(are Distrib)-.1 F 1.89(utions, w)-.2 F 1.89(as w)-.1 F 1.89 +(orking on 4.4BSD, and w)-.1 F 1.89(anted an)-.1 F .053 +(update to the mail system.)87 568.8 R .053(Bryan Costales w)5.053 F .053(as w) +-.1 F .053(orking on a book on)-.1 F F2(sendmail)2.553 E F1 .053(that w)2.553 F +.053(as being re)-.1 F(vie)-.25 E(wed)-.25 E .923(by the author)87 580.8 R +3.423(,w)-.4 G .923(hich encouraged him to mak)154.359 580.8 R 3.422(es)-.1 G +.922(ome re)283.572 580.8 R 3.422(visions. And)-.25 F .922(the author w)3.422 F +.922(anted to try to unify)-.1 F(some of the disparate v)87 592.8 Q(ersions of) +-.15 E F2(sendmail)2.5 E F1(that had been permitted to proliferate.)2.5 E .023 +(During the 1987\25591 f)112 609 R(allo)-.1 E 2.523(wp)-.25 G .023(eriod, man) +228.482 609 R 2.523(yv)-.15 G .023(endors and outside v)283.498 609 R .023 +(olunteers had produced v)-.2 F .024(ariants of)-.25 F F2(sendmail)87 621 Q F1 +5.518(.P)C .517(erhaps the best kno)136.688 621 R .517(wn is the ID)-.25 F +3.017(Av)-.4 G .517(ersion [ID)280.317 621 R 3.017(A87]. Originally)-.4 F .517 +(intended to be a ne)3.017 F 3.017(ws)-.25 G .517(et of)485.433 621 R .268 +(con\214guration \214les, ID)87 633 R 2.768(Ae)-.4 G .269(xpanded into a f) +189.464 633 R .269(airly lar)-.1 F .269(ge set of patches for the code.)-.18 F +.269(Originally produced in)5.269 F .471(Sweden, ID)87 645 R 2.971(Ad)-.4 G +-2.15 -.25(ev e)149.472 645 T .471(lopment passed to the Uni).25 F -.15(ve)-.25 +G .471(rsity of Illinois, and w).15 F .47(as widely used by the f)-.1 F .47 +(airly lar)-.1 F(ge)-.18 E .077 +(set of people who prefer to get and compile their o)87 657 R .077 +(wn source code rather than use v)-.25 F(endor)-.15 E .078(-supplied bina-)-.2 +F(ries.)87 669 Q .32 LW 76 678.6 72 678.6 DL 80 678.6 76 678.6 DL 84 678.6 80 +678.6 DL 88 678.6 84 678.6 DL 92 678.6 88 678.6 DL 96 678.6 92 678.6 DL 100 +678.6 96 678.6 DL 104 678.6 100 678.6 DL 108 678.6 104 678.6 DL 112 678.6 108 +678.6 DL 116 678.6 112 678.6 DL 120 678.6 116 678.6 DL 124 678.6 120 678.6 DL +128 678.6 124 678.6 DL 132 678.6 128 678.6 DL 136 678.6 132 678.6 DL 140 678.6 +136 678.6 DL 144 678.6 140 678.6 DL 148 678.6 144 678.6 DL 152 678.6 148 678.6 +DL 156 678.6 152 678.6 DL 160 678.6 156 678.6 DL 164 678.6 160 678.6 DL 168 +678.6 164 678.6 DL 172 678.6 168 678.6 DL 176 678.6 172 678.6 DL 180 678.6 176 +678.6 DL 184 678.6 180 678.6 DL 188 678.6 184 678.6 DL 192 678.6 188 678.6 DL +196 678.6 192 678.6 DL 200 678.6 196 678.6 DL 204 678.6 200 678.6 DL 208 678.6 +204 678.6 DL 212 678.6 208 678.6 DL 216 678.6 212 678.6 DL/F4 8/Times-Roman@0 +SF .045(*An earlier v)93.6 690.6 R .045(ersion of this paper w)-.12 F .044 +(as printed in the Proceedings of the 1994 A)-.08 F .044 +(UUG Queensland Summer T)-.44 F .044(echnical Conference,)-.56 F(Gate)72 700.2 +Q -.08(wa)-.2 G 2(yH).08 G(otel, Brisbane, March 1994.)107.928 700.2 Q F3 +(Changes in Sendmail V)72 756 Q(ersion 8)-1 E(1)499 756 Q EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 294.65(2C)72 60 S(hanges in Sendmail V)378.87 60 Q +(ersion 8)-1 E/F1 10/Times-Roman@0 SF .151 +(In about the same time frame, attempts were made to clean up and e)112 96 R +.151(xtend the Simple Mail T)-.15 F(rans-)-.35 E .468 +(port Protocol \(SMTP\) [RFC821].)87 108 R .468(This in)5.468 F -.2(vo)-.4 G +(lv).2 E .469(ed clari\214cations of some ambiguities in the protocol, and)-.15 +F .085(correction of some problem areas [RFC1123], as well as e)87 120 R .084 +(xtensions for additional functionality \(dubbed)-.15 F 1.052 +(Extended Simple Mail T)87 132 R 1.053 +(ransport Protocol, or ESMTP\) [RFC1425, RFC1426, RFC1427] and a richer)-.35 F +1.376(set of semantics in the body of messages \(the Multipurpose Internet Mai\ +l Extensions, a.k.a. MIME\))87 144 R .497([RFC1521, RFC1344].)87 156 R .497 +(Neither the ID)5.497 F 2.998(Ag)-.4 G .498(roup nor most v)258.526 156 R .498 +(endors were modifying)-.15 F/F2 10/Times-Italic@0 SF(sendmail)2.998 E F1 .498 +(to conform)2.998 F 1.7(to these ne)87 168 R 4.2(ws)-.25 G 4.2(tandards. It) +148.23 168 R 1.699(seemed clear that these were `)4.2 F 1.699(`good things') +-.74 F 4.199('t)-.74 G 1.699(hat should be encouraged.)394.483 168 R(Ho)87 180 +Q(we)-.25 E -.15(ve)-.25 G 1.635 -.4(r, s).15 H .835(ince no one w).4 F .835 +(as w)-.1 F .835(orking on a publically a)-.1 F -.25(va)-.2 G .835(ilable v).25 +F .836(ersion of)-.15 F F2(sendmail)3.336 E F1 .836(with these updates,)3.336 F +(the)87 192 Q 2.5(yw)-.15 G(ere unlik)113.79 192 Q(ely to be widely deplo)-.1 E +(yed an)-.1 E 2.5(yt)-.15 G(ime in the near future.)274.25 192 Q .466 +(There are, of course, other mail transport agents a)112 208.2 R -.25(va)-.2 G +.465(ilable, such as).25 F F2 .465(MMDF zmailer smail)2.965 F F1(and)2.965 E F2 +(PP)2.965 E F1(Ho)87 220.2 Q(we)-.25 E -.15(ve)-.25 G .842 -.4(r, n).15 H .042 +(one of these seemed to be g).4 F .043(aining the prominence of)-.05 F F2 +(sendmail)2.543 E F1 2.543(;i)C 2.543(ta)390.518 220.2 S .043 +(ppeared that most compa-)400.281 220.2 R .238(nies w)87 232.2 R .238 +(ould not con)-.1 F -.15(ve)-.4 G .238(rt to another mail transport agent an) +.15 F 2.737(yt)-.15 G .237(ime in the forseeable future.)327.438 232.2 R(Ho) +5.237 E(we)-.25 E -.15(ve)-.25 G 1.037 -.4(r, t).15 H(he).4 E(y)-.15 E +(might be persuaded to con)87 244.2 Q -.15(ve)-.4 G(rt to a ne).15 E(wer v)-.25 +E(ersion of)-.15 E F2(sendmail)2.5 E F1(.)A .841(All of these con)112 260.4 R +.841(vinced the author to w)-.4 F .841(ork on a updated v)-.1 F .841(ersion of) +-.15 F F2(sendmail)3.342 E F1 .842(for public distrib)3.342 F(u-)-.2 E(tion.)87 +272.4 Q 1.024(The ne)112 288.6 R 3.524(wv)-.25 G 1.023(ersion of)155.858 288.6 +R F2(sendmail)3.523 E F1 1.023(is referred to as v)3.523 F 1.023 +(ersion eight \(V8\).)-.15 F -1.11(Ve)6.023 G 1.023(rsions six and se)1.11 F +-.15(ve)-.25 G 3.523(nw).15 G(ere)491.79 288.6 Q 1.281 +(skipped because of an agreement that all \214les in 4.4BSD w)87 300.6 R 1.281 +(ould be numbered as \2318.1\232.)-.1 F 1.282(Rather than)6.282 F(ha)87 312.6 Q +2.05 -.15(ve a)-.2 H 4.25(ne).15 G 1.75(xternal v)127.76 312.6 R 1.75 +(ersion number that dif)-.15 F 1.75(fered from the \214le v)-.25 F 1.75 +(ersion numbers,)-.15 F F2(sendmail)4.25 E F1 1.75(just jumped)4.25 F +(directly to V8.)87 324.6 Q F0 2.5(2. CHANGES)72 348.6 R(IN VERSION EIGHT)2.5 E +F1 .138(The follo)112 364.8 R .139 +(wing is a summary of the changes between the last commonly a)-.25 F -.25(va) +-.2 G .139(ilable v).25 F .139(ersion of send-)-.15 F(mail from Berk)87 376.8 Q +(ele)-.1 E 2.5(y\()-.15 G(5.67\) and the latest v)170.9 376.8 Q +(ersion \(8.6.6\).)-.15 E(Man)112 393 Q 2.5(yo)-.15 G 2.5(ft)142.68 393 S +(hese are ideas that had been tried in ID)151.29 393 Q(A, b)-.4 E(ut man)-.2 E +2.5(yo)-.15 G 2.5(ft)363.27 393 S(hem were generalized in V8.)371.88 393 Q F0 +2.5(2.1. P)87 417 R(erf)-.2 E(ormance Enhancements)-.25 E F1 .549 +(Instead of closing SMTP connections immediately)127 433.2 R 3.049(,o)-.65 G +.549(pen connections are cached for possible)342.135 433.2 R .029(future use.) +102 445.2 R .029(There is a limit to the number of simultaneous open connectio\ +ns and the idle time of an)5.029 F(y)-.15 E(indi)102 457.2 Q +(vidual connection.)-.25 E 1.219(This is of best help during queue processing \ +\(since there is the potential of man)127 473.4 R 3.719(yd)-.15 G(if)474.82 +473.4 Q(ferent)-.25 E 1.113(messages going to one site\), although it can also\ + help when processing MX records which aren')102 485.4 R(t)-.18 E +(handled by MX Piggybacking.)102 497.4 Q 1.258(If tw)127 513.6 R 3.757(oh)-.1 G +1.257(osts with dif)161.075 513.6 R 1.257 +(ferent names in a single message happen to ha)-.25 F 1.557 -.15(ve t)-.2 H +1.257(he same set of MX).15 F .94(hosts, the)102 525.6 R 3.44(yc)-.15 G .94 +(an be sent in the same transaction.)153.45 525.6 R -1.11(Ve)5.94 G .94 +(rsion 8 notices this and tries to batch the mes-)1.11 F(sages.)102 537.6 Q +-.15(Fo)127 553.8 S 3.638(re).15 G 1.138(xample, if tw)148.668 553.8 R 3.637 +(os)-.1 G 1.137(ites `)216.42 553.8 R(`foo.com')-.74 E 3.637('a)-.74 G 1.137 +(nd `)286.914 553.8 R(`bar)-.74 E(.com')-.55 E 3.637('a)-.74 G 1.137 +(re both serv)352.408 553.8 R 1.137(ed by UUNET)-.15 F 3.637(,t)-.74 G(he) +470.513 553.8 Q 3.637(yw)-.15 G(ill)495.66 553.8 Q(ha)102 565.8 Q .557 -.15 +(ve t)-.2 H .257(he same set of MX hosts and will be sent in one transaction.) +.15 F .258(UUNET will then split the mes-)5.258 F(sage and send it to the tw) +102 577.8 Q 2.5(oi)-.1 G(ndi)213.28 577.8 Q(vidual hosts.)-.25 E F0 2.5 +(2.2. RFC)87 601.8 R(1123 Changes)2.5 E F1 2.607(An)127 618 S .107 +(umber of changes ha)141.827 618 R .407 -.15(ve b)-.2 H .106(een made to mak) +.15 F 2.606(es)-.1 G .106(endmail `)321.07 618 R .106 +(`conditionally compliant')-.74 F 2.606('\()-.74 G .106(that is, it)469.058 618 +R(satis\214es all of the MUST clauses and most b)102 630 Q +(ut not all of the SHOULD clauses in RFC 1123\).)-.2 E +(The major areas of change are \(numbers are RFC 1123 section numbers\):)127 +646.2 Q 26.5(\2475.2.7 Response)102 662.4 R .565(to RCPT command is f)3.065 F +3.065(ast. Pre)-.1 F(viously)-.25 E 3.065(,s)-.65 G .565(endmail e)362.295 +662.4 R .565(xpanded all aliases as f)-.15 F(ar)-.1 E .686 +(as it could \212 this could tak)156 674.4 R 3.186(eav)-.1 G .685 +(ery long time, particularly if there were name serv)290.118 674.4 R(er)-.15 E +3.891(delays. V)156 686.4 R 1.391(ersion 8 only checks for the e)-1.11 F 1.392 +(xistence of an alias and does the e)-.15 F(xpansion)-.15 E(later)156 698.4 Q +5.176(.I)-.55 G 2.676(td)184.226 698.4 S .176 +(oes still do a DNS lookup if there is an e)194.682 698.4 R .175 +(xplicit host name in the RCPT com-)-.15 F(mand, b)156 710.4 Q +(ut this time is bounded.)-.2 E EP +%%Page: 3 3 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(3)499 60 Q +/F1 10/Times-Roman@0 SF 26.5(\2475.2.8 Numeric)102 96 R .612 +(IP addresses are logged in Recei)3.112 F -.15(ve)-.25 G .613(d: lines.).15 F +.613(This helps tracing spoofed mes-)5.613 F(sages.)156 108 Q 21.5 +(\2475.2.17 Self)102 124.2 R .127(domain literal is properly handled.)2.627 F +(Pre)5.126 E(viously)-.25 E 2.626(,i)-.65 G 2.626(fs)368.196 124.2 S .126 +(omeone sent to user@[1.2.3.4],)378.042 124.2 R .12 +(where 1.2.3.4 is your IP address, the mail w)156 136.2 R .12 +(ould probably be rejected with a `)-.1 F(`con\214gu-)-.74 E(ration error')156 +148.2 Q 2.5('. V)-.74 F(ersion 8 can handle these addresses.)-1.11 E 26.5 +(\2475.3.2 Better)102 164.4 R 1.189(control o)3.69 F -.15(ve)-.15 G 3.689(ri) +.15 G(ndi)240.088 164.4 Q 1.189(vidual timeouts.)-.25 F 1.189 +(RFC 821 speci\214ed no timeouts.)6.189 F 1.189(Older v)6.189 F(er)-.15 E(-)-.2 +E .002(sions of sendmail had a single timeout, typically set to tw)156 176.4 R +2.502(oh)-.1 G 2.502(ours. V)398.142 176.4 R .002(ersion 8 allo)-1.11 F .002 +(ws the)-.25 F(con\214guration \214le to set timeouts for v)156 188.4 Q +(arious SMTP commands indi)-.25 E(vidually)-.25 E(.)-.65 E 26.5 +(\2475.3.3 Error)102 204.6 R 1.06(messages are sent as From:<>.)3.56 F 1.059 +(This w)6.059 F 1.059(as ur)-.1 F 1.059(ged by RFC 821 and reiterated by)-.18 F +.237(RFC 1123, b)156 216.6 R .237(ut older v)-.2 F .237(ersions of sendmail ne) +-.15 F -.15(ve)-.25 G 2.737(rr).15 G .237(eally did it properly)355.186 216.6 R +5.237(.V)-.65 G .238(ersion 8 does.)448.254 216.6 R(Ho)156 228.6 Q(we)-.25 E +-.15(ve)-.25 G 1.934 -.4(r, s).15 H 1.134 +(ome systems cannot handle this perfectly le).4 F -.05(ga)-.15 G 3.633(la).05 G +1.133(ddress; if necessary)402.941 228.6 R 3.633(,y)-.65 G(ou)494 228.6 Q +(can create a special mailer that uses the `g' \215ag to disable this.)156 +240.6 Q 26.5(\2475.3.3 Error)102 256.8 R 3.212(messages are ne)5.712 F -.15(ve) +-.25 G 5.712(rs).15 G 3.212(ent to <>.)275.628 256.8 R(Pre)8.213 E(viously)-.25 +E 5.713(,s)-.65 G 3.213(endmail w)383.028 256.8 R 3.213(as happ)-.1 F 5.713(yt) +-.1 G 5.713(os)474.957 256.8 S(end)489.56 256.8 Q 6 +(responses-to-responses which sometimes resulted in responses-to-responses-to-) +156 268.8 R(responses which resulted in ....)156 280.8 Q(you get the idea.)5 E +26.5(\2475.3.3 Route-addrs)102 297 R .111(\(the ugly `)2.611 F +(`<@hosta,@hostb:user@hostc>')-.74 E 2.611('s)-.74 G .111(yntax\) are pruned.) +389.124 297 R .112(RFC 821)5.112 F(ur)156 309 Q 1.001 +(ged the use of this bletcherous syntax.)-.18 F 1 +(RFC 1123 has seen the light and of)6.001 F(\214cially)-.25 E 1.124 +(deprecates them, further ur)156 321 R 1.125(ging that you eliminate all b)-.18 +F 1.125(ut `)-.2 F(`user@hostc')-.74 E 3.625('s)-.74 G 1.125(hould you)462.595 +321 R(recei)156 333 Q 1.698 -.15(ve o)-.25 H 1.398(ne of these things.).15 F +-1.11(Ve)6.398 G 1.398(rsion 8 is slightly more generous than the standards) +1.11 F .753(suggest; instead of stripping of)156 345 R 3.253(fa)-.25 G .753 +(ll the route addressees, it only strips hosts of)293.115 345 R 3.254(fu)-.25 G +3.254(pt)487.966 345 S(o)499 345 Q 1.29(the one before the last one kno)156 357 +R 1.289(wn to DNS, thus allo)-.25 F 1.289(wing you to ha)-.25 F 1.589 -.15 +(ve p)-.2 H(seudo-hosts).15 E(such as foo.BITNET)156 369 Q 5(.T)-.74 G +(he `R' option will turn this of)251.91 369 Q(f.)-.25 E +(The areas in which sendmail is not `)102 385.2 Q(`unconditionally compliant') +-.74 E 2.5('a)-.74 G(re:)367.43 385.2 Q 26.5(\2475.2.6 Sendmail)102 401.4 R +(does do header munging.)2.5 E 21.5(\2475.2.10 Sendmail)102 417.6 R(doesn')3.2 +E 3.2(ta)-.18 G -.1(lwa)233.88 417.6 S .7(ys use the e).1 F .701 +(xact SMTP message te)-.15 F .701(xt from RFC 821.)-.15 F .701(This is a)5.701 +F(rather silly requirement.)156 429.6 Q 19(\2475.3.1.1 Sendmail)102 445.8 R +(doesn')3.512 E 3.512(tg)-.18 G 1.012 +(uarantee only one connect for each host on queue runs.)235.064 445.8 R +(Connec-)6.011 E(tion caching gi)156 457.8 Q -.15(ve)-.25 G 2.5(sy).15 G +(ou most of this, b)235.87 457.8 Q(ut it does not pro)-.2 E(vide a guarantee.) +-.15 E 19(\2475.3.1.1 Sendmail)102 474 R(doesn')2.843 E 2.843(ta)-.18 G -.1 +(lwa)233.166 474 S .343(ys pro).1 F .343(vide an adequate limit on concurrenc) +-.15 F 4.144 -.65(y. T)-.15 H .344(hat is, there can).65 F .757(be se)156 486 R +-.15(ve)-.25 G .757(ral independent sendmails running at once.).15 F .757 +(My feeling is that doing an abso-)5.757 F 1.047(lute limit w)156 498 R 1.047 +(ould be a mistak)-.1 F 3.547(e\()-.1 G 1.048(it might result in lost mail\).) +284.302 498 R(Ho)6.048 E(we)-.25 E -.15(ve)-.25 G 1.848 -.4(r, i).15 H 3.548 +(fy).4 G 1.048(ou use the)461.354 498 R .801(XLA contrib)156 510 R .801 +(uted softw)-.2 F .801(are, most of this will be guaranteed \(b)-.1 F .801 +(ut I don')-.2 F 3.3(tg)-.18 G .8(uarantee the)454.61 510 R(guarantee\).)156 +522 Q F0 2.5(2.3. Extended)87 546 R(SMTP Support)2.5 E F1 -1.11(Ve)127 562.2 S +.154(rsion 8 includes both sending and recei)1.11 F .155 +(ving support for Extended SMTP support as de\214ned)-.25 F .229(by RFC 1425 \ +\(basic\) and RFC 1427 \(SIZE\); and limited support for RFC 1426 \(BOD)102 +574.2 R 2.729(Y\). The)-.55 F(body)2.729 E .275(support is minimal because the\ + \2318BITMIME\232 body type is not currently adv)102 586.2 R 2.776 +(ertised. Although)-.15 F(such)2.776 E 3.076(ab)102 598.2 S .576 +(ody type will be accepted, it will not be correctly con)114.516 598.2 R -.15 +(ve)-.4 G .576(rted to 7 bits if speaking to a non-8-bit-).15 F(MIME a)102 +610.2 Q -.1(wa)-.15 G(re SMTP serv).1 E(er)-.15 E(.)-.55 E/F2 10/Times-Italic@0 +SF(Sendmail)127 626.4 Q F1 .287(tries to speak ESMTP if you ha)2.787 F .588 +-.15(ve t)-.2 H .288(he `a' \215ag set in the \215ags for the mailer descrip-) +.15 F(tor)102 638.4 Q 3.322(,o)-.4 G 3.322(ri)123.532 638.4 S 3.322(ft)132.964 +638.4 S .822(he other end adv)142.396 638.4 R .822(ertises the f)-.15 F .822 +(act that it speaks ESMTP)-.1 F 5.822(.T)-1.11 G .821 +(his is a non-standard adv)376.446 638.4 R(ertise-)-.15 E(ment:)102 650.4 Q F2 +(sendmail)2.98 E F1 .48(announces \231ESMTP spok)2.98 F .48 +(en here\232 during the initial connection message, and client)-.1 F .587 +(sendmails search for this message.)102 662.4 R .586 +(This creates some problems for some PC-based mailers, which)5.586 F +(do not understand tw)102 674.4 Q +(o-line greeting messages as required by RFC 821.)-.1 E EP +%%Page: 4 4 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 294.65(4C)72 60 S(hanges in Sendmail V)378.87 60 Q +(ersion 8)-1 E 2.5(2.4. Eight-Bit)87 96 R(Clean)2.5 E/F1 10/Times-Roman@0 SF +(Pre)127 112.2 Q 1.263(vious v)-.25 F 1.263 +(ersions of sendmail used the 0200 bit for quoting.)-.15 F 1.264(This v)6.264 F +1.264(ersion a)-.15 F -.2(vo)-.2 G 1.264(ids that use.).2 F(Ho)102 124.2 Q(we) +-.25 E -.15(ve)-.25 G 1.119 -.4(r, y).15 H .318 +(ou can set option `7' to get se).4 F -.15(ve)-.25 G 2.818(nb).15 G .318 +(it stripping for compatibility with RFC 821, which is)290.046 124.2 R 2.5(a7) +102 136.2 S(-bit protocol.)113.94 136.2 Q(This option says `)5 E +(`strip to 7 bits on input')-.74 E('.)-.74 E(Indi)127 152.4 Q .375 +(vidual mailers can still produce se)-.25 F -.15(ve)-.25 G 2.875(nb).15 G .376 +(it out put using the `7' mailer \215ag.)303.02 152.4 R .376(This \215ag says) +5.376 F -.74(``)102 164.4 S(strip to 7 bits on output').74 E('.)-.74 E F0 2.5 +(2.5. User)87 188.4 R(Database)2.5 E F1 1.926 +(The User Database \(UDB\) is an as-yet e)127 204.6 R 1.926 +(xperimental attempt to pro)-.15 F 1.925(vide uni\214ed lar)-.15 F(ge-site)-.18 +E .396(name support.)102 216.6 R 1.996 -.8(We a)5.396 H .396 +(re installing it at Berk).8 F(ele)-.1 E .396(y; future v)-.15 F .396 +(ersions may sho)-.15 F 2.897(ws)-.25 G .397(igni\214cant modi\214cations.) +406.373 216.6 R(Brie\215y)102 228.6 Q 3.583(,U)-.65 G 1.083 +(DB contains a database that is intended to contain all the per)142.433 228.6 R +1.082(-user information for your)-.2 F -.1(wo)102 240.6 S .172 +(rkgroup, such as people').1 F 2.673(sf)-.55 G .173 +(ull names, their .plan information, their outgoing mail name, and their)222.29 +240.6 R(mail drop.)102 252.6 Q .438(The user database allo)127 268.8 R .438 +(ws you to map both incoming and outgoing addresses, much lik)-.25 F 2.937(eI) +-.1 G -.4(DA)487.46 268.8 S(.).4 E(Ho)102 280.8 Q(we)-.25 E -.15(ve)-.25 G +1.799 -.4(r, t).15 H .999(he interf).4 F .999(ace is still better with ID)-.1 F +.999(A; in particular)-.4 F 3.499(,t)-.4 G 1 +(he alias \214le with incoming/outgoing)355.55 280.8 R(marks pro)102 292.8 Q +(vides better locality of information.)-.15 E F0 2.5(2.6. Impr)87 316.8 R -.1 +(ove)-.18 G 2.5(dB).1 G(IND Support)158.01 316.8 Q F1 .262 +(The BIND support, particularly for MX records, had a number of anno)127 333 R +.261(ying `)-.1 F(`features')-.74 E 2.761('w)-.74 G(hich)486.78 333 Q(ha)102 +345 Q 1.212 -.15(ve b)-.2 H .912(een remo).15 F -.15(ve)-.15 G 3.412(di).15 G +3.412(nt)187.116 345 S .912(his release.)198.308 345 R .912(In particular)5.912 +F 3.412(,t)-.4 G .912(hese more tightly bind \(pun intended\) the name)307.916 +345 R(serv)102 357 Q(er to sendmail, so that the name serv)-.15 E +(er resolution rules are incorporated directly into sendmail.)-.15 E .688 +(The major change has been that the $[ ... $] operator didn')127 373.2 R 3.188 +(tf)-.18 G .688(ully qualify names that were in)376.41 373.2 R +(DNS as A or MX records.)102 385.2 Q -1.11(Ve)5 G +(rsion 8 does this quali\214cation.)1.11 E .429(This has pro)127 401.4 R -.15 +(ve)-.15 G 2.929(nt).15 G 2.929(ob)197.147 401.4 S 2.929(ea)210.076 401.4 S +2.929(na)221.885 401.4 S(nno)234.254 401.4 Q .43 +(yance in Sun shops, who often still run without BIND support.)-.1 F(Ho)102 +413.4 Q(we)-.25 E -.15(ve)-.25 G 1.001 -.4(r, i).15 H 2.701(ti).4 G 2.701(sr) +153.842 413.4 S .201 +(eally critical that this be supported, since MX records are mandatory)163.763 +413.4 R 5.2(.I)-.65 G 2.7(nS)450.26 413.4 S .2(unOS you)463.52 413.4 R .101 +(can choose either MX support or NIS support, b)102 425.4 R .101(ut not both.) +-.2 F .101(This is \214x)5.101 F .101(ed in Solaris, and some)-.15 F/F2 10 +/Times-Italic@0 SF(send-)2.602 E(mail)102 437.4 Q F1(support to allo)2.5 E 2.5 +(wt)-.25 G(his in SunOS should be forthcoming in a future release.)192.31 437.4 +Q F0 2.5(2.7. K)87 461.4 R(ey)-.25 E(ed Files)-.1 E F1 .242(Generalized k)127 +477.6 R -.15(ey)-.1 G .242(ed \214les is an idea tak).15 F .241 +(en directly from ID)-.1 F 2.741(As)-.4 G .241 +(endmail \(albeit with a completely)368.606 477.6 R(dif)102 489.6 Q +(ferent implementation\).)-.25 E(The)5 E 2.5(yc)-.15 G(an be useful on lar) +239.63 489.6 Q(ge sites.)-.18 E -1.11(Ve)127 505.8 S +(rsion 8 includes the follo)1.11 E(wing b)-.25 E(uilt-in map classes:)-.2 E +33.72(dbm Support)102 522 R(for the ndbm\(3\) library)2.5 E(.)-.65 E 33.17 +(hash Support)102 538.2 R 1.229(for the `)3.729 F(`Hash')-.74 E 3.729('t)-.74 G +1.229(ype from the ne)261.636 538.2 R 3.729(wB)-.25 G(erk)345.732 538.2 Q(ele) +-.1 E 3.729(yd)-.15 G 1.229(b\(3\) library)383.641 538.2 R 6.23(.t)-.65 G 1.23 +(his library pro-)441.55 538.2 R 4.094(vides substantially better database sup\ +port than ndbm\(3\), including in-memory)156 550.2 R +(caching, arbitrarily long k)156 562.2 Q -.15(ey)-.1 G 2.5(sa).15 G(nd v)279.89 +562.2 Q(alues, and better disk utilization.)-.25 E 31.51(btree Support)102 +578.4 R .547(for the `)3.047 F(`B-T)-.74 E(ree')-.35 E 3.047('t)-.74 G .547 +(ype from the ne)266.328 578.4 R 3.048(wB)-.25 G(erk)347.698 578.4 Q(ele)-.1 E +3.048(yd)-.15 G .548(b\(3\) library)384.926 578.4 R 5.548(.B)-.65 G(-T)445.362 +578.4 Q .548(rees pro)-.35 F(vide)-.15 E .521(better clustering than Hashed \ +\214les if you are fetching lots of records that ha)156 590.4 R .821 -.15(ve s) +-.2 H(imilar).15 E -.1(ke)156 602.4 S(ys, such as searching a dictionary for w) +-.05 E(ords be)-.1 E(ginning with `)-.15 E(`detr')-.74 E('.)-.74 E 39.83 +(nis Support)102 618.6 R(for NIS \(a.k.a. YP\) maps.)2.5 E +(NIS+ is not supported in this v)5 E(ersion.)-.15 E 34.83(host Support)102 +634.8 R(for DNS lookups.)2.5 E 19.84(dequote A)102 651 R -.74(``)2.642 G +(pseudo-map').74 E 2.642('\()-.74 G .142(that is, once that does not ha)232.554 +651 R .442 -.15(ve a)-.2 H .442 -.15(ny ex).15 H .142(ternal data\) that allo) +.15 F .142(ws a con-)-.25 F .099 +(\214guration \214le to break apart a quoted string in the address.)156 663 R +.098(This is necessary primarily)5.098 F .726 +(for DECnet addresses, which often ha)156 675 R 1.026 -.15(ve q)-.2 H .726 +(uoted addresses that need to be unwrapped).15 F(on g)156 687 Q(ate)-.05 E -.1 +(wa)-.25 G(ys.).1 E EP +%%Page: 5 5 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(5)499 60 Q +2.5(2.8. Multi-W)87 96 R(ord Classes & Macr)-.75 E(os in Classes)-.18 E/F1 10 +/Times-Roman@0 SF(Classes can no)127 112.2 Q 2.5(wb)-.25 G 2.5(em)200.35 112.2 +S(ultiple w)215.07 112.2 Q 2.5(ords. F)-.1 F(or e)-.15 E(xample,)-.15 E +(CShofmann.CS.Berk)142 128.4 Q(ele)-.1 E -.65(y.)-.15 G(EDU).65 E(allo)102 +144.6 Q 2.395(ws you to match the entire string `)-.25 F(`hofmann.CS.Berk)-.74 +E(ele)-.1 E -.65(y.)-.15 G(EDU').65 E 4.894('u)-.74 G 2.394 +(sing the single construct)399.878 144.6 R -.74(``)102 156.6 S($=S').74 E('.) +-.74 E(Class de\214nitions are no)127 172.8 Q 2.5(wa)-.25 G(llo)234.52 172.8 Q +(wed to include macros \212 for e)-.25 E(xample:)-.15 E(Cw$k)142 189 Q(is le) +102 205.2 Q -.05(ga)-.15 G(l.).05 E F0 2.5(2.9. IDENT)87 229.2 R(Pr)2.5 E +(otocol Support)-.18 E F1 .633 +(The IDENT protocol as de\214ned in RFC 1413 [RFC1413] is supported.)127 245.4 +R(Ho)5.633 E(we)-.25 E -.15(ve)-.25 G 1.433 -.4(r, m).15 H(an).4 E 3.134(ys) +-.15 G(ys-)491.78 245.4 Q .909(tems ha)102 257.4 R 1.209 -.15(ve a T)-.2 H .909 +(CP/IP b).15 F .908 +(ug that renders this useless, and the feature must be turned of)-.2 F 3.408 +(f. Roughly)-.25 F 3.408(,i)-.65 G(f)500.67 257.4 Q 8.538 +(one of these system recei)102 269.4 R -.15(ve)-.25 G 11.038(sa\231).15 G 8.539 +(No route to host\232 message \(ICMP message)280.568 269.4 R(ICMP_UNREA)102 +281.4 Q .829(CH_HOST\) on)-.4 F/F2 10/Times-Italic@0 SF(any)3.329 E F1 .828 +(connection, all connections to that host are closed.)3.329 F .828 +(Some \214re-)5.828 F -.1(wa)102 293.4 S .087 +(lls return this error if you try to connect to the IDENT port, so you can').1 +F 2.587(tr)-.18 G(ecei)408.889 293.4 Q .387 -.15(ve e)-.25 H .087 +(mail from these).15 F 1.712(hosts on these systems.)102 305.4 R(It')6.712 E +4.212(sp)-.55 G 1.712(ossible that if the \214re)228.62 305.4 R -.1(wa)-.25 G +1.712(ll used a more speci\214c message \(such as).1 F(ICMP_UNREA)102 317.4 Q +(CH_PR)-.4 E -1.88 -.4(OT O)-.4 H 72.325(COL, ICMP_UNREA).4 F(CH_POR)-.4 E +74.825(To)-.6 G(r)500.67 317.4 Q(ICMP_UNREA)102 329.4 Q(CH_NET_PR)-.4 E +(OHIB\) it w)-.4 E(ould w)-.1 E(ork, b)-.1 E(ut this hasn')-.2 E 2.5(tb)-.18 G +(een v)375.62 329.4 Q(eri\214ed.)-.15 E .678(IDENT protocol support cannot be \ +used on 4.3BSD, Apollo DomainOS, Apple A/UX, Con-)127 345.6 R -.15(vex)102 +357.6 S .949(OS, Data General DG/UX, HP-UX, Sequent Dynix, or Ultrix 4.x, x).15 +F/F3 10/Symbol SF<a3>3.449 E F1 3.449(3. It)3.449 F .949(seems to w)3.449 F +.949(ork on)-.1 F +(4.4BSD, IBM AIX 3.x, OSF/1, SGI IRIX, Solaris, SunOS, and Ultrix 4.4.)102 +369.6 Q F0 2.5(2.10. Separate)87 393.6 R(En)2.5 E -.1(ve)-.4 G(lope/Header Pr) +.1 E(ocessing)-.18 E F1 .854 +(Since the From: line is passed in separately from the en)127 409.8 R -.15(ve) +-.4 G .854(lope sender).15 F 3.354(,t)-.4 G .854(hese ha)420.978 409.8 R 1.154 +-.15(ve b)-.2 H .854(oth been).15 F .427 +(made visible; the $g macro is set to the en)102 421.8 R -.15(ve)-.4 G .428 +(lope sender during processing of mailer ar).15 F .428(gument v)-.18 F(ec-)-.15 +E(tors and the header sender during processing of headers.)102 433.8 Q .085 +(It is also possible to specify separate per)127 450 R .085(-mailer en)-.2 F +-.15(ve)-.4 G .084(lope and header processing.).15 F .084(The Sender)5.084 F(-) +-.2 E -.55(RW)102 462 S 1.085(Set and RecipientR).55 F 1.085(Wset ar)-.55 F +1.085(guments for mailers can be speci\214ed as `)-.18 F(`en)-.74 E -.15(ve)-.4 +G(lope/header').15 E 3.585('t)-.74 G 3.585(og)478.595 462 S -2.15 -.25(iv e) +492.18 462 T(dif)102 474 Q(ferent re)-.25 E(writings for en)-.25 E -.15(ve)-.4 +G(lope v).15 E(ersus header addresses.)-.15 E F0 2.5(2.11. Owner)87 498 R +(-List Pr)-.37 E(opagates to En)-.18 E -.1(ve)-.4 G(lope).1 E F1 1.168 +(When an alias has an associated o)127 514.2 R(wner)-.25 E 1.168 +(-list name, that alias is used to change the en)-.2 F -.15(ve)-.4 G(lope).15 E +(sender address.)102 526.2 Q(This will cause do)5 E +(wnstream errors to be returned to that o)-.25 E(wner)-.25 E(.)-.55 E 1.813 +(Some people \214nd this confusing because the en)127 542.4 R -.15(ve)-.4 G +1.813(lope sender is what appears in the \214rst).15 F -.74(``)102 554.4 S +(From_').74 E 3.127('l)-.74 G .627(ine in UNIX messages \(that is, the line be) +146.417 554.4 R .627(ginning `)-.15 F(`From<space>')-.74 E 3.127('i)-.74 G .627 +(nstead of `)424.797 554.4 R(`From:')-.74 E(';)-.74 E .502 +(the latter is the header from, which)102 566.4 R F2(does)3.002 E F1 .503 +(indicate the sender of the message\).)3.002 F .503(In pre)5.503 F .503 +(vious v)-.25 F(ersions,)-.15 E F2(sendmail)102 578.4 Q F1 .057(has tried to a) +2.557 F -.2(vo)-.2 G .057(id changing the en).2 F -.15(ve)-.4 G .056 +(lope sender for back compatibility with UNIX con).15 F -.15(ve)-.4 G(n-).15 E +.177(tion; at this point that back compatibility is creating too man)102 590.4 +R 2.678(yp)-.15 G .178(roblems, and it is necessary to mo)357.972 590.4 R -.15 +(ve)-.15 G(forw)102 602.4 Q(ard into the 1980s.)-.1 E F0 2.5(2.12. Command)87 +626.4 R(Line Flags)2.5 E F1(The)127 642.6 Q F0<ad42>2.5 E F1 +(\215ag has been added to pass in body type information.)2.5 E(The)127 658.8 Q +F0<ad70>3.057 E F1 .557 +(\215ag has been added to pass in protocol information that w)3.057 F .557 +(as pre)-.1 F .556(viously passed in by)-.25 F(de\214ning the)102 670.8 Q F0 +($r)2.5 E F1(and)2.5 E F0($s)2.5 E F1(macros.)2.5 E(The)127 687 Q F0<ad58>2.6 E +F1 .1(\215ag has been added to allo)2.6 F 2.6(wl)-.25 G .1 +(ogging of all protocol in and out of sendmail for deb)279.89 687 R(ug-)-.2 E +2.732(ging. Y)102 699 R .232(ou can set \231\255X \214lename\232 and a complet\ +e transcript will be logged in that \214le.)-1.1 F .231(This gets big)5.231 F +-.1(fa)102 711 S(st: the option is only for deb).1 E(ugging.)-.2 E EP +%%Page: 6 6 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 294.65(6C)72 60 S(hanges in Sendmail V)378.87 60 Q +(ersion 8)-1 E/F1 10/Times-Roman@0 SF(The)127 96 Q F0<ad71>4.006 E F1 1.507(\ +\215ag can limit limit a queue run to speci\214c recipients, senders, or queue\ + ids using)4.006 F +(\255qRsubstring, \255qSsubstring, or \255qIsubstring respecti)102 108 Q -.15 +(ve)-.25 G(ly).15 E(.)-.65 E F0 2.5(2.13. New)87 132 R(Con\214guration Line T) +2.5 E(ypes)-.74 E F1 .674(The `T' \(T)127 148.2 R .674 +(rusted users\) con\214guration line has been deleted.)-.35 F .674 +(It will still be accepted b)5.674 F .674(ut will)-.2 F(be ignored.)102 160.2 Q +(The `K' line has been added to declare database maps.)127 176.4 Q +(The `V' line has been added to declare the con\214guration v)127 192.6 Q +(ersion le)-.15 E -.15(ve)-.25 G(l.).15 E(The `M' \(mailer\) line tak)127 208.8 +Q(es a D= \214eld to specify e)-.1 E -.15(xe)-.15 G(cution directory).15 E(.) +-.65 E F0 2.5(2.14. New)87 232.8 R(and Extended Options)2.5 E F1(Se)127 249 Q +-.15(ve)-.25 G .9(ral ne).15 F 3.4(wo)-.25 G .9(ptions ha)184.8 249 R 1.2 -.15 +(ve b)-.2 H .9(een added, man).15 F 3.4(yt)-.15 G 3.4(os)314.89 249 S .9 +(upport ne)327.18 249 R 3.4(wf)-.25 G .9(eatures, others to allo)379.83 249 R +3.4(wt)-.25 G(uning)481.22 249 Q(that w)102 261 Q(as pre)-.1 E(viously a)-.25 E +-.25(va)-.2 G(ilable only by recompiling.).25 E(Brie\215y:)5 E 28.78(AT)102 +277.2 S .099(he alias \214le speci\214cation can no)144.11 277.2 R 2.599(wb) +-.25 G 2.599(eal)286.654 277.2 S .099(ist of alias \214les.)303.512 277.2 R +.098(Also, the con\214guration can spec-)5.099 F(ify a class of \214le.)138 +289.2 Q -.15(Fo)5 G 2.5(re).15 G(xample, to search the NIS aliases, use \231O) +232.13 289.2 Q(Anis:mail.aliases\232.)-.35 E 31(bI)102 305.4 S +(nsist on a minimum number of disk blocks.)141.33 305.4 Q 29.33(CD)102 321.6 S +(eli)145.22 321.6 Q -.15(ve)-.25 G .24(ry checkpoint interv).15 F 2.74 +(al. Checkpoint)-.25 F .24(the queue \(to a)2.74 F -.2(vo)-.2 G .24 +(id duplicate deli).2 F -.15(ve)-.25 G .24(ries\) e).15 F -.15(ve)-.25 G .24 +(ry C).15 F(addresses.)138 333.6 Q 29.89(ED)102 349.8 S(ef)145.22 349.8 Q .712 +(ault error message.)-.1 F .711 +(This message \(or the contents of the indicated \214le\) are prepended)5.712 F +(to error messages.)138 361.8 Q 28.78(GE)102 378 S .785(nable GECOS matching.) +144.11 378 R .785(If you can')5.785 F 3.285<748c>-.18 G .786 +(nd a local user name and this option is enabled,)307.51 378 R .59 +(do a sequential scan of the passwd \214le to match ag)138 390 R .589 +(ainst full names.)-.05 F(Pre)5.589 E .589(viously a compile)-.25 F(option.)138 +402 Q 31(hM)102 418.2 S(aximum hop count.)146.89 418.2 Q(Pre)5 E +(viously this w)-.25 E(as compiled in.)-.1 E 32.67(IT)102 434.4 S +(his option has been e)144.11 434.4 Q(xtended to allo)-.15 E 2.5(ws)-.25 G +(etting of resolv)300.64 434.4 Q(er parameters.)-.15 E 33.22(jS)102 450.6 S +(end errors in MIME-encapsulated format.)143.56 450.6 Q 32.11(JF)102 466.8 S +(orw)143.41 466.8 Q(ard \214le path.)-.1 E(Where to search for .forw)5 E +(ard \214les \212 def)-.1 E(aults to $HOME/.forw)-.1 E(ard.)-.1 E 31(kC)102 483 +S .05(onnection cache size.)144.67 483 R .05 +(The total number of connections that will be k)5.05 F .05(ept open at an)-.1 F +2.55(yt)-.15 G(ime.)486.5 483 Q 28.78(KC)102 499.2 S 1.395 +(onnection cache lifetime.)144.67 499.2 R 1.395(The amount of time an)6.395 F +3.895(yc)-.15 G 1.394(onnection will be permitted to sit)364.53 499.2 R(idle.) +138 511.2 Q 33.22(lE)102 527.4 S .333(nable Errors-T)144.11 527.4 R .333 +(o: header)-.8 F 5.334(.T)-.55 G .334 +(hese headers violate RFC 1123; this option is included to pro-)252.89 527.4 R +(vide back compatibility with old v)138 539.4 Q(ersions of sendmail.)-.15 E +28.78(OI)102 555.6 S(ncoming daemon options \(e.g., use alternate SMTP port\).) +141.33 555.6 Q 31(pP)102 571.8 S(ri)143.56 571.8 Q -.25(va)-.25 G .3 -.15(cy o) +.25 H 2.5(ptions. These).15 F(can be used to mak)2.5 E 2.5(ey)-.1 G +(our SMTP serv)322.22 571.8 Q(er less friendly)-.15 E(.)-.65 E 32.67(rT)102 588 +S .67(his option has been e)144.11 588 R .67(xtended to allo)-.15 F 3.17<778c> +-.25 G .67(ner grained control o)307 588 R -.15(ve)-.15 G 3.17(rt).15 G 3.17 +(imeouts. F)411.02 588 R .67(or e)-.15 F(xample,)-.15 E +(you can set the timeout for SMTP commands indi)138 600 Q(vidually)-.25 E(.) +-.65 E 29.33(RD)102 616.2 S(on')145.22 616.2 Q 11.797(tp)-.18 G 9.297 +(rune route-addrs.)177.947 616.2 R(Normally)269.851 616.2 Q 11.797(,i)-.65 G +11.797(fv)324.608 616.2 S 9.297(ersion 8 sees an address lik)344.585 616.2 R(e) +-.1 E 1.256("<@hostA,@hostB:user@hostC>, sendmail will try to strip of)138 +628.2 R 3.755(fa)-.25 G 3.755(sm)406.48 628.2 S 1.255(uch as it can \(up to) +421.905 628.2 R(user@hostC\) as suggested by RFC 1123.)138 640.2 Q +(This option disables that beha)5 E(viour)-.2 E(.)-.55 E 29.89(TT)102 656.4 S +1.485(he \231Return T)144.11 656.4 R 3.985(oS)-.8 G 1.485 +(ender\232 timeout has been e)213.035 656.4 R 1.485(xtended to allo)-.15 F +3.986(ws)-.25 G 1.486(peci\214cation of a w)399.942 656.4 R(arning)-.1 E .789 +(message interv)138 668.4 R .789 +(al, typically something on the order of four hours.)-.25 F .788 +(If a message cannot be)5.788 F(deli)138 680.4 Q -.15(ve)-.25 G 1.245 +(red in that interv).15 F 1.245(al, a w)-.25 F 1.245 +(arning message is sent back to the sender b)-.1 F 1.246(ut the message)-.2 F +(continues to be tried.)138 692.4 Q 28.78(UU)102 708.6 S(ser database spec.) +145.22 708.6 Q(This is still e)5 E(xperimental.)-.15 E EP +%%Page: 7 7 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(7)499 60 Q +/F1 10/Times-Roman@0 SF 28.78(VF)102 96 S .758(allback `)143.41 96 R(`MX')-.74 +E 3.258('h)-.74 G 3.258(ost. This)211.756 96 R .757 +(can be thought of as an MX host that applies to all addresses)3.258 F +(that has a v)138 108 Q(ery high preference v)-.15 E +(alue \(that is, use it only if e)-.25 E -.15(ve)-.25 G(rything else f).15 E +(ails\).)-.1 E 28.78(wI)102 124.2 S 3.066(fs)141.33 124.2 S .566(et, assume th\ +at if you are the best MX host for a host, you should send directly to that) +151.616 124.2 R 3.213(host. This)138 136.2 R .713 +(is intended for compatibility with UIUC sendmail, and may ha)3.213 F 1.013 +-.15(ve s)-.2 H .712(ome use on).15 F(\214re)138 148.2 Q -.1(wa)-.25 G(lls.).1 +E 31(7D)102 164.4 S 2.758(on)145.22 164.4 S .258(ot run eight bit clean.) +157.978 164.4 R -.7(Te)5.258 G(chnically).7 E 2.758(,y)-.65 G .258(ou ha) +305.656 164.4 R .558 -.15(ve t)-.2 H 2.758(oa).15 G .259 +(ssert this option to be RFC 821 com-)354.68 164.4 R(patible.)138 176.4 Q F0 +2.5(2.15. New)87 200.4 R(Mailer De\214nitions)2.5 E F1 21.75(L= Set)102 216.6 R +.93(the allo)3.43 F -.1(wa)-.25 G .93(ble line length.).1 F .93 +(In V5, the L mailer \215ag implied a line length limit of 990)5.93 F +(characters; this is no)138 228.6 Q 2.5(ws)-.25 G(ettable to an arbitrary v) +233.29 228.6 Q(alue.)-.25 E 17.86(F=a T)102 244.8 R(ry to use ESMTP)-.35 E 5 +(.I)-1.11 G 2.5(tw)222.65 244.8 S(ill f)235.15 244.8 Q +(all back to SMTP if the initial EHLO pack)-.1 E(et is rejected.)-.1 E 17.3 +(F=b Ensure)102 261 R 2.5(ab)2.5 G(lank line at the end of messages.)180.21 261 +Q(Useful on the *\214le* mailer)5 E(.)-.55 E 17.86(F=c Strip)102 277.2 R .68(a\ +ll comments from addresses; this should only be used as a last resort when dea\ +ling)3.18 F(with crank)138 289.2 Q 2.5(ym)-.15 G(ailers.)195.62 289.2 Q 17.3 +(F=g Ne)102 305.4 R -.15(ve)-.25 G 2.88(ru).15 G .38 +(se the null sender as the en)169.91 305.4 R -.15(ve)-.4 G .379(lope sender).15 +F 2.879(,e)-.4 G -.15(ve)343.645 305.4 S 2.879(nw).15 G .379(hen running SMTP) +368.034 305.4 R 5.379(.T)-1.11 G .379(his violates)458.341 305.4 R(RFC 1123.) +138 317.4 Q 17.3(F=7 Strip)102 333.6 R(all output to this mailer to 7 bits.)2.5 +E 16.19(F=L Used)102 349.8 R .198 +(to set the line limit to 990 bytes for SMTP compatibility)2.697 F 5.198(.I) +-.65 G 2.698(tn)398.622 349.8 S .698 -.25(ow d)409.1 349.8 T .198 +(oes that only if the).25 F(L= k)138 361.8 Q -.15(ey)-.1 G +(letter is not speci\214ed.).15 E +(This \215ag is obsolete and should not be used.)5 E F0 2.5(2.16. New)87 385.8 +R(or Changed Pr)2.5 E(e-De\214ned Macr)-.18 E(os)-.18 E F1 23.5($k UUCP)102 402 +R(node name from uname\(2\).)2.5 E 20.72($m Domain)102 418.2 R +(part of our full hostname.)2.5 E 23.5($_ RFC)102 434.4 R(1413-pro)2.5 E +(vided sender address.)-.15 E 21.28($w Pre)102 450.6 R .148(viously w)-.25 F +.148(as sometimes the full domain name, sometimes just the \214rst w)-.1 F +2.647(ord. No)-.1 F 2.647(wg)-.25 G(uar)488.1 450.6 Q(-)-.2 E +(anteed to be the \214rst w)138 462.6 Q +(ord of the domain name \(i.e., the host name\).)-.1 E 25.72($j Pre)102 478.8 R +.193(viously had to be de\214ned \212 it is no)-.25 F 2.693(wp)-.25 G .194 +(rede\214ned to be the full domain name, if that can)310.067 478.8 R +(be determined.)138 490.8 Q(That is, it is equi)5 E -.25(va)-.25 G(lent to $w) +.25 E(.$m.)-.65 E F0 2.5(2.17. New)87 514.8 R(and Changed Classes)2.5 E F1 +17.86($=k Initialized)102 531 R(to contain $k.)2.5 E 15.64($=w No)102 547.2 R +3.069(wi)-.25 G .569 +(ncludes \231[1.2.3.4]\232 \(where 1.2.3.4 is your IP address\) to allo)163.039 +547.2 R 3.068(wt)-.25 G .568(he con\214guration \214le)422.314 547.2 R +(to recognize your o)138 559.2 Q(wn IP address.)-.25 E F0 2.5(2.18. New)87 +583.2 R(Rewriting T)2.5 E(ok)-.92 E(ens)-.1 E F1(The)127 599.4 Q F0($&)3.25 E +F1 .75(construct has been adopted from ID)3.25 F 3.25(At)-.4 G 3.25(od)322 +599.4 S .75(efer macro e)335.25 599.4 R -.25(va)-.25 G 3.25(luation. Normally) +.25 F 3.25(,m)-.65 G(acros)482.9 599.4 Q .476 +(in rulesets are bound when the rule is \214rst parsed during startup.)102 +611.4 R .476(Some macros change during pro-)5.476 F .046 +(cessing and are uninteresting during startup.)102 623.4 R(Ho)5.046 E(we)-.25 E +-.15(ve)-.25 G .846 -.4(r, t).15 H .047 +(hat macro can be referenced using \231$&x\232 to).4 F(defer the e)102 635.4 Q +-.25(va)-.25 G(ulation of $x until the rule is processed.).25 E(The tok)127 +651.6 Q(ens)-.1 E F0($\()2.5 E F1(and)2.5 E F0($\))2.5 E F1(ha)2.5 E .3 -.15 +(ve b)-.2 H(een added to allo).15 E 2.5(ws)-.25 G(peci\214cation of map re) +319.59 651.6 Q(writing.)-.25 E -1.11(Ve)127 667.8 S 1.499(rsion 8 allo)1.11 F +(ws)-.25 E F0($@)3.999 E F1 1.499 +(on the Left Hand Side of an `R' line to match zero tok)3.999 F 3.998 +(ens. This)-.1 F(is)3.998 E(intended to be used to match the null input.)102 +679.8 Q EP +%%Page: 8 8 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 294.65(8C)72 60 S(hanges in Sendmail V)378.87 60 Q +(ersion 8)-1 E 2.5(2.19. Bigger)87 96 R(Defaults)2.5 E/F1 10/Times-Roman@0 SF +-1.11(Ve)127 112.2 S 1.283(rsion 8 allo)1.11 F 1.284 +(ws up to 100 rulesets instead of 30.)-.25 F 1.284 +(It is recommended that rulesets 0\2559 be)6.284 F(reserv)102 124.2 Q +(ed for sendmail')-.15 E 2.5(sd)-.55 G(edicated use in future releases.)202.66 +124.2 Q(The total number of MX records that can be used has been raised to 20.) +127 140.4 Q .335(The number of queued messages that can be handled at one time\ + has been raised from 600 to)127 156.6 R(1000.)102 168.6 Q F0 2.5(2.20. Differ) +87 192.6 R(ent Default T)-.18 E(uning P)-.92 E(arameters)-.1 E F1 -1.11(Ve)127 +208.8 S .8(rsion 8 has changed the def)1.11 F .8 +(ault parameters for tuning queue costs to mak)-.1 F 3.3(et)-.1 G .8 +(he number of)449.08 208.8 R .712(recipients more important than the size of t\ +he message \(for small messages\).)102 220.8 R .712(This is reasonable if)5.712 +F(you are connected with reasonably f)102 232.8 Q(ast links.)-.1 E F0 2.5 +(2.21. A)87 256.8 R(uto-Quoting in Addr)-.5 E(esses)-.18 E F1(Pre)127 273 Q +(viously)-.25 E 3.2(,t)-.65 G .701(he `)177.36 273 R .701 +(`Full Name <email address>')-.74 F 3.201('s)-.74 G .701(yntax w)322.025 273 R +.701(ould generate incorrect protocol out-)-.1 F .006(put if `)102 285 R .006 +(`Full Name')-.74 F 2.506('h)-.74 G .006(ad special characters such as dot.) +187.754 285 R .005(This v)5.006 F .005(ersion puts quotes around such names.) +-.15 F F0 2.5(2.22. Symbolic)87 309 R(Names On Err)2.5 E(or Mailer)-.18 E F1 +(Se)127 325.2 Q -.15(ve)-.25 G(ral names ha).15 E .3 -.15(ve b)-.2 H(een b).15 +E(uilt in to the $@ portion of the $#error mailer)-.2 E 5(.F)-.55 G(or e)428.96 +325.2 Q(xample:)-.15 E($#error $@NOHOST $: Host unkno)142 341.4 Q(wn)-.25 E +(Prints the indicated message and sets the e)102 357.6 Q(xit status of)-.15 E +/F2 10/Times-Italic@0 SF(sendmail)2.5 E F1(to)2.5 E/F3 9/Times-Roman@0 SF +(EX_NOHOST)2.5 E F1(.)A F0 2.5(2.23. New)87 381.6 R(Built-In Mailers)2.5 E F1 +-1 -.8(Tw o)127 397.8 T(ne)3.901 E 3.101(wm)-.25 G .601(ailers, *\214le* and *\ +include*, are included to de\214ne options when mailing to a \214le)174.822 +397.8 R(or a :include: \214le respecti)102 409.8 Q -.15(ve)-.25 G(ly).15 E 5 +(.P)-.65 G(re)232.88 409.8 Q(viously these were o)-.25 E -.15(ve)-.15 G +(rloaded on the local mailer).15 E(.)-.55 E F0 2.5(2.24. SMTP)87 433.8 R +(VRFY Doesn't Expand)2.5 E F1(Pre)127 450 Q 1.438(vious v)-.25 F 1.438 +(ersions of sendmail treated VRFY and EXPN the same.)-.15 F 1.437(In this v) +6.437 F 1.437(ersion, VRFY)-.15 F(doesn')102 462 Q 2.5(te)-.18 G +(xpand aliases or follo)138.05 462 Q 2.5(w.)-.25 G(forw)235.84 462 Q +(ard \214les.)-.1 E .663(As an optimization, if you run with your def)127 478.2 +R .664(ault deli)-.1 F -.15(ve)-.25 G .664(ry mode being queue-only).15 F 3.164 +(,t)-.65 G .664(he RCPT)466.386 478.2 R 1.09 +(command will also not chase aliases and .forw)102 490.2 R 1.09(ard \214les.) +-.1 F 1.09(It will chase them when it processes the)6.09 F 2.5(queue. This)102 +502.2 R(speeds up RCPT processing.)2.5 E F0 2.5(2.25. [IPC])87 526.2 R +(Mailers Allo)2.5 E 2.5(wM)-.1 G(ultiple Hosts)210.49 526.2 Q F1 .099 +(When an address resolv)127 542.4 R .099(es to a mailer that has `)-.15 F +(`[IPC]')-.74 E 2.599('a)-.74 G 2.6(si)353.52 542.4 S .1(ts `)362.79 542.4 R +(`P)-.74 E(ath')-.15 E .1(', the $@ part \(host name\))-.74 F .138 +(can be a colon-separated list of hosts instead of a single hostname.)102 554.4 +R .137(This asks sendmail to search the)5.137 F .16 +(list for the \214rst entry that is a)102 566.4 R -.25(va)-.2 G .16(ilable e) +.25 F .161(xactly as though it were an MX record.)-.15 F .161 +(The intent is to route)5.161 F .738(internal traf)102 578.4 R .738 +(\214c through internal netw)-.25 F .738 +(orks without publishing an MX record to the net.)-.1 F .737(MX e)5.737 F +(xpan-)-.15 E(sion is still done on the indi)102 590.4 Q(vidual items.)-.25 E +F0 2.5(2.26. Aliases)87 614.4 R(Extended)2.5 E F1 .298 +(The implementation has been mer)127 630.6 R .298(ged with maps.)-.18 F .299 +(Among other things, this supports multiple)5.298 F +(alias \214les and NIS-based aliases.)102 642.6 Q -.15(Fo)5 G 2.5(re).15 G +(xample:)258.34 642.6 Q -.35(OA)142 658.8 S(/etc/aliases,nis:mail.aliases).35 E +(will search \214rst the local database \231/etc/aliases\232 follo)102 675 Q +(wed by the NIS map)-.25 E EP +%%Page: 9 9 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(9)499 60 Q +2.5(2.27. P)87 96 R(ortability and Security Enhancements)-.2 E/F1 10 +/Times-Roman@0 SF 2.5(An)127 112.2 S(umber of internal changes ha)141.72 112.2 +Q .3 -.15(ve b)-.2 H(een made to enhance portability).15 E(.)-.65 E(Se)127 +128.4 Q -.15(ve)-.25 G(ral \214x).15 E(es ha)-.15 E .3 -.15(ve b)-.2 H +(een made to increase the paranoia f).15 E(actor)-.1 E(.)-.55 E .46 +(In particular)127 144.6 R 2.96(,t)-.4 G .46(he permissions required for .forw) +184.45 144.6 R .46(ard and :include: \214les ha)-.1 F .76 -.15(ve b)-.2 H .46 +(een tightened up).15 F(considerably)102 156.6 Q 5.182(.V)-.65 G 2.683(5w) +167.352 156.6 S .183(ould pretty much read an)182.155 156.6 R 2.683<798c>-.15 G +.183(le it could get to as root, which e)295.96 156.6 R .183(xposed some secu-) +-.15 F 1.02(rity holes.)102 168.6 R 1.02 +(V8 insists that all directories leading up to the .forw)6.02 F 1.02 +(ard or :include: \214le be searchable)-.1 F .334 +(\("x" permission\) by the controlling user" \(de\214ned belo)102 180.6 R .335 +(w\), that the \214le itself be readable by the con-)-.25 F(trolling user)102 +192.6 Q 2.5(,a)-.4 G(nd that .forw)159.65 192.6 Q(ard \214les be o)-.1 E +(wned by the user who is being forw)-.25 E(arded to or root.)-.1 E .565 +(The "controlling user" is the user on whose behalf the mail is being deli)127 +208.8 R -.15(ve)-.25 G 3.065(red. F).15 F .565(or e)-.15 F(xample,)-.15 E .459 +(if you mail to "user1" then the controlling user for ~user1/.forw)102 220.8 R +.46(ard and an)-.1 F 2.96(ym)-.15 G .46(ailers in)416.94 220.8 R -.2(vo)-.4 G +-.1(ke).2 G 2.96(db).1 G 2.96(yt)481.04 220.8 S(hat)491.78 220.8 Q(.forw)102 +232.8 Q(ard \214le, including :include: \214les.)-.1 E(Pre)127 249 Q(viously) +-.25 E 2.816(,a)-.65 G -.15(ny)178.636 249 S .316 +(one who had a home directory could create a .forw).15 F .316(ard could forw) +-.1 F .316(ard to a pro-)-.1 F 2.965(gram. No)102 261 R 1.765 -.65(w, s)-.25 H +.466(endmail checks to mak).65 F 2.966(es)-.1 G .466(ure that the)262.934 261 R +2.966(yh)-.15 G -2.25 -.2(av e)321.672 261 T .466(an "appro)3.166 F -.15(ve) +-.15 G 2.966(ds).15 G .466(hell", that is, a shell listed)398.42 261 R +(in the /etc/shells \214le.)102 273 Q F0 2.5(2.28. Miscellaneous)87 297 R +(Fixes and Enhancements)2.5 E F1 4.03(An)127 313.2 S 1.53(umber of small b) +143.25 313.2 R 1.53(ugs ha)-.2 F 1.53(ving to do with things lik)-.2 F 4.03(eb) +-.1 G 1.53(ackslash-escaped quotes inside of)364.72 313.2 R(comments ha)102 +325.2 Q .3 -.15(ve b)-.2 H(een \214x).15 E(ed.)-.15 E 1.552(The \214x)127 341.4 +R 1.552(ed size limit on header lines \(such as \231T)-.15 F 1.553 +(o:\232 and \231Cc:\232\) has been eliminated; those)-.8 F -.2(bu)102 353.4 S +-.25(ff).2 G(ers are dynamically allocated no).25 E -.65(w.)-.25 G .289(Sendma\ +il writes a /etc/sendmail.pid \214le with the current process id and the curre\ +nt in)127 369.6 R -.2(vo)-.4 G(cation).2 E(\215ags.)102 381.6 Q -1 -.8(Tw o)127 +397.8 T .218 +(people using the same program \(e.g., submit\) are considered "dif)3.518 F +.219(ferent" so that duplicate)-.25 F .508(elimination doesn')102 409.8 R 3.008 +(td)-.18 G .508(elete one of them.)187.836 409.8 R -.15(Fo)5.508 G 3.008(re).15 +G .508(xample, tw)287.556 409.8 R 3.008(op)-.1 G .508(eople forw)345.412 409.8 +R .508(arding their email to |submit)-.1 F(will be treated as tw)102 421.8 Q +2.5(or)-.1 G(ecipients.)193.27 421.8 Q .721(The mailstats program prints maile\ +r names and gets the location of the sendmail.st \214le from)127 438 R +(/etc/sendmail.cf.)102 450 Q(Man)127 466.2 Q 2.5(ym)-.15 G(inor b)160.46 466.2 +Q(ugs ha)-.2 E .3 -.15(ve b)-.2 H(een \214x).15 E +(ed, such as handling of backslashes inside of quotes.)-.15 E 2.5(Ah)127 482.4 +S(ook has been added to allo)141.72 482.4 Q 2.5(wr)-.25 G -.25(ew)260.89 482.4 +S(riting of local addresses after aliasing.).25 E F0 2.5(3. FUTURE)72 506.4 R +-.1(WO)2.5 G(RK).1 E F1 1.719(The pre)112 522.6 R 1.719 +(vious section describes)-.25 F/F2 10/Times-Italic@0 SF(sendmail)4.219 E F1 +1.719(as of v)4.219 F 1.719(ersion 8.6.6.)-.15 F 1.718 +(There is still much to be done.)6.719 F(Some high points are described belo)87 +534.6 Q 3.8 -.65(w. T)-.25 H(his list is by no means e).65 E(xhausti)-.15 E +-.15(ve)-.25 G(.).15 E F0 2.5(3.1. Full)87 558.6 R(MIME Support)2.5 E F1 +(Currently)127 574.8 Q F2(sendmail)3.305 E F1 .805(only supports se)3.305 F +-.15(ve)-.25 G 3.305(nb).15 G .805(it MIME messages.)297.005 574.8 R .806 +(Although it can pass eight bit)5.805 F .371(MIME messages, it cannot adv)102 +586.8 R .371(ertise that f)-.15 F .37 +(act because the standards say that the mail agent must be)-.1 F .26 +(able to do 8- to 7-bit con)102 598.8 R -.15(ve)-.4 G .26(rsion to ha).15 F +.561 -.15(ve f)-.2 H .261(ull 8-bit support.).15 F .261(This requires f)5.261 F +.261(ar more e)-.1 F(xtensi)-.15 E .561 -.15(ve m)-.25 H(odi\214-).15 E +(cation of the message body than is currently supported.)102 610.8 Q .464 +(The best w)127 627 R .464(ay to do this w)-.1 F .463 +(ould be to support the general concept of an e)-.1 F .463(xternal `)-.15 F +.463(`message \214l-)-.74 F(ter')102 639 Q 3.319('t)-.74 G .819 +(hat could do arbitrary modi\214cations of the message.)124.569 639 R .819 +(This w)5.819 F .82(ould allo)-.1 F 3.32(wM)-.25 G .82(IME con)427.37 639 R +-.15(ve)-.4 G .82(rsion as).15 F .63 +(well as such things as automatic encryption of messages sent o)102 651 R -.15 +(ve)-.15 G 3.129(re).15 G .629(xternal links.)379.264 651 R .629 +(This is probably)5.629 F(an e)102 663 Q(xtremely non-tri)-.15 E(vial change.) +-.25 E F0 2.5(3.2. Ser)87 687 R(vice Switch Abstraction)-.1 E F1 .369(Most mod\ +ern systems include some concept of a \231service switch\232 \212 for e)127 +703.2 R .37(xample, to look up)-.15 F .984 +(host names you can try DNS, NIS, NIS+, te)102 715.2 R .984 +(xt tables, NetInfo, or other services in some arbitrary)-.15 F EP +%%Page: 10 10 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 287.15(10 Changes)72 60 R(in Sendmail V)2.5 E(ersion 8) +-1 E/F1 10/Times-Roman@0 SF(order)102 96 Q 5.174(.T)-.55 G .174 +(his is currently v)136.334 96 R .174(ery clumsy in)-.15 F/F2 10/Times-Italic@0 +SF(sendmail)2.674 E F1 2.674(,w)C .174 +(ith only limited control of the services pro)309.612 96 R(vided.)-.15 E F0 2.5 +(3.3. Mor)87 120 R 2.5(eC)-.18 G(ontr)139.86 120 Q(ol of Local Addr)-.18 E +(esses)-.18 E F1 .943(Currently some addresses are declared as \231local\232 a\ +nd are handled specially \212 for e)127 136.2 R(xample,)-.15 E(the)102 148.2 Q +3.455(ym)-.15 G .955(ay ha)130.305 148.2 R 1.255 -.15(ve .)-.2 H(forw).15 E +.956(ard \214les, may be translated into program calls or \214le deli)-.1 F +-.15(ve)-.25 G .956(ries, and so forth.).15 F .311(These should be brok)102 +160.2 R .311(en out into separate \215ags to allo)-.1 F 2.811(wt)-.25 G .31 +(he local system administrator to ha)330.29 160.2 R .61 -.15(ve m)-.2 H(ore).15 +E(\214ne-grained control o)102 172.2 Q -.15(ve)-.15 G 2.5(ro).15 G(perations.) +208.62 172.2 Q F0 2.5(3.4. Mor)87 196.2 R 2.5(eR)-.18 G(un-T)139.86 196.2 Q +(ime Con\214guration Options)-.18 E F1 .016(There are man)127 212.4 R 2.516(yo) +-.15 G .016(ptions that are con\214gured at compile time, such as the method o\ +f \214le locking)197.148 212.4 R .719 +(and the use of the IDENT protocol [RFC1413].)102 224.4 R .719 +(These should be transfered to run time by adding)5.719 F(ne)102 236.4 Q 2.5 +(wo)-.25 G(ptions.)125.91 236.4 Q(Similarly)127 252.6 Q 3.413(,s)-.65 G .913 +(ome options are currently o)173.383 252.6 R -.15(ve)-.15 G .913 +(rloaded, that is, a single option controls more than).15 F(one thing.)102 +264.6 Q(These should probably be brok)5 E(en out into separate options.)-.1 E +(This implies that options will change from single characters to w)127 280.8 Q +(ords.)-.1 E F0 2.5(3.5. Mor)87 304.8 R 2.5(eC)-.18 G(on\214guration Contr) +139.86 304.8 Q(ol Ov)-.18 E(er Err)-.1 E(ors)-.18 E F1(Currently)127 321 Q +3.649(,t)-.65 G 1.148 +(he con\214guration \214le can generate an error message during parsing.) +173.609 321 R(Ho)6.148 E(we)-.25 E -.15(ve)-.25 G 1.948 -.4(r, i).15 H(t).4 E +.569(cannot tweak other operations, such as issuing a w)102 333 R .57 +(arning message to the system postmaster)-.1 F 5.57(.S)-.55 G(imi-)487.33 333 Q +(larly)102 345 Q 2.558(,s)-.65 G .057 +(ome errors should not be triggered if the)128.628 345 R 2.557(ya)-.15 G .057 +(re in aliases during an alias \214le reb)302.237 345 R .057(uild, b)-.2 F .057 +(ut should)-.2 F(be triggered if that alias is actually used.)102 357 Q F0 2.5 +(3.6. Long)87 381 R -.92(Te)2.5 G(rm Host State).92 E F1(Currently)127 397.2 Q +(,)-.65 E F2(sendmail)3.731 E F1 1.231 +(only remembers host status during a single queue run.)3.731 F 1.232 +(This should be)6.232 F(con)102 409.2 Q -.15(ve)-.4 G .492(rted to long term s\ +tatus stored on disk so it can be shared between instantiations of).15 F F2 +(sendmail)2.991 E F1(.)A .866(Entries will ha)102 421.2 R 1.167 -.15(ve t)-.2 H +3.367(ob).15 G 3.367(et)190.666 421.2 S .867(imestamped so the)201.253 421.2 R +3.367(yc)-.15 G .867(an time out.)290.084 421.2 R .867(This will allo)5.867 F +(w)-.25 E F2(sendmail)3.367 E F1 .867(to implement)3.367 F -.15(ex)102 433.2 S +(ponential back).15 E(of)-.1 E 2.5(fo)-.25 G 2.5(nq)188.7 433.2 S +(ueue runs on a per)201.2 433.2 Q(-host basis.)-.2 E F0 2.5(3.7. Connection)87 +457.2 R(Contr)2.5 E(ol)-.18 E F1 .819(Modern netw)127 473.4 R .819(orks ha)-.1 +F 1.119 -.15(ve d)-.2 H(if).15 E .819(ferent types of connecti)-.25 F .818 +(vity than the past.)-.25 F .818(In particular)5.818 F 3.318(,t)-.4 G .818 +(he rising)468.462 473.4 R .636 +(prominence of dialup IP has created certain challenges for automated serv)102 +485.4 R 3.136(ers. It)-.15 F .636(is not uncommon)3.136 F .732(to try to mak) +102 497.4 R 3.232(eac)-.1 G .732(onnection to a host and ha)175.27 497.4 R +1.032 -.15(ve i)-.2 H 3.232(tf).15 G .732(ail, e)307.984 497.4 R -.15(ve)-.25 G +3.232(nt).15 G .732(hough if you tried ag)348.208 497.4 R .732(ain it w)-.05 F +.731(ould suc-)-.1 F 2.5(ceed. The)102 509.4 R +(connection management could be a bit cle)2.5 E -.15(ve)-.25 G +(rer to try to adapt to such situations.).15 E F0 2.5(3.8. Other)87 533.4 R +(Caching)2.5 E F1 .074(When you do an MX record lookup, the name serv)127 549.6 +R .075(er automatically returns the IP addresses of)-.15 F .518 +(the associated MX serv)102 561.6 R 3.018(ers. This)-.15 F .518 +(information is currently ignored, and another query is done to get)3.018 F +(this information.)102 573.6 Q(It should be cached to a)5 E -.2(vo)-.2 G(id e) +.2 E(xcess name serv)-.15 E(er traf)-.15 E(\214c.)-.25 E F0 2.5(4. REFERENCES) +72 597.6 R F1([Allman83a])87 613.8 Q .137(\231Sendmail \212 An Internetw)123 +625.8 R .137(ork Mail Router)-.1 F 4.037 -.7(.\232 E)-.55 H 2.638(.A).7 G 2.638 +(llman. In)327.58 625.8 R F2 .138(Unix Pr)2.638 F -.1(og)-.45 G -.15(ra).1 G +(mmer).15 E(s')-.1 E 2.638(sM)-.4 G(anual,)463.582 625.8 Q F1(4.2)2.638 E(Berk) +123 637.8 Q(ele)-.1 E 2.5(yS)-.15 G(oftw)166.91 637.8 Q(are Distrib)-.1 E +(ution, v)-.2 E(olume 2C.)-.2 E(August 1983.)5 E([Allman83b])87 654 Q .384 +(\231Mail Systems and Addressing in 4.2BSD.)123 666 R 5.384<9a45>-.7 G 2.884 +(.A)311.544 666 S .383(llman In)324.148 666 R F2 .383(UNICOM Confer)2.883 F +.383(ence Pr)-.37 F(oceedings.)-.45 E F1(San Die)123 678 Q(go, California.)-.15 +E(January 1983.)5 E([Allman&Amos85])87 694.2 Q -.74(``)123 706.2 S 1.145 +(Sendmail Re).74 F(visited.)-.25 E 5.125 -.74('' E)-.7 H 3.645(.A).74 G 1.145 +(llman and M. Amos.)241.215 706.2 R(In)6.145 E F2 1.145 +(Usenix Summer 1985 Confer)3.645 F 1.145(ence Pr)-.37 F(o-)-.45 E(ceedings.)123 +718.2 Q F1(Portland, Ore)5 E 2.5(gon. June)-.15 F(1985.)2.5 E EP +%%Page: 11 11 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(11)494 60 Q +/F1 10/Times-Roman@0 SF([ID)87 96 Q(A87])-.4 E/F2 10/Times-Italic@0 SF(Electr) +1.97 E .983(onic Mail Addr)-.45 F .983(essing in Theory and Pr)-.37 F .982 +(actice with the ID)-.15 F 3.482(AS)-.35 G .982(endmail Enhancement Kit)398.156 +96 R .563(\(or The P)123 108 R(ostmaster')-.8 E 3.063(sL)-.4 G .563(ast W) +215.989 108 R .564(ill and T)-.55 F(estament\).)-.92 E F1 .564(Lennart Lo)5.564 +F -.5(..)359.828 102 S 3.064(vstrand. Department)364.828 108 R .564 +(of Computer)3.064 F 1.267(and Information Science, Uni)123 120 R -.15(ve)-.25 +G 1.267(rsity of Link).15 F(o)-.1 E -.5(..)306.585 114 S 1.266 +(ping, Sweden, Report no. LiTH-ID)311.585 120 R(A-Ex-8715.)-.4 E(May 1987.)123 +132 Q([RFC821])87 148.2 Q F2(Simple Mail T)123 160.2 Q -.15(ra)-.55 G +(nsport Pr).15 E(otocol.)-.45 E F1(J. Postel.)5 E(August 1982.)5 E([RFC1123])87 +176.4 Q F2(Requir)123 188.4 Q .163 +(ements for Internet Hosts \212 Application and Support.)-.37 F F1 .164 +(Internet Engineering T)5.164 F .164(ask F)-.8 F(orce,)-.15 E +(R. Braden, Editor)123 200.4 Q 5(.O)-.55 G(ctober 1989.)207.72 200.4 Q +([RFC1344])87 216.6 Q F2(Implications of MIME for Internet Mail Gate)123 228.6 +Q(ways.)-.15 E F1(N. Borenstein.)5 E(June 1992.)5 E([RFC1413])87 244.8 Q F2 +(Identi\214cation Pr)123 256.8 Q(otocol.)-.45 E F1(M. St. Johns.)5 E +(February 1993.)5 E([RFC1425])87 273 Q F2 2.352(SMTP Service Extensions.)123 +285 R F1 2.352(J. Klensin, N. Freed, M. Rose, E. Stef)7.352 F 2.351 +(ferud, and D. Crock)-.25 F(er)-.1 E(.)-.55 E(February 1993.)123 297 Q +([RFC1426])87 313.2 Q F2 .12(SMTP Service Extension for 8bit-MIMEtr)123 325.2 R +(ansport.)-.15 E F1 .12(J. Klensin, N. Freed, M. Rose, E. Stef)5.12 F(ferud,) +-.25 E(and D. Crock)123 337.2 Q(er)-.1 E 5(.F)-.55 G(ebruary 1993.)196.78 337.2 +Q([RFC1427])87 353.4 Q F2 .813(SMTP Service Extension for Messa)123 365.4 R +1.013 -.1(ge S)-.1 H .813(ize Declar).1 F(ation.)-.15 E F1 .813 +(J. Klensin, N. Freed, and K. Moore.)5.813 F(February 1993.)123 377.4 Q +([RFC1521])87 393.6 Q F2 2.033 +(MIME \(Multipurpose Internet Mail Extensions\) P)123 405.6 R 2.033 +(art One: Mec)-.8 F 2.033(hanisms for Specifying and)-.15 F .933 +(Describing the F)123 417.6 R .933(ormat of Internet Messa)-1.05 F 1.133 -.1 +(ge B)-.1 H(odies.).1 E F1 .932(N. Borenstein and N. Freed.)5.932 F(September) +5.932 E(1993.)123 429.6 Q EP +%%Trailer +end +%%EOF diff --git a/usr.sbin/sendmail/doc/op/op.me b/usr.sbin/sendmail/doc/op/op.me new file mode 100644 index 000000000000..6fd40ad866e3 --- /dev/null +++ b/usr.sbin/sendmail/doc/op/op.me @@ -0,0 +1,7593 @@ +.\" Copyright (c) 1983, 1995 Eric P. Allman +.\" Copyright (c) 1983, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)op.me 8.70 (Berkeley) 11/3/95 +.\" +.\" eqn op.me | pic | troff -me +.eh 'SMM:08-%''Sendmail Installation and Operation Guide' +.oh 'Sendmail Installation and Operation Guide''SMM:08-%' +.\" SD is lib if sendmail is installed in /usr/lib, sbin if in /usr/sbin +.ds SD sbin +.\" SB is bin if newaliases/mailq are installed in /usr/bin, ucb if in /usr/ucb +.ds SB bin +.nr si 3n +.de $0 +.(x +.in \\$3u*3n +.ti -3n +\\$2. \\$1 +.)x +.. +.de $C +.(x +.in 0 +\\$1 \\$2. \\$3 +.)x +.. +.sc +.+c +.(l C +.sz 16 +.b SENDMAIL +.sz 12 +.sp +.b "INSTALLATION AND OPERATION GUIDE" +.sz 10 +.sp +.r +Eric Allman +Pang\(aea Reference Systems +eric@Sendmail.ORG +.sp +Version 8.70 +.sp +For Sendmail Version 8.7 +.)l +.sp 2 +.pp +.i Sendmail +implements a general purpose internetwork mail routing facility +under the UNIX\(rg +operating system. +It is not tied to any one transport protocol \*- +its function may be likened to a crossbar switch, +relaying messages from one domain into another. +In the process, +it can do a limited amount of message header editing +to put the message into a format that is appropriate +for the receiving domain. +All of this is done under the control of a configuration file. +.pp +Due to the requirements of flexibility +for +.i sendmail , +the configuration file can seem somewhat unapproachable. +However, there are only a few basic configurations +for most sites, +for which standard configuration files have been supplied. +Most other configurations +can be built by adjusting an existing configuration files +incrementally. +.pp +.i Sendmail +is based on +RFC821 (Simple Mail Transport Protocol), +RFC822 (Internet Mail Format Protocol), +RFC1123 (Internet Host Requirements), +RFC1521 (MIME), +RFC1651 (SMTP Service Extensions), +and a series of as-yet-draft standards describing +Delivery Status Notifications (DSNs), +available from the internet drafts sites as +draft-ietf-notary-mime-delivery-\fIXX\fP.txt, +draft-ietf-notary-mime-report-\fIXX\fP.txt, +draft-ietf-notary-smtp-drpt-\fIXX\fP.txt, +and +draft-ietf-notary-status-\fIXX\fP.txt +(replace +.i XX +by the latest draft number). +However, since +.i sendmail +is designed to work in a wider world, +in many cases it can be configured to exceed these protocols. +These cases are described herein. +.pp +Although +.i sendmail +is intended to run +without the need for monitoring, +it has a number of features +that may be used to monitor or adjust the operation +under unusual circumstances. +These features are described. +.pp +Section one describes how to do a basic +.i sendmail +installation. +Section two +explains the day-to-day information you should know +to maintain your mail system. +If you have a relatively normal site, +these two sections should contain sufficient information +for you to install +.i sendmail +and keep it happy. +Section three +describes some parameters that may be safely tweaked. +Section four +has information regarding the command line arguments. +Section five +contains the nitty-gritty information about the configuration +file. +This section is for masochists +and people who must write their own configuration file. +Section six +describes configuration that can be done at compile time. +Section seven +gives a brief description of differences +in this version of +.i sendmail . +The appendixes give a brief +but detailed explanation of a number of features +not described in the rest of the paper. +.pp +.b WARNING: +Several major changes were introduced in version 8.7. +You should not attempt to use this document +for prior versions of +.i sendmail . +.bp 7 +.sh 1 "BASIC INSTALLATION" +.pp +There are two basic steps to installing +.i sendmail . +The hard part is to build the configuration table. +This is a file that +.i sendmail +reads when it starts up +that describes the mailers it knows about, +how to parse addresses, +how to rewrite the message header, +and the settings of various options. +Although the configuration table is quite complex, +a configuration can usually be built +by adjusting an existing off-the-shelf configuration. +The second part is actually doing the installation, +i.e., creating the necessary files, etc. +.pp +The remainder of this section will describe the installation of +.i sendmail +assuming you can use one of the existing configurations +and that the standard installation parameters are acceptable. +All pathnames and examples +are given from the root of the +.i sendmail +subtree, +normally +.i /usr/src/usr.\*(SD/sendmail +on 4.4BSD. +.pp +If you are loading this off the tape, +continue with the next section. +If you have a running binary already on your system, +you should probably skip to section 1.2. +.sh 2 "Compiling Sendmail" +.pp +All +.i sendmail +source is in the +.i src +subdirectory. +If you are running on a 4.4BSD system, +compile by typing +.q make . +On other systems, you may have to make some other adjustments. +On most systems, +you can do the appropriate compilation by typing +.(b +sh makesendmail +.)b +This will leave the binary in an appropriately named subdirectory. +It works for multiple object versions +compiled out of the same directory. +.sh 3 "Tweaking the Makefile" +.pp +.i Sendmail +supports two different formats +for the local (on disk) version of databases, +notably the +.i aliases +database. +At least one of these should be defined if at all possible. +.nr ii 1i +.ip NDBM +The ``new DBM'' format, +available on nearly all systems around today. +This was the preferred format prior to 4.4BSD. +It allows such complex things as multiple databases +and closing a currently open database. +.ip NEWDB +The new database package from Berkeley. +If you have this, use it. +It allows +long records, +multiple open databases, +real in-memory caching, +and so forth. +You can define this in conjunction with one of the other two; +if you do, +old databases are read, +but when a new database is created it will be in NEWDB format. +As a nasty hack, +if you have NEWDB, NDBM, and NIS defined, +and if the alias file name includes the substring +.q /yp/ , +.i sendmail +will create both new and old versions of the alias file +during a +.i newalias +command. +This is required because the Sun NIS/YP system +reads the DBM version of the alias file. +It's ugly as sin, +but it works. +.lp +If neither of these are defined, +.i sendmail +reads the alias file into memory on every invocation. +This can be slow and should be avoided. +There are also several methods for remote database access: +.ip NIS +Sun's Network Information Services (formerly YP). +.ip NISPLUS +Sun's NIS+ services. +.ip NETINFO +NeXT's NetInfo service. +.ip HESIOD +Hesiod service (from Athena). +.lp +Other compilation flags are set in conf.h +and should be predefined for you +unless you are porting to a new environment. +.sh 3 "Compilation and installation" +.pp +After making the local system configuration described above, +You should be able to compile and install the system. +The script +.q makesendmail +is the best approach on most systems: +.(b +sh makesendmail +.)b +This will use +.i uname (1) +to select the correct Makefile for your environment. +.pp +You may be able to install using +.(b +sh makesendmail install +.)b +This should install the binary in +/usr/\*(SD +and create links from +/usr/\*(SB/newaliases +and +/usr/\*(SB/mailq +to +/usr/\*(SD/sendmail. +On 4.4BSD systems it will also format and install man pages. +.sh 2 "Configuration Files" +.pp +.i Sendmail +cannot operate without a configuration file. +The configuration defines the mail delivery mechanisms understood at this site, +how to access them, +how to forward email to remote mail systems, +and a number of tuning parameters. +This configuration file is detailed +in the later portion of this document. +.pp +The +.i sendmail +configuration can be daunting at first. +The world is complex, +and the mail configuration reflects that. +The distribution includes an m4-based configuration package +that hides a lot of the complexity. +.pp +These configuration files are simpler than old versions +largely because the world has become simpler; +in particular, +text-based host files are officially eliminated, +obviating the need to +.q hide +hosts behind a registered internet gateway. +.pp +These files also assume that most of your neighbors +use domain-based UUCP addressing; +that is, +instead of naming hosts as +.q host!user +they will use +.q host.domain!user . +The configuration files can be customized to work around this, +but it is more complex. +.pp +Our configuration files are processed by +.i m4 +to facilitate local customization; +the directory +.i cf +of the +.i sendmail +distribution directory +contains the source files. +This directory contains several subdirectories: +.nr ii 1i +.ip cf +Both site-dependent and site-independent descriptions of hosts. +These can be literal host names +(e.g., +.q ucbvax.mc ) +when the hosts are gateways +or more general descriptions +(such as +.q "tcpproto.mc" +as a general description of an SMTP-connected host +or +.q "uucpproto.mc" +as a general description of a UUCP-connected host). +Files ending +.b \&.mc +(``Master Configuration'') +are the input descriptions; +the output is in the corresponding +.b \&.cf +file. +The general structure of these files is described below. +.ip domain +Site-dependent subdomain descriptions. +These are tied to the way your organization wants to do addressing. +For example, +.b domain/cs.exposed.m4 +is our description for hosts in the CS.Berkeley.EDU subdomain +that want their individual hostname to be externally visible; +.b domain/cs.hidden.m4 +is the same except that the hostname is hidden +(everything looks like it comes from CS.Berkeley.EDU). +These are referenced using the +.sm DOMAIN +.b m4 +macro in the +.b \&.mc +file. +.ip feature +Definitions of specific features that some particular host in your site +might want. +These are referenced using the +.sm FEATURE +.b m4 +macro. +An example feature is +use_cw_file +(which tells +.i sendmail +to read an /etc/sendmail.cw file on startup +to find the set of local names). +.ip hack +Local hacks, referenced using the +.sm HACK +.b m4 +macro. +Try to avoid these. +The point of having them here is to make it clear that they smell. +.ip m4 +Site-independent +.i m4 (1) +include files that have information common to all configuration files. +This can be thought of as a +.q #include +directory. +.ip mailer +Definitions of mailers, +referenced using the +.sm MAILER +.b m4 +macro. +The mailer types that are known in this distribution are +fax, +local, +smtp, +uucp, +and usenet. +For example, to include support for the UUCP-based mailers, +use +.q MAILER(uucp) . +.ip ostype +Definitions describing various operating system environments +(such as the location of support files). +These are referenced using the +.sm OSTYPE +.b m4 +macro. +.ip sh +Shell files used by the +.b m4 +build process. +You shouldn't have to mess with these. +.ip siteconfig +Local site configuration information, +such as UUCP connectivity. +They normally contain lists of site information, for example: +.(b +SITE(contessa) +SITE(hoptoad) +SITE(nkainc) +SITE(well) +.)b +They are referenced using the SITECONFIG macro: +.(b +SITECONFIG(site.config.file, name_of_site, X) +.)b +where +.i X +is the macro/class name to use. +It can be U +(indicating locally connected hosts) +or one of W, X, or Y +for up to three remote UUCP hubs. +.pp +If you are in a new domain +(e.g., a company), +you will probably want to create a +cf/domain +file for your domain. +This consists primarily of relay definitions: +for example, Berkeley's domain definition +defines relays for +BitNET, +CSNET, +and UUCP. +Of these, +only the UUCP relay is particularly specific +to Berkeley. +All of these are internet-style domain names. +Please check to make certain they are reasonable for your domain. +.pp +Subdomains at Berkeley are also represented in the +cf/domain +directory. +For example, +the domain +cs-exposed +is the Computer Science subdomain with the local hostname shown +to other users; +cs-hidden +makes users appear to be from the CS.Berkeley.EDU subdomain +(with no local host information included). +You will probably have to update this directory +to be appropriate for your domain. +.pp +You will have to use or create +.b \&.mc +files in the +.i cf/cf +subdirectory for your hosts. +This is detailed in the +cf/README +file. +.sh 2 "Details of Installation Files" +.pp +This subsection describes the files that +comprise the +.i sendmail +installation. +.sh 3 "/usr/\*(SD/sendmail" +.pp +The binary for +.i sendmail +is located in /usr/\*(SD\**. +.(f +\**This is usually +/usr/sbin +on 4.4BSD and newer systems; +many systems install it in +/usr/lib. +I understand it is in /usr/ucblib +on System V Release 4. +.)f +It should be setuid root. +For security reasons, +/, /usr, and /usr/\*(SD +should be owned by root, mode 755\**. +.(f +\**Some vendors ship them owned by bin; +this creates a security hole that is not actually related to +.i sendmail . +Other important directories that should have restrictive ownerships +and permissions are +/bin, /usr/bin, /etc, /usr/etc, /lib, and /usr/lib. +.)f +.sh 3 "/etc/sendmail.cf" +.pp +This is the configuration file for +.i sendmail \**. +.(f +\**Actually, the pathname varies depending on the operating system; +/etc is the preferred directory. +Some older systems install it in +.b /usr/lib/sendmail.cf , +and I've also seen it in +.b /usr/ucblib +and +.b /etc/mail . +If you want to move this file, +change +.i src/conf.h . +.)f +This and /etc/sendmail.pid +are the only non-library file names compiled into +.i sendmail \**. +.(f +\**The system libraries can reference other files; +in particular, system library subroutines that +.i sendmail +calls probably reference +.i /etc/passwd +and +.i /etc/resolv.conf . +.)f +.pp +The configuration file is normally created +using the distribution files described above. +If you have a particularly unusual system configuration +you may need to create a special version. +The format of this file is detailed in later sections +of this document. +.sh 3 "/usr/\*(SB/newaliases" +.pp +The +.i newaliases +command should just be a link to +.i sendmail : +.(b +rm \-f /usr/\*(SB/newaliases +ln \-s /usr/\*(SD/sendmail /usr/\*(SB/newaliases +.)b +This can be installed in whatever search path you prefer +for your system. +.sh 3 "/var/spool/mqueue" +.pp +The directory +.i /var/spool/mqueue +should be created to hold the mail queue. +This directory should be mode 700 +and owned by root. +.pp +The actual path of this directory +is defined in the +.b Q +option of the +.i sendmail.cf +file. +.sh 3 "/etc/aliases*" +.pp +The system aliases are held in +.q /etc/aliases . +A sample is given in +.q lib/aliases +which includes some aliases which +.i must +be defined: +.(b +cp lib/aliases /etc/aliases +.i "edit /etc/aliases" +.)b +You should extend this file with any aliases that are apropos to your system. +.pp +Normally +.i sendmail +looks at a version of these files maintained by the +.i dbm \|(3) +or +.i db \|(3) +routines. +These are stored either in +.q /etc/aliases.dir +and +.q /etc/aliases.pag +or +.q /etc/aliases.db +depending on which database package you are using. +These can initially be created as empty files, +but they will have to be initialized promptly. +These should be mode 644: +.(b +cp /dev/null /etc/aliases.dir +cp /dev/null /etc/aliases.pag +chmod 644 /etc/aliases.* +newaliases +.)b +The +.i db +routines preset the mode reasonably, +so this step can be skipped. +The actual path of this file +is defined in the +.b A +option of the +.i sendmail.cf +file. +.sh 3 "/etc/rc" +.pp +It will be necessary to start up the +.i sendmail +daemon when your system reboots. +This daemon performs two functions: +it listens on the SMTP socket for connections +(to receive mail from a remote system) +and it processes the queue periodically +to insure that mail gets delivered when hosts come up. +.pp +Add the following lines to +.q /etc/rc +(or +.q /etc/rc.local +as appropriate) +in the area where it is starting up the daemons: +.(b +if [ \-f /usr/\*(SD/sendmail \-a \-f /etc/sendmail.cf ]; then + (cd /var/spool/mqueue; rm \-f [lnx]f*) + /usr/\*(SD/sendmail \-bd \-q30m & + echo \-n ' sendmail' >/dev/console +fi +.)b +The +.q cd +and +.q rm +commands insure that all lock files have been removed; +extraneous lock files may be left around +if the system goes down in the middle of processing a message. +The line that actually invokes +.i sendmail +has two flags: +.q \-bd +causes it to listen on the SMTP port, +and +.q \-q30m +causes it to run the queue every half hour. +.pp +Some people use a more complex startup script, +removing zero length qf files and df files for which there is no qf file. +For example, see Figure 1 +for an example of a complex startup script. +.(z +.hl +# remove zero length qf files +for qffile in qf* +do + if [ \-r $qffile ] + then + if [ ! \-s $qffile ] + then + echo \-n " <zero: $qffile>" > /dev/console + rm \-f $qffile + fi + fi +done +# rename tf files to be qf if the qf does not exist +for tffile in tf* +do + qffile=`echo $tffile | sed 's/t/q/'` + if [ \-r $tffile \-a ! \-f $qffile ] + then + echo \-n " <recovering: $tffile>" > /dev/console + mv $tffile $qffile + else + echo \-n " <extra: $tffile>" > /dev/console + rm \-f $tffile + fi +done +# remove df files with no corresponding qf files +for dffile in df* +do + qffile=`echo $dffile | sed 's/d/q/'` + if [ \-r $dffile \-a ! \-f $qffile ] + then + echo \-n " <incomplete: $dffile>" > /dev/console + mv $dffile `echo $dffile | sed 's/d/D/'` + fi +done +# announce files that have been saved during disaster recovery +for xffile in [A-Z]f* +do + echo \-n " <panic: $xffile>" > /dev/console +done +.sp +.ce +Figure 1 \(em A complex startup script +.hl +.)z +.pp +If you are not running a version of UNIX +that supports Berkeley TCP/IP, +do not include the +.b \-bd +flag. +.sh 3 "/usr/lib/sendmail.hf" +.pp +This is the help file used by the SMTP +.b HELP +command. +It should be copied from +.q lib/sendmail.hf : +.(b +cp lib/sendmail.hf /usr/lib +.)b +The actual path of this file +is defined in the +.b H +option of the +.i sendmail.cf +file. +.sh 3 "/etc/sendmail.st" +.pp +If you wish to collect statistics +about your mail traffic, +you should create the file +.q /etc/sendmail.st : +.(b +cp /dev/null /etc/sendmail.st +chmod 666 /etc/sendmail.st +.)b +This file does not grow. +It is printed with the program +.q mailstats/mailstats.c. +The actual path of this file +is defined in the +.b S +option of the +.i sendmail.cf +file. +.sh 3 "/usr/\*(SB/mailq" +.pp +If +.i sendmail +is invoked as +.q mailq, +it will simulate the +.b \-bp +flag +(i.e., +.i sendmail +will print the contents of the mail queue; +see below). +This should be a link to /usr/\*(SD/sendmail. +.sh 1 "NORMAL OPERATIONS" +.sh 2 "The System Log" +.pp +The system log is supported by the +.i syslogd \|(8) +program. +All messages from +.i sendmail +are logged under the +.sm LOG_MAIL +facility\**. +.(f +\**Except on Ultrix, +which does not support facilities in the syslog. +.)f +.sh 3 "Format" +.pp +Each line in the system log +consists of a timestamp, +the name of the machine that generated it +(for logging from several machines +over the local area network), +the word +.q sendmail: , +and a message\**. +.(f +\**This format may vary slightly if your vendor has changed +the syntax. +.)f +Most messages are a sequence of +.i name \c +=\c +.i value +pairs. +.pp +The two most common lines are logged when a message is processed. +The first logs the receipt of a message; +there will be exactly one of these per message. +Some fields may be omitted if they do not contain interesting information. +Fields are: +.ip from +The envelope sender address. +.ip size +The size of the message in bytes. +.ip class +The class (i.e., numeric precedence) of the message. +.ip pri +The initial message priority (used for queue sorting). +.ip nrcpts +The number of envelope recipients for this message +(after aliasing and forwarding). +.ip msgid +The message id of the message (from the header). +.ip proto +The protocol used to receive this message (e.g., ESMTP or UUCP) +.ip relay +The machine from which it was received. +.lp +There is also one line logged per delivery attempt +(so there can be several per message if delivery is deferred +or there are multiple recipients). +Fields are: +.ip to +A comma-separated list of the recipients to this mailer. +.ip ctladdr +The ``controlling user'', that is, the name of the user +whose credentials we use for delivery. +.ip delay +The total delay between the time this message was received +and the time it was delivered. +.ip xdelay +The amount of time needed in this delivery attempt +(normally indicative of the speed of the connection). +.ip mailer +The name of the mailer used to deliver to this recipient. +.ip relay +The name of the host that actually accepted (or rejected) this recipient. +.ip stat +The delivery status. +.lp +Not all fields are present in all messages; +for example, the relay is not listed for local deliveries. +.sh 3 "Levels" +.pp +If you have +.i syslogd \|(8) +or an equivalent installed, +you will be able to do logging. +There is a large amount of information that can be logged. +The log is arranged as a succession of levels. +At the lowest level +only extremely strange situations are logged. +At the highest level, +even the most mundane and uninteresting events +are recorded for posterity. +As a convention, +log levels under ten +are considered generally +.q useful; +log levels above 64 +are reserved for debugging purposes. +Levels from 11\-64 are reserved for verbose information +that some sites might want. +.pp +A complete description of the log levels +is given in section +.\" XREF +4.6. +.sh 2 "Dumping State" +.pp +You can ask +.i sendmail +to log a dump of the open files +and the connection cache +by sending it a +.sm SIGUSR1 +signal. +The results are logged at +.sm LOG_DEBUG +priority. +.sh 2 "The Mail Queue" +.pp +Sometimes a host cannot handle a message immediately. +For example, it may be down or overloaded, causing it to refuse connections. +The sending host is then expected to save this message in +its mail queue +and attempt to deliver it later. +.pp +Under normal conditions the mail queue will be processed transparently. +However, you may find that manual intervention is sometimes necessary. +For example, +if a major host is down for a period of time +the queue may become clogged. +Although +.i sendmail +ought to recover gracefully when the host comes up, +you may find performance unacceptably bad in the meantime. +.sh 3 "Printing the queue" +.pp +The contents of the queue can be printed +using the +.i mailq +command +(or by specifying the +.b \-bp +flag to +.i sendmail ): +.(b +mailq +.)b +This will produce a listing of the queue id's, +the size of the message, +the date the message entered the queue, +and the sender and recipients. +.sh 3 "Forcing the queue" +.pp +.i Sendmail +should run the queue automatically +at intervals. +The algorithm is to read and sort the queue, +and then to attempt to process all jobs in order. +When it attempts to run the job, +.i sendmail +first checks to see if the job is locked. +If so, it ignores the job. +.pp +There is no attempt to insure that only one queue processor +exists at any time, +since there is no guarantee that a job cannot take forever +to process +(however, +.i sendmail +does include heuristics to try to abort jobs +that are taking absurd amounts of time; +technically, this violates RFC 821, but is blessed by RFC 1123). +Due to the locking algorithm, +it is impossible for one job to freeze the entire queue. +However, +an uncooperative recipient host +or a program recipient +that never returns +can accumulate many processes in your system. +Unfortunately, +there is no completely general way to solve this. +.pp +In some cases, +you may find that a major host going down +for a couple of days +may create a prohibitively large queue. +This will result in +.i sendmail +spending an inordinate amount of time +sorting the queue. +This situation can be fixed by moving the queue to a temporary place +and creating a new queue. +The old queue can be run later when the offending host returns to service. +.pp +To do this, +it is acceptable to move the entire queue directory: +.(b +cd /var/spool +mv mqueue omqueue; mkdir mqueue; chmod 700 mqueue +.)b +You should then kill the existing daemon +(since it will still be processing in the old queue directory) +and create a new daemon. +.pp +To run the old mail queue, +run the following command: +.(b +/usr/\*(SD/sendmail \-oQ/var/spool/omqueue \-q +.)b +The +.b \-oQ +flag specifies an alternate queue directory +and the +.b \-q +flag says to just run every job in the queue. +If you have a tendency toward voyeurism, +you can use the +.b \-v +flag to watch what is going on. +.pp +When the queue is finally emptied, +you can remove the directory: +.(b +rmdir /var/spool/omqueue +.)b +.sh 2 "The Service Switch" +.pp +The implementation of certain system services +such as host and user name lookup +is controlled by the service switch. +If the host operating system supports such a switch +.i sendmail +will use the native version. +Ultrix, Solaris, and DEC OSF/1 are examples of such systems. +.pp +If the underlying operating system does not support a service switch +(e.g., SunOS, HP-UX, BSD) +then +.i sendmail +will provide a stub implementation. +The +.b ServiceSwitchFile +option points to the name of a file that has the service definitions +Each line has the name of a service +and the possible implementations of that service. +For example, the file: +.(b +hosts dns files nis +aliases files nis +.)b +will ask +.i sendmail +to look for hosts in the Domain Name System first. +If the requested host name is not found, +it tries local files, +and if that fails it tries NIS. +Similarly, +when looking for aliases +it will try the local files first +followed by NIS. +.pp +Service switches are not completely integrated. +For example, despite the fact that the host entry listed in the above example +specifies to look in NIS, +on SunOS this won't happen because the system implementation of +.i gethostbyname \|(3) +doesn't understand this. +If there is enough demand +.i sendmail +may reimplement +.i gethostbyname \|(3), +.i gethostbyaddr \|(3), +.i getpwent \|(3), +and the other system routines that would be necessary +to make this work seamlessly. +.sh 2 "The Alias Database" +.pp +The alias database exists in two forms. +One is a text form, +maintained in the file +.i /etc/aliases. +The aliases are of the form +.(b +name: name1, name2, ... +.)b +Only local names may be aliased; +e.g., +.(b +eric@prep.ai.MIT.EDU: eric@CS.Berkeley.EDU +.)b +will not have the desired effect +(except on prep.ai.MIT.EDU, +and they probably don't want me)\**. +.(f +\**Actually, any mailer that has the `A' mailer flag set +will permit aliasing; +this is normally limited to the local mailer. +.)f +Aliases may be continued by starting any continuation lines +with a space or a tab. +Blank lines and lines beginning with a sharp sign +(\c +.q # ) +are comments. +.pp +The second form is processed by the +.i ndbm \|(3)\** +.(f +\**The +.i gdbm +package probably works as well. +.)f +or +.i db \|(3) +library. +This form is in the files +.i /etc/aliases.dir +and +.i /etc/aliases.pag. +This is the form that +.i sendmail +actually uses to resolve aliases. +This technique is used to improve performance. +.pp +The control of search order is actually set by the service switch. +Essentially, the entry +.(b +OAswitch:aliases +.)b +is always added as the first alias entry; +also, the first alias file name without a class +(e.g., without +.q nis: +on the front) +will be used as the name of the file for a ``files'' entry +in the aliases switch. +For example, if the configuration file contains +.(b +OA/etc/aliases +.)b +and the service switch contains +.(b +aliases nis files nisplus +.)b +then aliases will first be searched in the NIS database, +then in /etc/aliases, +then in the NIS+ database. +.pp +You can also use +.sm NIS -based +alias files. +For example, the specification: +.(b +OA/etc/aliases +OAnis:mail.aliases@my.nis.domain +.)b +will first search the /etc/aliases file +and then the map named +.q mail.aliases +in +.q my.nis.domain . +Warning: if you build your own +.sm NIS -based +alias files, +be sure to provide the +.b \-l +flag to +.i makedbm (8) +to map upper case letters in the keys to lower case; +otherwise, aliases with upper case letters in their names +won't match incoming addresses. +.pp +Additional flags can be added after the colon +exactly like a +.b K +line \(em for example: +.(b +OAnis:\-N mail.aliases@my.nis.domain +.)b +will search the appropriate NIS map and always include null bytes in the key. +.sh 3 "Rebuilding the alias database" +.pp +The DB or DBM version of the database +may be rebuilt explicitly by executing the command +.(b +newaliases +.)b +This is equivalent to giving +.i sendmail +the +.b \-bi +flag: +.(b +/usr/\*(SD/sendmail \-bi +.)b +.pp +If the +.b RebuildAliases +(old +.b D ) +option is specified in the configuration, +.i sendmail +will rebuild the alias database automatically +if possible +when it is out of date. +Auto-rebuild can be dangerous +on heavily loaded machines +with large alias files; +if it might take more than the rebuild timeout +(option +.b AliasWait , +old +.b a , +which is normally five minutes) +to rebuild the database, +there is a chance that several processes will start the rebuild process +simultaneously. +.pp +If you have multiple aliases databases specified, +the +.b \-bi +flag rebuilds all the database types it understands +(for example, it can rebuild NDBM databases but not NIS databases). +.sh 3 "Potential problems" +.pp +There are a number of problems that can occur +with the alias database. +They all result from a +.i sendmail +process accessing the DBM version +while it is only partially built. +This can happen under two circumstances: +One process accesses the database +while another process is rebuilding it, +or the process rebuilding the database dies +(due to being killed or a system crash) +before completing the rebuild. +.pp +Sendmail has three techniques to try to relieve these problems. +First, it ignores interrupts while rebuilding the database; +this avoids the problem of someone aborting the process +leaving a partially rebuilt database. +Second, +it locks the database source file during the rebuild \(em +but that may not work over NFS or if the file is unwritable. +Third, +at the end of the rebuild +it adds an alias of the form +.(b +@: @ +.)b +(which is not normally legal). +Before +.i sendmail +will access the database, +it checks to insure that this entry exists\**. +.(f +\**The +.b AliasWait +option is required in the configuration +for this action to occur. +This should normally be specified. +.)f +.sh 3 "List owners" +.pp +If an error occurs on sending to a certain address, +say +.q \fIx\fP , +.i sendmail +will look for an alias +of the form +.q owner-\fIx\fP +to receive the errors. +This is typically useful +for a mailing list +where the submitter of the list +has no control over the maintenance of the list itself; +in this case the list maintainer would be the owner of the list. +For example: +.(b +unix-wizards: eric@ucbarpa, wnj@monet, nosuchuser, + sam@matisse +owner-unix-wizards: unix-wizards-request +unix-wizards-request: eric@ucbarpa +.)b +would cause +.q eric@ucbarpa +to get the error that will occur +when someone sends to +unix-wizards +due to the inclusion of +.q nosuchuser +on the list. +.pp +List owners also cause the envelope sender address to be modified. +The contents of the owner alias are used if they point to a single user, +otherwise the name of the alias itself is used. +For this reason, and to obey Internet conventions, +the +.q owner- +address normally points at the +.q -request +address; this causes messages to go out with the typical Internet convention +of using ``\c +.i list -request'' +as the return address. +.sh 2 "User Information Database" +.pp +If you have a version of +.i sendmail +with the user information database +compiled in, +and you have specified one or more databases using the +.b U +option, +the databases will be searched for a +.i user :maildrop +entry. +If found, the mail will be sent to the specified address. +.sh 2 "Per-User Forwarding (.forward Files)" +.pp +As an alternative to the alias database, +any user may put a file with the name +.q .forward +in his or her home directory. +If this file exists, +.i sendmail +redirects mail for that user +to the list of addresses listed in the .forward file. +For example, if the home directory for user +.q mckusick +has a .forward file with contents: +.(b +mckusick@ernie +kirk@calder +.)b +then any mail arriving for +.q mckusick +will be redirected to the specified accounts. +.pp +Actually, the configuration file defines a sequence of filenames to check. +By default, this is the user's .forward file, +but can be defined to be more generally using the +.b J +option. +If you change this, +you will have to inform your user base of the change; +\&.forward is pretty well incorporated into the collective subconscious. +.sh 2 "Special Header Lines" +.pp +Several header lines have special interpretations +defined by the configuration file. +Others have interpretations built into +.i sendmail +that cannot be changed without changing the code. +These builtins are described here. +.sh 3 "Errors-To:" +.pp +If errors occur anywhere during processing, +this header will cause error messages to go to +the listed addresses. +This is intended for mailing lists. +.pp +The Errors-To: header was created in the bad old days +when UUCP didn't understand the distinction between an envelope and a header; +this was a hack to provide what should now be passed +as the envelope sender address. +It should go away. +It is only used if the +.b UseErrorsTo +option is set. +.pp +The Errors-To: header is official deprecated +and will go away in a future release. +.sh 3 "Apparently-To:" +.pp +RFC 822 requires at least one recipient field +(To:, Cc:, or Bcc: line) +in every message. +If a message comes in with no recipients listed in the message +then +.i sendmail +will adjust the header based on the +.q NoRecipientAction +option. +One of the possible actions is to add an +.q "Apparently-To:" +header line for any recipients it is aware of. +This is not put in as a standard recipient line +to warn any recipients that the list is not complete. +.pp +The Apparently-To: header is non-standard +and is deprecated. +.sh 3 "Precedence" +.pp +The Precedence: header can be used as a crude control of message priority. +It tweaks the sort order in the queue +and can be configured to change the message timeout values. +.sh 2 "IDENT Protocol Support" +.pp +.i Sendmail +supports the IDENT protocol as defined in RFC 1413. +Although this enhances identification +of the author of an email message +by doing a ``call back'' to the originating system to include +the owner of a particular TCP connection +in the audit trail +it is in no sense perfect; +a determined forger can easily spoof the IDENT protocol. +The following description is excerpted from RFC 1413: +.ba +5 +.lp +6. Security Considerations +.lp +The information returned by this protocol is at most as trustworthy +as the host providing it OR the organization operating the host. For +example, a PC in an open lab has few if any controls on it to prevent +a user from having this protocol return any identifier the user +wants. Likewise, if the host has been compromised the information +returned may be completely erroneous and misleading. +.lp +The Identification Protocol is not intended as an authorization or +access control protocol. At best, it provides some additional +auditing information with respect to TCP connections. At worst, it +can provide misleading, incorrect, or maliciously incorrect +information. +.lp +The use of the information returned by this protocol for other than +auditing is strongly discouraged. Specifically, using Identification +Protocol information to make access control decisions - either as the +primary method (i.e., no other checks) or as an adjunct to other +methods may result in a weakening of normal host security. +.lp +An Identification server may reveal information about users, +entities, objects or processes which might normally be considered +private. An Identification server provides service which is a rough +analog of the CallerID services provided by some phone companies and +many of the same privacy considerations and arguments that apply to +the CallerID service apply to Identification. If you wouldn't run a +"finger" server due to privacy considerations you may not want to run +this protocol. +.ba +.lp +In some cases your system may not work properly with IDENT support +due to a bug in the TCP/IP implementation. +The symptoms will be that for some hosts +the SMTP connection will be closed +almost immediately. +If this is true or if you do not want to use IDENT, +you should set the IDENT timeout to zero; +this will disable the IDENT protocol. +.sh 1 "ARGUMENTS" +.pp +The complete list of arguments to +.i sendmail +is described in detail in Appendix A. +Some important arguments are described here. +.sh 2 "Queue Interval" +.pp +The amount of time between forking a process +to run through the queue +is defined by the +.b \-q +flag. +If you run with delivery mode set to +.b i +or +.b b +this can be relatively large, +since it will only be relevant +when a host that was down comes back up. +If you run in +.b q +mode +it should be relatively short, +since it defines the maximum amount of time that a message +may sit in the queue. +(See also the MinQueueAge option.) +.pp +RFC 1123 section 5.3.1.1 says that this value should be at least 30 minutes +(although that probably doesn't make sense if you use ``queue-only'' mode). +.sh 2 "Daemon Mode" +.pp +If you allow incoming mail over an IPC connection, +you should have a daemon running. +This should be set by your +.i /etc/rc +file using the +.b \-bd +flag. +The +.b \-bd +flag and the +.b \-q +flag may be combined in one call: +.(b +/usr/\*(SD/sendmail \-bd \-q30m +.)b +.pp +An alternative approach is to invoke sendmail from +.i inetd (8) +(use the +.b \-bs +flag to ask sendmail to speak SMTP on its standard input and output). +This works and allows you to wrap +.i sendmail +in a TCP wrapper program, +but may be a bit slower since the configuration file +has to be re-read on every message that comes in. +If you do this, you still need to have a +.i sendmail +running to flush the queue: +.(b +/usr/\*(SD/sendmail \-q30m +.)b +.sh 2 "Forcing the Queue" +.pp +In some cases you may find that the queue has gotten clogged for some reason. +You can force a queue run +using the +.b \-q +flag (with no value). +It is entertaining to use the +.b \-v +flag (verbose) +when this is done to watch what happens: +.(b +/usr/\*(SD/sendmail \-q \-v +.)b +.pp +You can also limit the jobs to those with a particular queue identifier, +sender, or recipient +using one of the queue modifiers. +For example, +.q \-qRberkeley +restricts the queue run to jobs that have the string +.q berkeley +somewhere in one of the recipient addresses. +Similarly, +.q \-qSstring +limits the run to particular senders and +.q \-qIstring +limits it to particular queue identifiers. +.sh 2 "Debugging" +.pp +There are a fairly large number of debug flags +built into +.i sendmail . +Each debug flag has a number and a level, +where higher levels means to print out more information. +The convention is that levels greater than nine are +.q absurd, +i.e., +they print out so much information that you wouldn't normally +want to see them except for debugging that particular piece of code. +Debug flags are set using the +.b \-d +option; +the syntax is: +.(b +.ta \w'debug-option 'u +debug-flag: \fB\-d\fP debug-list +debug-list: debug-option [ , debug-option ]* +debug-option: debug-range [ . debug-level ] +debug-range: integer | integer \- integer +debug-level: integer +.)b +where spaces are for reading ease only. +For example, +.(b +\-d12 Set flag 12 to level 1 +\-d12.3 Set flag 12 to level 3 +\-d3\-17 Set flags 3 through 17 to level 1 +\-d3\-17.4 Set flags 3 through 17 to level 4 +.)b +For a complete list of the available debug flags +you will have to look at the code +(they are too dynamic to keep this documentation up to date). +.sh 2 "Changing the Values of Options" +.pp +Options can be overridden using the +.b \-o +or +.b \-O +command line flags. +For example, +.(b +/usr/\*(SD/sendmail \-oT2m +.)b +sets the +.b T +(timeout) option to two minutes +for this run only; +the equivalent line using the long option name is +.(b +/usr/\*(SD/sendmail -OQueueTimeout=2m +.)b +.pp +Some options have security implications. +Sendmail allows you to set these, +but relinquishes its setuid root permissions thereafter\**. +.(f +\**That is, it sets its effective uid to the real uid; +thus, if you are executing as root, +as from root's crontab file or during system startup +the root permissions will still be honored. +.)f +.sh 2 "Trying a Different Configuration File" +.pp +An alternative configuration file +can be specified using the +.b \-C +flag; for example, +.(b +/usr/\*(SD/sendmail \-Ctest.cf \-oQ/tmp/mqueue +.)b +uses the configuration file +.i test.cf +instead of the default +.i /etc/sendmail.cf. +If the +.b \-C +flag has no value +it defaults to +.i sendmail.cf +in the current directory. +.pp +.i Sendmail +gives up its setuid root permissions +when you use this flag, so it is common to use a publicly writable directory +(such as /tmp) +as the spool directory (QueueDirectory or Q option) while testing. +.sh 2 "Logging Traffic" +.pp +Many SMTP implementations do not fully implement the protocol. +For example, some personal computer based SMTPs +do not understand continuation lines in reply codes. +These can be very hard to trace. +If you suspect such a problem, you can set traffic logging using the +.b \-X +flag. +For example, +.(b +/usr/\*(SD/sendmail \-X /tmp/traffic \-bd +.)b +will log all traffic in the file +.i /tmp/traffic . +.pp +This logs a lot of data very quickly and should +.b NEVER +be used +during normal operations. +After starting up such a daemon, +force the errant implementation to send a message to your host. +All message traffic in and out of +.i sendmail , +including the incoming SMTP traffic, +will be logged in this file. +.sh 2 "Testing Configuration Files" +.pp +When you build a configuration table, +you can do a certain amount of testing +using the +.q "test mode" +of +.i sendmail . +For example, +you could invoke +.i sendmail +as: +.(b +sendmail \-bt \-Ctest.cf +.)b +which would read the configuration file +.q test.cf +and enter test mode. +In this mode, +you enter lines of the form: +.(b +rwset address +.)b +where +.i rwset +is the rewriting set you want to use +and +.i address +is an address to apply the set to. +Test mode shows you the steps it takes +as it proceeds, +finally showing you the address it ends up with. +You may use a comma separated list of rwsets +for sequential application of rules to an input. +For example: +.(b +3,1,21,4 monet:bollard +.)b +first applies ruleset three to the input +.q monet:bollard. +Ruleset one is then applied to the output of ruleset three, +followed similarly by rulesets twenty-one and four. +.pp +If you need more detail, +you can also use the +.q \-d21 +flag to turn on more debugging. +For example, +.(b +sendmail \-bt \-d21.99 +.)b +turns on an incredible amount of information; +a single word address +is probably going to print out several pages worth of information. +.pp +You should be warned that internally, +.i sendmail +applies ruleset 3 to all addresses. +In test mode +you will have to do that manually. +For example, older versions allowed you to use +.(b +0 bruce@broadcast.sony.com +.)b +This version requires that you use: +.(b +3,0 bruce@broadcast.sony.com +.)b +.pp +As of version 8.7, +some other syntaxes are available in test mode: +.bu +\&.D\|x\|value +defines macro +.i x +to have the indicated +.i value . +This is useful when debugging rules that use the +.b $& \c +.i x +syntax. +.bu +\&.C\|c\|value +adds the indicated +.i value +to class +.i c . +.bu +\&.S\|ruleset +dumps the contents of the indicated ruleset. +.bu +\-d\|debug-spec +is equivalent to the command-line flag. +.sh 1 "TUNING" +.pp +There are a number of configuration parameters +you may want to change, +depending on the requirements of your site. +Most of these are set +using an option in the configuration file. +For example, +the line +.q "O Timeout.queuereturn=5d" +sets option +.q Timeout.queuereturn +to the value +.q 5d +(five days). +.pp +Most of these options have appropriate defaults for most sites. +However, +sites having very high mail loads may find they need to tune them +as appropriate for their mail load. +In particular, +sites experiencing a large number of small messages, +many of which are delivered to many recipients, +may find that they need to adjust the parameters +dealing with queue priorities. +.pp +All versions of +.i sendmail +prior to 8.7 +had single character option names. +As of 8.7, +options have long (multi-character names). +Although old short names are still accepted, +most new options do not have short equivalents. +.pp +This section only describes the options you are most likely +to want to tweak; +read section +.\"XREF +5 +for more details. +.sh 2 "Timeouts" +.pp +All time intervals are set +using a scaled syntax. +For example, +.q 10m +represents ten minutes, whereas +.q 2h30m +represents two and a half hours. +The full set of scales is: +.(b +.ta 4n +s seconds +m minutes +h hours +d days +w weeks +.)b +.sh 3 "Queue interval" +.pp +The argument to the +.b \-q +flag +specifies how often a sub-daemon will run the queue. +This is typically set to between fifteen minutes +and one hour. +RFC 1123 section 5.3.1.1 recommends that this be at least 30 minutes. +.sh 3 "Read timeouts" +.pp +Timeouts all have option names +.q Timeout.\fIsuboption\fP . +The recognized +.i suboption s, +their default values, and the minimum values +allowed by RFC 1123 section 5.3.2 are: +.nr ii 1i +.ip connect +The time to wait for an SMTP connection to open +(the +.i connect (2) +system call) +[0, unspecified]. +If zero, uses the kernel default. +In no case can this option extend the timeout +longer than the kernel provides, but it can shorten it. +This is to get around kernels that provide an absurdly long connection timeout +(90 minutes in one case). +.ip initial +The wait for the initial 220 greeting message +[5m, 5m]. +.ip helo +The wait for a reply from a HELO or EHLO command +[5m, unspecified]. +This may require a host name lookup, so +five minutes is probably a reasonable minimum. +.ip mail\(dg +The wait for a reply from a MAIL command +[10m, 5m]. +.ip rcpt\(dg +The wait for a reply from a RCPT command +[1h, 5m]. +This should be long +because it could be pointing at a list +that takes a long time to expand +(see below). +.ip datainit\(dg +The wait for a reply from a DATA command +[5m, 2m]. +.ip datablock\(dg +The wait for reading a data block +(that is, the body of the message). +[1h, 3m]. +This should be long because it also applies to programs +piping input to +.i sendmail +which have no guarantee of promptness. +.ip datafinal\(dg +The wait for a reply from the dot terminating a message. +[1h, 10m]. +If this is shorter than the time actually needed +for the receiver to deliver the message, +duplicates will be generated. +This is discussed in RFC 1047. +.ip rset +The wait for a reply from a RSET command +[5m, unspecified]. +.ip quit +The wait for a reply from a QUIT command +[2m, unspecified]. +.ip misc +The wait for a reply from miscellaneous (but short) commands +such as NOOP (no-operation) and VERB (go into verbose mode). +[2m, unspecified]. +.ip command\(dg +In server SMTP, +the time to wait for another command. +[1h, 5m]. +.ip ident +The timeout waiting for a reply to an IDENT query +[30s\**, unspecified]. +.(f +\**On some systems the default is zero to turn the protocol off entirely. +.)f +.lp +For compatibility with old configuration files, +if no +.i suboption +is specified, +all the timeouts marked with \(dg are set to the indicated value. +.pp +Many of the RFC 1123 minimum values +may well be too short. +.i Sendmail +was designed to the RFC 822 protocols, +which did not specify read timeouts; +hence, versions of +.i sendmail +prior to version 8.1 did not guarantee to reply to messages promptly. +In particular, a +.q RCPT +command specifying a mailing list +will expand and verify the entire list; +a large list on a slow system +may easily take more than five minutes\**. +.(f +\**This verification includes looking up every address +with the name server; +this involves network delays, +and can in some cases can be considerable. +.)f +I recommend a one hour timeout \*- +since a communications failure during the RCPT phase is rare, +a long timeout is not onerous +and may ultimately help reduce network load +and duplicated messages. +.pp +For example, the lines: +.(b +O Timeout.command=25m +O Timeout.datablock=3h +.)b +sets the server SMTP command timeout to 25 minutes +and the input data block timeout to three hours. +.sh 3 "Message timeouts" +.pp +After sitting in the queue for a few days, +a message will time out. +This is to insure that at least the sender is aware +of the inability to send a message. +The timeout is typically set to five days. +It is sometimes considered convenient to also send a warning message +if the message is in the queue longer than a few hours +(assuming you normally have good connectivity; +if your messages normally took several hours to send +you wouldn't want to do this because it wouldn't be an unusual event). +These timeouts are set using the +.b Timeout.queuereturn +and +.b Timeout.queuewarn +options in the configuration file +(previously both were set using the +.b T +option). +.pp +Since these options are global, +and since you can not know +.i "a priori" +how long another host outside your domain will be down, +a five day timeout is recommended. +This allows a recipient to fix the problem even if it occurs +at the beginning of a long weekend. +RFC 1123 section 5.3.1.1 says that this parameter +should be ``at least 4\-5 days''. +.pp +The +.b Timeout.queuewarn +value can be piggybacked on the +.b T +option by indicating a time after which +a warning message should be sent; +the two timeouts are separated by a slash. +For example, the line +.(b +OT5d/4h +.)b +causes email to fail after five days, +but a warning message will be sent after four hours. +This should be large enough that the message will have been tried +several times. +.sh 2 "Forking During Queue Runs" +.pp +By setting the +.b ForkEachJob +(\c +.b Y ) +option, +.i sendmail +will fork before each individual message +while running the queue. +This will prevent +.i sendmail +from consuming large amounts of memory, +so it may be useful in memory-poor environments. +However, if the +.b ForkEachJob +option is not set, +.i sendmail +will keep track of hosts that are down during a queue run, +which can improve performance dramatically. +.pp +If the +.b ForkEachJob +option is set, +.i sendmail +can not use connection caching. +.sh 2 "Queue Priorities" +.pp +Every message is assigned a priority when it is first instantiated, +consisting of the message size (in bytes) +offset by the message class +(which is determined from the Precedence: header) +times the +.q "work class factor" +and the number of recipients times the +.q "work recipient factor." +The priority is used to order the queue. +Higher numbers for the priority mean that the message will be processed later +when running the queue. +.pp +The message size is included so that large messages are penalized +relative to small messages. +The message class allows users to send +.q "high priority" +messages by including a +.q Precedence: +field in their message; +the value of this field is looked up in the +.b P +lines of the configuration file. +Since the number of recipients affects the amount of load a message presents +to the system, +this is also included into the priority. +.pp +The recipient and class factors +can be set in the configuration file using the +.b RecipientFactor +(\c +.b y ) +and +.b ClassFactor +(\c +.b z ) +options respectively. +They default to 30000 (for the recipient factor) +and 1800 +(for the class factor). +The initial priority is: +.EQ +pri = msgsize - (class times bold ClassFactor) + (nrcpt times bold RecipientFactor) +.EN +(Remember, higher values for this parameter actually mean +that the job will be treated with lower priority.) +.pp +The priority of a job can also be adjusted each time it is processed +(that is, each time an attempt is made to deliver it) +using the +.q "work time factor," +set by the +.b RetryFactor +(\c +.b Z ) +option. +This is added to the priority, +so it normally decreases the precedence of the job, +on the grounds that jobs that have failed many times +will tend to fail again in the future. +The +.b RetryFactor +option defaults to 90000. +.sh 2 "Load Limiting" +.pp +.i Sendmail +can be asked to queue (but not deliver) +mail if the system load average gets too high +using the +.b QueueLA +(\c +.b x ) +option. +When the load average exceeds the value of the +.b QueueLA +option, +the delivery mode is set to +.b q +(queue only) +if the +.b QueueFactor +(\c +.b q ) +option divided by the difference in the current load average and the +.b QueueLA +option +plus one +exceeds the priority of the message \(em +that is, the message is queued iff: +.EQ +pri > { bold QueueFactor } over { LA - { bold QueueLA } + 1 } +.EN +The +.b QueueFactor +option defaults to 600000, +so each point of load average is worth 600000 +priority points +(as described above). +.pp +For drastic cases, +the +.b RefuseLA +(\c +.b X ) +option defines a load average at which +.i sendmail +will refuse +to accept network connections. +Locally generated mail +(including incoming UUCP mail) +is still accepted. +.sh 2 "Delivery Mode" +.pp +There are a number of delivery modes that +.i sendmail +can operate in, +set by the +.b DeliveryMode +(\c +.b d ) +configuration option. +These modes +specify how quickly mail will be delivered. +Legal modes are: +.(b +.ta 4n +i deliver interactively (synchronously) +b deliver in background (asynchronously) +q queue only (don't deliver) +d defer delvery attempts (don't deliver) +.)b +There are tradeoffs. +Mode +.q i +gives the sender the quickest feedback, +but may slow down some mailers and +is hardly ever necessary. +Mode +.q b +delivers promptly but +can cause large numbers of processes +if you have a mailer that takes a long time to deliver a message. +Mode +.q q +minimizes the load on your machine, +but means that delivery may be delayed for up to the queue interval. +Mode +.q d +is identical to mode +.q q +except that it also prevents all the early map lookups from working; +it is intended for ``dial on demand'' sites where DNS lookups +might cost real money. +Some simple error messages +(e.g., host unknown during the SMTP protocol) +will be delayed using this mode. +Mode +.q b +is the usual default. +.pp +If you run in mode +.q q +(queue only), +.q d +(defer), +or +.q b +(deliver in background) +.i sendmail +will not expand aliases and follow .forward files +upon initial receipt of the mail. +This speeds up the response to RCPT commands. +Mode +.q i +cannot be used by the SMTP server. +.sh 2 "Log Level" +.pp +The level of logging can be set for +.i sendmail . +The default using a standard configuration table is level 9. +The levels are as follows: +.nr ii 0.5i +.ip 0 +No logging. +.ip 1 +Serious system failures and potential security problems. +.ip 2 +Lost communications (network problems) and protocol failures. +.ip 3 +Other serious failures. +.ip 4 +Minor failures. +.ip 5 +Message collection statistics. +.ip 6 +Creation of error messages, +VRFY and EXPN commands. +.ip 7 +Delivery failures (host or user unknown, etc.). +.ip 8 +Successful deliveries and alias database rebuilds. +.ip 9 +Messages being deferred +(due to a host being down, etc.). +.ip 10 +Database expansion (alias, forward, and userdb lookups). +.ip 20 +Logs attempts to run locked queue files. +These are not errors, +but can be useful to note if your queue appears to be clogged. +.ip 30 +Lost locks (only if using lockf instead of flock). +.lp +Additionally, +values above 64 are reserved for extremely verbose debugging output. +No normal site would ever set these. +.sh 2 "File Modes" +.pp +The modes used for files depend on what functionality you want +and the level of security you require. +.sh 3 "To suid or not to suid?" +.pp +.i Sendmail +can safely be made +setuid to root. +At the point where it is about to +.i exec \|(2) +a mailer, +it checks to see if the userid is zero; +if so, +it resets the userid and groupid to a default +(set by the +.b u +and +.b g +options). +(This can be overridden +by setting the +.b S +flag to the mailer +for mailers that are trusted +and must be called as root.) +However, +this will cause mail processing +to be accounted +(using +.i sa \|(8)) +to root +rather than to the user sending the mail. +.pp +If you don't make +.i sendmail +setuid to root, it will still run but you lose a lot of functionality +and a lot of privacy, since you'll have to make the queue directory +world readable. +You could also make +.i sendmail +setuid to some pseudo-user +(e.g., create a user called +.q sendmail +and make +.i sendmail +setuid to that) +which will fix the privacy problems +but not the functionality issues. +Also, this isn't a guarantee of security: +for example, +root occasionally sends mail, +and the daemon often runs as root. +.sh 3 "Should my alias database be writable?" +.pp +At Berkeley +we have the alias database +(/etc/aliases*) +mode 644. +While this is not as flexible as if the database +were more 666, it avoids potential security problems +with a globally writable database. +.pp +The database that +.i sendmail +actually used +is represented by the two files +.i aliases.dir +and +.i aliases.pag +(both in /etc) +(or +.i aliases.db +if you are running with the new Berkeley database primitives). +The mode on these files should match the mode +on /etc/aliases. +If +.i aliases +is writable +and the +DBM +files +(\c +.i aliases.dir +and +.i aliases.pag ) +are not, +users will be unable to reflect their desired changes +through to the actual database. +However, +if +.i aliases +is read-only +and the DBM files are writable, +a slightly sophisticated user +can arrange to steal mail anyway. +.pp +If your DBM files are not writable by the world +or you do not have auto-rebuild enabled +(with the +.b AutoRebuildAliases +option), +then you must be careful to reconstruct the alias database +each time you change the text version: +.(b +newaliases +.)b +If this step is ignored or forgotten +any intended changes will also be ignored or forgotten. +.sh 2 "Connection Caching" +.pp +When processing the queue, +.i sendmail +will try to keep the last few open connections open +to avoid startup and shutdown costs. +This only applies to IPC connections. +.pp +When trying to open a connection +the cache is first searched. +If an open connection is found, it is probed to see if it is still active +by sending a +.sm NOOP +command. +It is not an error if this fails; +instead, the connection is closed and reopened. +.pp +Two parameters control the connection cache. +The +.b ConnectionCacheSize +(\c +.b k ) +option defines the number of simultaneous open connections +that will be permitted. +If it is set to zero, +connections will be closed as quickly as possible. +The default is one. +This should be set as appropriate for your system size; +it will limit the amount of system resources that +.i sendmail +will use during queue runs. +Never set this higher than 4. +.pp +The +.b ConnectionCacheTimeout +(\c +.b K ) +option specifies the maximum time that any cached connection +will be permitted to idle. +When the idle time exceeds this value +the connection is closed. +This number should be small +(under ten minutes) +to prevent you from grabbing too many resources +from other hosts. +The default is five minutes. +.sh 2 "Name Server Access" +.pp +Control of host address lookups is set by the +.b hosts +service entry in your service switch file. +If you are on a system that has built-in service switch support +(e.g., Ultrix, Solaris, or DEC OSF/1) +then your system is probably configured properly already. +Otherwise, +.i sendmail +will consult the file +.b /etc/service.switch , +which should be created. +.i Sendmail +only uses two entries: +.b hosts +and +.b aliases . +.pp +However, some systems (such as SunOS) +will do DNS lookups +regardless of the setting of the service switch entry. +In particular, the system routine +.i gethostbyname (3) +is used to look up host names, +and many vendor versions try some combination of DNS, NIS, +and file lookup in /etc/hosts +without consulting a service switch. +.i Sendmail +makes no attempt to work around this problem, +and the DNS lookup will be done anyway. +If you do not have a nameserver configured at all, +such as at a UUCP-only site, +.i sendmail +will get a +.q "connection refused" +message when it tries to connect to the name server. +If the +.b hosts +switch entry has the service +.q dns +listed somewhere in the list, +.i sendmail +will interpret this to mean a temporary failure +and will queue the mail for later processing; +otherwise, it ignores the name server data. +.pp +The same technique is used to decide whether to do MX lookups. +If you want MX support, you +.i must +have +.q dns +listed as a service in the +.b hosts +switch entry. +.pp +The +.b ResolverOptions +(\c +.b I ) +option allows you to tweak name server options. +The command line takes a series of flags as documented in +.i resolver (3) +(with the leading +.q RES_ +deleted). +Each can be preceded by an optional `+' or `\(mi'. +For example, the line +.(b +O ResolverOptions=+AAONLY \(miDNSRCH +.)b +turns on the AAONLY (accept authoritative answers only) +and turns off the DNSRCH (search the domain path) options. +Most resolver libraries default DNSRCH, DEFNAMES, and RECURSE +flags on and all others off. +You can also include +.q HasWildcardMX +to specify that there is a wildcard MX record matching your domain; +this turns off MX matching when canonifying names, +which can lead to inappropriate canonifications. +.pp +Version level 1 configurations +turn DNSRCH and DEFNAMES off when doing delivery lookups, +but leave them on everywhere else. +Version 8 of +.i sendmail +ignores them when doing canonification lookups +(that is, when using $[ ... $]), +and always does the search. +If you don't want to do automatic name extension, +don't call $[ ... $]. +.pp +The search rules for $[ ... $] are somewhat different than usual. +If the name being looked up +has at least one dot, it always tries the unmodified name first. +If that fails, it tries the reduced search path, +and lastly tries the unmodified name +(but only for names without a dot, +since names with a dot have already been tried). +This allows names such as +``utc.CS'' +to match the site in Czechoslovakia +rather than the site in your local Computer Science department. +It also prefers A and CNAME records over MX records \*- +that is, if it finds an MX record it makes note of it, +but keeps looking. +This way, if you have a wildcard MX record matching your domain, +it will not assume that all names match. +.pp +To completely turn off all name server access +on systems without service switch support +(such as SunOS) +you will have to recompile with +\-DNAMED_BIND=0 +and remove \-lresolv from the list of libraries to be searched +when linking. +.sh 2 "Moving the Per-User Forward Files" +.pp +Some sites mount each user's home directory +from a local disk on their workstation, +so that local access is fast. +However, the result is that .forward file lookups are slow. +In some cases, +mail can even be delivered on machines inappropriately +because of a file server being down. +The performance can be especially bad if you run the automounter. +.pp +The +.b ForwardPath +(\c +.b J ) +option allows you to set a path of forward files. +For example, the config file line +.(b +O ForwardPath=/var/forward/$u:$z/.forward.$w +.)b +would first look for a file with the same name as the user's login +in /var/forward; +if that is not found (or is inaccessible) +the file +``.forward.\c +.i machinename '' +in the user's home directory is searched. +A truly perverse site could also search by sender +by using $r, $s, or $f. +.pp +If you create a directory such as /var/forward, +it should be mode 1777 +(that is, the sticky bit should be set). +Users should create the files mode 644. +.sh 2 "Free Space" +.pp +On systems that have one of the system calls in the +.i statfs (2) +family +(including +.i statvfs +and +.i ustat ), +you can specify a minimum number of free blocks on the queue filesystem +using the +.b MinFreeBlocks +(\c +.b b ) +option. +If there are fewer than the indicated number of blocks free +on the filesystem on which the queue is mounted +the SMTP server will reject mail +with the +452 error code. +This invites the SMTP client to try again later. +.pp +Beware of setting this option too high; +it can cause rejection of email +when that mail would be processed without difficulty. +.sh 2 "Maximum Message Size" +.pp +To avoid overflowing your system with a large message, +the +.b MaxMessageSize +option can be set to set an absolute limit +on the size of any one message. +This will be advertised in the ESMTP dialogue +and checked during message collection. +.sh 2 "Privacy Flags" +.pp +The +.b PrivacyOptions +(\c +.b p ) +option allows you to set certain +``privacy'' +flags. +Actually, many of them don't give you any extra privacy, +rather just insisting that client SMTP servers +use the HELO command +before using certain commands +or adding extra headers to indicate possible spoof attempts. +.pp +The option takes a series of flag names; +the final privacy is the inclusive or of those flags. +For example: +.(b +O PrivacyOptions=needmailhelo, noexpn +.)b +insists that the HELO or EHLO command be used before a MAIL command is accepted +and disables the EXPN command. +.pp +The flags are detailed in section +.\"XREF +5.1.6. +.sh 2 "Send to Me Too" +.pp +Normally, +.i sendmail +deletes the (envelope) sender from any list expansions. +For example, if +.q matt +sends to a list that contains +.q matt +as one of the members he won't get a copy of the message. +If the +.b \-m +(me too) +command line flag, or if the +.b MeToo +(\c +.b m ) +option is set in the configuration file, +this behaviour is suppressed. +Some sites like to run the +.sm SMTP +daemon with +.b \-m . +.sh 1 "THE WHOLE SCOOP ON THE CONFIGURATION FILE" +.pp +This section describes the configuration file +in detail. +.pp +There is one point that should be made clear immediately: +the syntax of the configuration file +is designed to be reasonably easy to parse, +since this is done every time +.i sendmail +starts up, +rather than easy for a human to read or write. +On the +.q "future project" +list is a +configuration-file compiler. +.pp +The configuration file is organized as a series of lines, +each of which begins with a single character +defining the semantics for the rest of the line. +Lines beginning with a space or a tab +are continuation lines +(although the semantics are not well defined in many places). +Blank lines and lines beginning with a sharp symbol +(`#') +are comments. +.sh 2 "R and S \*- Rewriting Rules" +.pp +The core of address parsing +are the rewriting rules. +These are an ordered production system. +.i Sendmail +scans through the set of rewriting rules +looking for a match on the left hand side +(LHS) +of the rule. +When a rule matches, +the address is replaced by the right hand side +(RHS) +of the rule. +.pp +There are several sets of rewriting rules. +Some of the rewriting sets are used internally +and must have specific semantics. +Other rewriting sets +do not have specifically assigned semantics, +and may be referenced by the mailer definitions +or by other rewriting sets. +.pp +The syntax of these two commands are: +.(b F +.b S \c +.i n +.)b +Sets the current ruleset being collected to +.i n . +If you begin a ruleset more than once +it deletes the old definition. +.(b F +.b R \c +.i lhs +.i rhs +.i comments +.)b +The +fields must be separated +by at least one tab character; +there may be embedded spaces +in the fields. +The +.i lhs +is a pattern that is applied to the input. +If it matches, +the input is rewritten to the +.i rhs . +The +.i comments +are ignored. +.pp +Macro expansions of the form +.b $ \c +.i x +are performed when the configuration file is read. +Expansions of the form +.b $& \c +.i x +are performed at run time using a somewhat less general algorithm. +This for is intended only for referencing internally defined macros +such as +.b $h +that are changed at runtime. +.sh 3 "The left hand side" +.pp +The left hand side of rewriting rules contains a pattern. +Normal words are simply matched directly. +Metasyntax is introduced using a dollar sign. +The metasymbols are: +.(b +.ta \w'\fB$=\fP\fIx\fP 'u +\fB$*\fP Match zero or more tokens +\fB$+\fP Match one or more tokens +\fB$\-\fP Match exactly one token +\fB$=\fP\fIx\fP Match any phrase in class \fIx\fP +\fB$~\fP\fIx\fP Match any word not in class \fIx\fP +.)b +If any of these match, +they are assigned to the symbol +.b $ \c +.i n +for replacement on the right hand side, +where +.i n +is the index in the LHS. +For example, +if the LHS: +.(b +$\-:$+ +.)b +is applied to the input: +.(b +UCBARPA:eric +.)b +the rule will match, and the values passed to the RHS will be: +.(b +.ta 4n +$1 UCBARPA +$2 eric +.)b +.pp +Additionally, the LHS can include +.b $@ +to match zero tokens. +This is +.i not +bound to a +.b $ \c +.i n +on the RHS, and is normally only used when it stands alone +in order to match the null input. +.sh 3 "The right hand side" +.pp +When the left hand side of a rewriting rule matches, +the input is deleted and replaced by the right hand side. +Tokens are copied directly from the RHS +unless they begin with a dollar sign. +Metasymbols are: +.(b +.ta \w'$#mailer\0\0\0'u +\fB$\fP\fIn\fP Substitute indefinite token \fIn\fP from LHS +\fB$[\fP\fIname\fP\fB$]\fP Canonicalize \fIname\fP +\fB$(\fP\fImap key\fP \fB$@\fP\fIarguments\fP \fB$:\fP\fIdefault\fP \fB$)\fP + Generalized keyed mapping function +\fB$>\fP\fIn\fP \*(lqCall\*(rq ruleset \fIn\fP +\fB$#\fP\fImailer\fP Resolve to \fImailer\fP +\fB$@\fP\fIhost\fP Specify \fIhost\fP +\fB$:\fP\fIuser\fP Specify \fIuser\fP +.)b +.pp +The +.b $ \c +.i n +syntax substitutes the corresponding value from a +.b $+ , +.b $\- , +.b $* , +.b $= , +or +.b $~ +match on the LHS. +It may be used anywhere. +.pp +A host name enclosed between +.b $[ +and +.b $] +is looked up in the host database(s) +and replaced by the canonical name\**. +.(f +\**This is actually +completely equivalent +to $(host \fIhostname\fP$). +In particular, a +.b $: +default can be used. +.)f +For example, +.q $[ftp$] +might become +.q ftp.CS.Berkeley.EDU +and +.q $[[128.32.130.2]$] +would become +.q vangogh.CS.Berkeley.EDU. +.i Sendmail +recognizes it's numeric IP address +without calling the name server +and replaces it with it's canonical name. +.pp +The +.b $( +\&... +.b $) +syntax is a more general form of lookup; +it uses a named map instead of an implicit map. +If no lookup is found, the indicated +.i default +is inserted; +if no default is specified and no lookup matches, +the value is left unchanged. +The +.i arguments +are passed to the map for possible use. +.pp +The +.b $> \c +.i n +syntax +causes the remainder of the line to be substituted as usual +and then passed as the argument to ruleset +.i n . +The final value of ruleset +.i n +then becomes +the substitution for this rule. +The +.b $> +syntax can only be used at the beginning of the right hand side; +it can be only be preceded by +.b $@ +or +.b $: . +.pp +The +.b $# +syntax should +.i only +be used in ruleset zero +or a subroutine of ruleset zero. +It causes evaluation of the ruleset to terminate immediately, +and signals to +.i sendmail +that the address has completely resolved. +The complete syntax is: +.(b +\fB$#\fP\fImailer\fP \fB$@\fP\fIhost\fP \fB$:\fP\fIuser\fP +.)b +This specifies the +{mailer, host, user} +3-tuple necessary to direct the mailer. +If the mailer is local +the host part may be omitted\**. +.(f +\**You may want to use it for special +.q "per user" +extensions. +For example, in the address +.q jgm+foo@CMU.EDU ; +the +.q +foo +part is not part of the user name, +and is passed to the local mailer for local use. +.)f +The +.i mailer +must be a single word, +but the +.i host +and +.i user +may be multi-part. +If the +.i mailer +is the builtin IPC mailer, +the +.i host +may be a colon-separated list of hosts +that are searched in order for the first working address +(exactly like MX records). +The +.i user +is later rewritten by the mailer-specific envelope rewriting set +and assigned to the +.b $u +macro. +As a special case, if the value to +.b $# +is +.q local +and the first character of the +.b $: +value is +.q @ , +the +.q @ +is stripped off, and a flag is set in the address descriptor +that causes sendmail to not do ruleset 5 processing. +.pp +Normally, a rule that matches is retried, +that is, +the rule loops until it fails. +A RHS may also be preceded by a +.b $@ +or a +.b $: +to change this behavior. +A +.b $@ +prefix causes the ruleset to return with the remainder of the RHS +as the value. +A +.b $: +prefix causes the rule to terminate immediately, +but the ruleset to continue; +this can be used to avoid continued application of a rule. +The prefix is stripped before continuing. +.pp +The +.b $@ +and +.b $: +prefixes may precede a +.b $> +spec; +for example: +.(b +.ta 8n +R$+ $: $>7 $1 +.)b +matches anything, +passes that to ruleset seven, +and continues; +the +.b $: +is necessary to avoid an infinite loop. +.pp +Substitution occurs in the order described, +that is, +parameters from the LHS are substituted, +hostnames are canonicalized, +.q subroutines +are called, +and finally +.b $# , +.b $@ , +and +.b $: +are processed. +.sh 3 "Semantics of rewriting rule sets" +.pp +There are five rewriting sets +that have specific semantics. +Four of these are related as depicted by figure 1. +.(z +.hl +.ie n \{\ +.(c + +---+ + -->| 0 |-->resolved address + / +---+ + / +---+ +---+ + / ---->| 1 |-->| S |-- + +---+ / +---+ / +---+ +---+ \e +---+ +addr-->| 3 |-->| D |-- --->| 4 |-->msg + +---+ +---+ \e +---+ +---+ / +---+ + --->| 2 |-->| R |-- + +---+ +---+ +.)c + +.\} +.el .ie !"\*(.T"" \ +\{\ +.PS +boxwid = 0.3i +boxht = 0.3i +movewid = 0.3i +moveht = 0.3i +linewid = 0.3i +lineht = 0.3i + + box invis "addr"; arrow +Box3: box "3" +A1: arrow +BoxD: box "D"; line; L1: Here +C: [ + C1: arrow; box "1"; arrow; box "S"; line; E1: Here + move to C1 down 0.5; right + C2: arrow; box "2"; arrow; box "R"; line; E2: Here + ] with .w at L1 + (0.5, 0) + move to C.e right 0.5 +L4: arrow; box "4"; arrow; box invis "msg" + line from L1 to C.C1 + line from L1 to C.C2 + line from C.E1 to L4 + line from C.E2 to L4 + move to BoxD.n up 0.6; right +Box0: arrow; box "0" + arrow; box invis "resolved address" width 1.3 + line from 1/3 of the way between A1 and BoxD.w to Box0 +.PE +.\} +.el .sp 2i +.ce +Figure 1 \*- Rewriting set semantics +.(c +D \*- sender domain addition +S \*- mailer-specific sender rewriting +R \*- mailer-specific recipient rewriting +.)c +.hl +.)z +.pp +Ruleset three +should turn the address into +.q "canonical form." +This form should have the basic syntax: +.(b +local-part@host-domain-spec +.)b +Ruleset three +is applied by +.i sendmail +before doing anything with any address. +.pp +If no +.q @ +sign is specified, +then the +host-domain-spec +.i may +be appended (box +.q D +in Figure 1) +from the +sender address +(if the +.b C +flag is set in the mailer definition +corresponding to the +.i sending +mailer). +.pp +Ruleset zero +is applied after ruleset three +to addresses that are going to actually specify recipients. +It must resolve to a +.i "{mailer, host, user}" +triple. +The +.i mailer +must be defined in the mailer definitions +from the configuration file. +The +.i host +is defined into the +.b $h +macro +for use in the argv expansion of the specified mailer. +.pp +Rulesets one and two +are applied to all sender and recipient addresses respectively. +They are applied before any specification +in the mailer definition. +They must never resolve. +.pp +Ruleset four is applied to all addresses +in the message. +It is typically used +to translate internal to external form. +.sh 3 "IPC mailers" +.pp +Some special processing occurs +if the ruleset zero resolves to an IPC mailer +(that is, a mailer that has +.q [IPC] +listed as the Path in the +.b M +configuration line. +The host name passed after +.q $@ +has MX expansion performed; +this looks the name up in DNS to find alternate delivery sites. +.pp +The host name can also be provided as a dotted quad in square brackets; +for example: +.(b +[128.32.149.78] +.)b +This causes direct conversion of the numeric value +to a TCP/IP host address. +.pp +The host name passed in after the +.q $@ +may also be a colon-separated list of hosts. +Each is separately MX expanded and the results are concatenated +to make (essentially) one long MX list. +The intent here is to create +.q fake +MX records that are not published in DNS +for private internal networks. +.pp +As a final special case, the host name can be passed in +as a text string +in square brackets: +.(b +[ucbvax.berkeley.edu] +.)b +This form avoids the MX mapping. +.b N.B.: +.i +This is intended only for situations where you have a network firewall +or other host that will do special processing for all your mail, +so that your MX record points to a gateway machine; +this machine could then do direct delivery to machines +within your local domain. +Use of this feature directly violates RFC 1123 section 5.3.5: +it should not be used lightly. +.r +.sh 2 "D \*- Define Macro" +.pp +Macros are named with a single character +or with a word in {braces}. +Single character names may be selected from the entire ASCII set, +but user-defined macros +should be selected from the set of upper case letters only. +Lower case letters +and special symbols +are used internally. +Long names beginning with a lower case letter or a punctuation character +are reserved for use by sendmail, +so user-defined long macro names should begin with an upper case letter. +.pp +The syntax for macro definitions is: +.(b F +.b D \c +.i x\|val +.)b +where +.i x +is the name of the macro +(which may be a single character +or a word in braces) +and +.i val +is the value it should have. +There should be no spaces given +that do not actually belong in the macro value. +.pp +Macros are interpolated +using the construct +.b $ \c +.i x , +where +.i x +is the name of the macro to be interpolated. +This interpolation is done when the configuration file is read, +except in +.b M +lines. +The special construct +.b $& \c +.i x +can be used in +.b R +lines to get deferred interpolation. +.pp +Conditionals can be specified using the syntax: +.(b +$?x text1 $| text2 $. +.)b +This interpolates +.i text1 +if the macro +.b $x +is set, +and +.i text2 +otherwise. +The +.q else +(\c +.b $| ) +clause may be omitted. +.pp +Lower case macro names are reserved to have +special semantics, +used to pass information in or out of +.i sendmail , +and special characters are reserved to +provide conditionals, etc. +Upper case names +(that is, +.b $A +through +.b $Z ) +are specifically reserved for configuration file authors. +.pp +The following macros are defined and/or used internally by +.i sendmail +for interpolation into argv's for mailers +or for other contexts. +The ones marked \(dg are information passed into sendmail\**, +.(f +\**As of version 8.6, +all of these macros have reasonable defaults. +Previous versions required that they be defined. +.)f +the ones marked \(dd are information passed both in and out of sendmail, +and the unmarked macros are passed out of sendmail +but are not otherwise used internally. +These macros are: +.nr ii 5n +.ip $a +The origination date in RFC 822 format. +This is extracted from the Date: line. +.ip $b +The current date in RFC 822 format. +.ip $c +The hop count. +This is a count of the number of Received: lines +plus the value of the +.b \-h +command line flag. +.ip $d +The current date in UNIX (ctime) format. +.ip $e\(dg +(Obsolete; use SmtpGreetingMessage option instead.) +The SMTP entry message. +This is printed out when SMTP starts up. +The first word must be the +.b $j +macro as specified by RFC821. +Defaults to +.q "$j Sendmail $v ready at $b" . +Commonly redefined to include the configuration version number, e.g., +.q "$j Sendmail $v/$Z ready at $b" +.ip $f +The envelope sender (from) address. +.ip $g +The sender address relative to the recipient. +For example, if +.b $f +is +.q foo , +.b $g +will be +.q host!foo , +.q foo@host.domain , +or whatever is appropriate for the receiving mailer. +.ip $h +The recipient host. +This is set in ruleset 0 from the $# field of a parsed address. +.ip $i +The queue id, +e.g., +.q HAA12345 . +.ip $j\(dd +The \*(lqofficial\*(rq domain name for this site. +This is fully qualified if the full qualification can be found. +It +.i must +be redefined to be the fully qualified domain name +if your system is not configured so that information can find +it automatically. +.ip $k +The UUCP node name (from the uname system call). +.ip $l\(dg +(Obsolete; use UnixFromLine option instead.) +The format of the UNIX from line. +Unless you have changed the UNIX mailbox format, +you should not change the default, +which is +.q "From $g $d" . +.ip $m +The domain part of the \fIgethostname\fP return value. +Under normal circumstances, +.b $j +is equivalent to +.b $w.$m . +.ip $n\(dg +The name of the daemon (for error messages). +Defaults to +.q MAILER-DAEMON . +.ip $o\(dg +(Obsolete: use OperatorChars option instead.) +The set of \*(lqoperators\*(rq in addresses. +A list of characters +which will be considered tokens +and which will separate tokens +when doing parsing. +For example, if +.q @ +were in the +.b $o +macro, then the input +.q a@b +would be scanned as three tokens: +.q a, +.q @, +and +.q b. +Defaults to +.q ".:@[]" , +which is the minimum set necessary to do RFC 822 parsing; +a richer set of operators is +.q ".:%@!/[]" , +which adds support for UUCP, the %-hack, and X.400 addresses. +.ip $p +Sendmail's process id. +.ip $q\(dg +Default format of sender address. +The +.b $q +macro specifies how an address should appear in a message +when it is defaulted. +Defaults to +.q "<$g>" . +It is commonly redefined to be +.q "$?x$x <$g>$|$g$." +or +.q "$g$?x ($x)$." , +corresponding to the following two formats: +.(b +Eric Allman <eric@CS.Berkeley.EDU> +eric@CS.Berkeley.EDU (Eric Allman) +.)b +.i Sendmail +properly quotes names that have special characters +if the first form is used. +.ip $r +Protocol used to receive the message. +Set from the +.b \-p +command line flag or by the SMTP server code. +.ip $s +Sender's host name. +Set from the +.b \-p +command line flag or by the SMTP server code. +.ip $t +A numeric representation of the current time. +.ip $u +The recipient user. +.ip $v +The version number of the +.i sendmail +binary. +.ip $w\(dd +The hostname of this site. +This is the root name of this host (but see below for caveats). +.ip $x +The full name of the sender. +.ip $z +The home directory of the recipient. +.ip $_ +The validated sender address. +.pp +There are three types of dates that can be used. +The +.b $a +and +.b $b +macros are in RFC 822 format; +.b $a +is the time as extracted from the +.q Date: +line of the message +(if there was one), +and +.b $b +is the current date and time +(used for postmarks). +If no +.q Date: +line is found in the incoming message, +.b $a +is set to the current time also. +The +.b $d +macro is equivalent to the +.b $b +macro in UNIX +(ctime) +format. +.pp +The macros +.b $w , +.b $j , +and +.b $m +are set to the identity of this host. +.i Sendmail +tries to find the fully qualified name of the host +if at all possible; +it does this by calling +.i gethostname (2) +to get the current hostname +and then passing that to +.i gethostbyname (3) +which is supposed to return the canonical version of that host name.\** +.(f +\**For example, on some systems +.i gethostname +might return +.q foo +which would be mapped to +.q foo.bar.com +by +.i gethostbyname . +.)f +Assuming this is successful, +.b $j +is set to the fully qualified name +and +.b $m +is set to the domain part of the name +(everything after the first dot). +The +.b $w +macro is set to the first word +(everything before the first dot) +if you have a level 5 or higher configuration file; +otherwise, it is set to the same value as +.b $j . +If the canonification is not successful, +it is imperative that the config file set +.b $j +to the fully qualified domain name\**. +.(f +\**Older versions of sendmail didn't pre-define +.b $j +at all, so up until 8.6, +config files +.i always +had to define +.b $j . +.)f +.pp +The +.b $f +macro is the id of the sender +as originally determined; +when mailing to a specific host +the +.b $g +macro is set to the address of the sender +.ul +relative to the recipient. +For example, +if I send to +.q bollard@matisse.CS.Berkeley.EDU +from the machine +.q vangogh.CS.Berkeley.EDU +the +.b $f +macro will be +.q eric +and the +.b $g +macro will be +.q eric@vangogh.CS.Berkeley.EDU. +.pp +The +.b $x +macro is set to the full name of the sender. +This can be determined in several ways. +It can be passed as flag to +.i sendmail . +It can be defined in the +.sm NAME +environment variable. +The third choice is the value of the +.q Full-Name: +line in the header if it exists, +and the fourth choice is the comment field +of a +.q From: +line. +If all of these fail, +and if the message is being originated locally, +the full name is looked up in the +.i /etc/passwd +file. +.pp +When sending, +the +.b $h , +.b $u , +and +.b $z +macros get set to the host, user, and home directory +(if local) +of the recipient. +The first two are set from the +.b $@ +and +.b $: +part of the rewriting rules, respectively. +.pp +The +.b $p +and +.b $t +macros are used to create unique strings +(e.g., for the +.q Message-Id: +field). +The +.b $i +macro is set to the queue id on this host; +if put into the timestamp line +it can be extremely useful for tracking messages. +The +.b $v +macro is set to be the version number of +.i sendmail ; +this is normally put in timestamps +and has been proven extremely useful for debugging. +.pp +The +.b $c +field is set to the +.q "hop count," +i.e., the number of times this message has been processed. +This can be determined +by the +.b \-h +flag on the command line +or by counting the timestamps in the message. +.pp +The +.b $r +and +.b $s +fields are set to the protocol used to communicate with +.i sendmail +and the sending hostname. +They can be set together using the +.b \-p +command line flag or separately using the +.b \-M +or +.b \-oM +flags. +.pp +The +.b $_ +is set to a validated sender host name. +If the sender is running an RFC 1413 compliant IDENT server +and the receiver has the IDENT protocol turned on, +it will include the user name on that host. +.sh 2 "C and F \*- Define Classes" +.pp +Classes of phrases may be defined +to match on the left hand side of rewriting rules, +where a +.q phrase +is a sequence of characters that do not contain space characters. +For example +a class of all local names for this site +might be created +so that attempts to send to oneself +can be eliminated. +These can either be defined directly in the configuration file +or read in from another file. +Classes are named as a single letter or a word in {braces}. +Class names beginning with lower case letters +and special characters are reserved for system use. +Classes defined in config files may be given names +from the set of upper case letters for short names +or beginning with an upper case letter for long names. +.pp +The syntax is: +.(b F +.b C \c +.i c\|phrase1 +.i phrase2... +.br +.b F \c +.i c\|file +.)b +The first form defines the class +.i c +to match any of the named words. +It is permissible to split them among multiple lines; +for example, the two forms: +.(b +CHmonet ucbmonet +.)b +and +.(b +CHmonet +CHucbmonet +.)b +are equivalent. +The ``F'' form +reads the elements of the class +.i c +from the named +.i file . +.pp +Elements of classes can be accessed in rules using +.b $= +or +.b $~ . +The +.b $~ +(match entries not in class) +only matches a single word; +multi-word entries in the class are ignored in this context. +.pp +The class +.b $=w +is set to be the set of all names +this host is known by. +This can be used to match local hostnames. +.pp +The class +.b $=k +is set to be the same as +.b $k , +that is, the UUCP node name. +.pp +The class +.b $=m +is set to the set of domains by which this host is known, +initially just +.b $m . +.pp +The class +.b $=t +is set to the set of trusted users by the +.b T +configuration line. +If you want to read trusted users from a file use +.b Ft \c +.i /file/name . +.pp +The class +.b $=n +can be set to the set of MIME body types +that can never be eight to seven bit encoded. +It defaults to +.q multipart/signed . +Message types +.q message/* +and +.q multipart/* +are never encoded directly. +Multipart messages are always handled recursively. +The handling of message/* messages +are controlled by class +.b $=s . +The class +.b $=e +contains the Content-Transfer-Encodings that can be 8\(->7 bit encoded. +It is predefined to contain +.q 7bit , +.q 8bit , +and +.q binary . +The class +.b $=s +contains the set of subtypes of message that can be treated recursively. +By default it contains only +.q rfc822 . +Other +.q message/* +types cannot be 8\(->7 bit encoded. +If a message containing eight bit data is sent to a seven bit host, +and that message cannot be encoded into seven bits, +it will be stripped to 7 bits. +.pp +.i Sendmail +can be compiled to allow a +.i scanf (3) +string on the +.b F +line. +This lets you do simplistic parsing of text files. +For example, to read all the user names in your system +.i /etc/passwd +file into a class, use +.(b +FL/etc/passwd %[^:] +.)b +which reads every line up to the first colon. +.sh 2 "M \*- Define Mailer" +.pp +Programs and interfaces to mailers +are defined in this line. +The format is: +.(b F +.b M \c +.i name , +{\c +.i field =\c +.i value \|}* +.)b +where +.i name +is the name of the mailer +(used internally only) +and the +.q field=name +pairs define attributes of the mailer. +Fields are: +.(b +.ta 1i +Path The pathname of the mailer +Flags Special flags for this mailer +Sender Rewriting set(s) for sender addresses +Recipient Rewriting set(s) for recipient addresses +Argv An argument vector to pass to this mailer +Eol The end-of-line string for this mailer +Maxsize The maximum message length to this mailer +Linelimit The maximum line length in the message body +Directory The working directory for the mailer +Userid The default user and group id to run as +Nice The nice(2) increment for the mailer +Charset The default character set for 8-bit characters +Type The MTS type information (used for error messages) +.)b +Only the first character of the field name is checked. +.pp +The following flags may be set in the mailer description. +Any other flags may be used freely +to conditionally assign headers to messages +destined for particular mailers. +Flags marked with \(dg +are not interpreted by the +.i sendmail +binary; +these are the conventionally used to correlate to the flags portion +of the +.b H +line. +Flags marked with \(dd +apply to the mailers for the sender address +rather than the usual recipient mailers. +.nr ii 4n +.ip a +Run Extended SMTP (ESMTP) protocol (defined in RFCs 1651, 1652, and 1653). +This flag defaults on if the SMTP greeting message includes the word +.q ESMTP . +.ip A +Look up the user part of the address in the alias database. +Normally this is only set for local mailers. +.ip b +Force a blank line on the end of a message. +This is intended to work around some stupid versions of +/bin/mail +that require a blank line, but do not provide it themselves. +It would not normally be used on network mail. +.ip c +Do not include comments in addresses. +This should only be used if you have to work around +a remote mailer that gets confused by comments. +This strips addresses of the form +.q "Phrase <address>" +or +.q "address (Comment)" +down to just +.q address . +.ip C\(dd +If mail is +.i received +from a mailer with this flag set, +any addresses in the header that do not have an at sign +(\c +.q @ ) +after being rewritten by ruleset three +will have the +.q @domain +clause from the sender envelope address +tacked on. +This allows mail with headers of the form: +.(b +From: usera@hosta +To: userb@hostb, userc +.)b +to be rewritten as: +.(b +From: usera@hosta +To: userb@hostb, userc@hosta +.)b +automatically. +However, it doesn't really work reliably. +.ip D\(dg +This mailer wants a +.q Date: +header line. +.ip e +This mailer is expensive to connect to, +so try to avoid connecting normally; +any necessary connection will occur during a queue run. +.ip E +Escape lines beginning with +.q From +in the message with a `>' sign. +.ip f +The mailer wants a +.b \-f +.i from +flag, +but only if this is a network forward operation +(i.e., +the mailer will give an error +if the executing user +does not have special permissions). +.ip F\(dg +This mailer wants a +.q From: +header line. +.ip g +Normally, +.i sendmail +sends internally generated email (e.g., error messages) +using the null return address +as required by RFC 1123. +However, some mailers don't accept a null return address. +If necessary, +you can set the +.b g +flag to prevent +.i sendmail +from obeying the standards; +error messages will be sent as from the MAILER-DAEMON +(actually, the value of the +.b $n +macro). +.ip h +Upper case should be preserved in host names +for this mailer. +.ip I +This mailer will be speaking SMTP +to another +.i sendmail +\*- +as such it can use special protocol features. +This option is not required +(i.e., +if this option is omitted the transmission will still operate successfully, +although perhaps not as efficiently as possible). +.ip k +Normally when +.i sendmail +connects to a host via SMTP, +it checks to make sure that this isn't accidently the same host name +as might happen if +.i sendmail +is misconfigured or if a long-haul network interface is set in loopback mode. +This flag disables the loopback check. +It should only be used under very unusual circumstances. +.ip K +Currently unimplemented. +Reserved for chunking. +.ip l +This mailer is local +(i.e., +final delivery will be performed). +.ip L +Limit the line lengths as specified in RFC821. +This deprecated option should be replaced by the +.b L= +mail declaration. +For historic reasons, the +.b L +flag also sets the +.b 7 +flag. +.ip m +This mailer can send to multiple users +on the same host +in one transaction. +When a +.b $u +macro occurs in the +.i argv +part of the mailer definition, +that field will be repeated as necessary +for all qualifying users. +.ip M\(dg +This mailer wants a +.q Message-Id: +header line. +.ip n +Do not insert a UNIX-style +.q From +line on the front of the message. +.ip o +Always run as the owner of the recipient mailbox. +Normally +.i sendmail +runs as the sender for locally generated mail +or as +.q daemon +(actually, the user specified in the +.b u +option) +when delivering network mail. +The normal behaviour is required by most local mailers, +which will not allow the envelope sender address +to be set unless the mailer is running as daemon. +This flag is ignored if the +.b S +flag is set. +.ip p +Use the route-addr style reverse-path in the SMTP +.q "MAIL FROM:" +command +rather than just the return address; +although this is required in RFC821 section 3.1, +many hosts do not process reverse-paths properly. +Reverse-paths are officially discouraged by RFC 1123. +.ip P\(dg +This mailer wants a +.q Return-Path: +line. +.ip r +Same as +.b f , +but sends a +.b \-r +flag. +.ip s +Strip quote characters (" and \e) off of the address +before calling the mailer. +.ip S +Don't reset the userid +before calling the mailer. +This would be used in a secure environment +where +.i sendmail +ran as root. +This could be used to avoid forged addresses. +If the +.b U= +field is also specified, +this flag causes the user id to always be set to that user and group +(instead of leaving it as root). +.ip u +Upper case should be preserved in user names +for this mailer. +.ip U +This mailer wants UUCP-style +.q From +lines with the ugly +.q "remote from <host>" +on the end. +.ip w +The user must have a valid account on this machine, +i.e., +getpwnam +must succeed. +If not, +the mail is bounced. +This is required to get +.q \&.forward +capability. +.ip x\(dg +This mailer wants a +.q Full-Name: +header line. +.ip X +This mailer want to use the hidden dot algorithm +as specified in RFC821; +basically, +any line beginning with a dot +will have an extra dot prepended +(to be stripped at the other end). +This insures that lines in the message containing a dot +will not terminate the message prematurely. +.ip 5 +If no aliases are found for this address, +pass the address through ruleset 5 for possible alternate resolution. +This is intended to forward the mail to an alternate delivery spot. +.ip 7 +Strip all output to seven bits. +This is the default if the +.b L +flag is set. +Note that clearing this option is not +sufficient to get full eight bit data passed through +.i sendmail . +If the +.b 7 +option is set, this is essentially always set, +since the eighth bit was stripped on input. +Note that this option will only impact messages +that didn't have 8\(->7 bit MIME conversions performed. +.ip 8 +If set, +it is acceptable to send eight bit data to this mailer; +the usual attempt to do 8\(->7 bit MIME conversions will be bypassed. +.ip : +Check addresses to see if they begin +.q :include: ; +if they do, convert them to the +.q *include* +mailer. +.ip | +Check addresses to see if they begin with a `|'; +if they do, convert them to the +.q prog +mailer. +.ip / +Check addresses to see if they begin with a `/'; +if they do, convert them to the +.q *file* +mailer. +.ip @ +Look up addresses in the user database. +.pp +Configuration files prior to level 6 +assume the `A', `w', `5', `:', `|', `/', and `@' options +on the mailer named +.q local . +.pp +The mailer with the special name +.q error +can be used to generate a user error. +The (optional) host field is an exit status to be returned, +and the user field is a message to be printed. +The exit status may be numeric or one of the values +USAGE, NOUSER, NOHOST, UNAVAILABLE, SOFTWARE, TEMPFAIL, PROTOCOL, or CONFIG +to return the corresponding EX_ exit code. +For example, the entry: +.(b +$#error $@ NOHOST $: Host unknown in this domain +.)b +on the RHS of a rule +will cause the specified error to be generated +and the +.q "Host unknown" +exit status to be returned +if the LHS matches. +This mailer is only functional in rulesets zero or five. +.pp +The mailer named +.q local +.i must +be defined in every configuration file. +This is used to deliver local mail, +and is treated specially in several ways. +Additionally, three other mailers named +.q prog , +.q *file* , +and +.q *include* +may be defined to tune the delivery of messages to programs, +files, +and :include: lists respectively. +They default to: +.(b +Mprog, P=/bin/sh, F=lsD, A=sh \-c $u +M*file*, P=/dev/null, F=lsDFMPEu, A=FILE +M*include*, P=/dev/null, F=su, A=INCLUDE +.)b +.pp +The Sender and Recipient rewriting sets +may either be a simple ruleset id +or may be two ids separated by a slash; +if so, the first rewriting set is applied to envelope +addresses +and the second is applied to headers. +.pp +The Directory +is actually a colon-separated path of directories to try. +For example, the definition +.q D=$z:/ +first tries to execute in the recipient's home directory; +if that is not available, +it tries to execute in the root of the filesystem. +This is intended to be used only on the +.q prog +mailer, +since some shells (such as +.i csh ) +refuse to execute if they cannot read the home directory. +Since the queue directory is not normally readable by unprivileged users +.i csh +scripts as recipients can fail. +.pp +The Userid +specifies the default user and group id to run as, +overriding the +.b DefaultUser +option (q.v.). +If the +.b S +mailer flag is also specified, +this is the user and group to run as in all circumstances. +This may be given as +.i user:group +to set both the user and group id; +either may be an integer or a symbolic name to be looked up +in the +.i passwd +and +.i group +files respectively. +If only a symbolic user name is specified, +the group id in the +.i passwd +file for that user is used as the group id. +.pp +The Charset field +is used when converting a message to MIME; +this is the character set used in the +Content-Type: header. +If this is not set, the +.b DefaultCharset +option is used, +and if that is not set, the value +.q unknown-8bit +is used. +.b WARNING: +this field applies to the sender's mailer, +not the recipient's mailer. +For example, if the envelope sender address +lists an address on the local network +and the recipient is on an external network, +the character set will be set from the Charset= field +for the local network mailer, +not that of the external network mailer. +.pp +The Type= field +sets the type information +used in MIME error messages +as defined by +RFC XXX +(not yet published). +It is actually three values separated by slashes: +the MTA-type (that is, the description of how hosts are named), +the address type (the description of e-mail addresses), +and the diagnostic type (the description of error diagnostic codes). +Each of these must be a registered value +or begin with +.q X\- . +The default is +.q dns/rfc822/smtp . +.sh 2 "H \*- Define Header" +.pp +The format of the header lines that +.i sendmail +inserts into the message +are defined by the +.b H +line. +The syntax of this line is: +.(b F +.b H [\c +.b ? \c +.i mflags \c +.b ? ]\c +.i hname \c +.b : +.i htemplate +.)b +Continuation lines in this spec +are reflected directly into the outgoing message. +The +.i htemplate +is macro expanded before insertion into the message. +If the +.i mflags +(surrounded by question marks) +are specified, +at least one of the specified flags +must be stated in the mailer definition +for this header to be automatically output. +If one of these headers is in the input +it is reflected to the output +regardless of these flags. +.pp +Some headers have special semantics +that will be described later. +.sh 2 "O \*- Set Option" +.pp +There are a number of +global +options that +can be set from a configuration file. +Options are represented by full words; +some are also representable as single characters +for back compatibility. +The syntax of this line is: +.(b F +.b O \0 +.i option \c +.b = \c +.i value +.)b +This sets option +.i option +to be +.i value . +Note that there +.i must +be a space between the letter `O' and the name of the option. +An older version is: +.(b F +.b O \c +.i o\|value +.)b +where the option +.i o +is a single character. +Depending on the option, +.i value +may be a string, an integer, +a boolean +(with legal values +.q t , +.q T , +.q f , +or +.q F ; +the default is TRUE), +or +a time interval. +.pp +The options supported (with the old, one character names in brackets) are: +.nr ii 1i +.ip "AliasFile=\fIspec, spec, ...\fP" +[A] +Specify possible alias file(s). +Each +.i spec +should be in the format +``\c +.i class \c +.b : +.i file '' +where +.i class \c +.b : +is optional and defaults to ``implicit''. +Depending on how +.i sendmail +is compiled, valid classes are +.q implicit +(search through a compiled-in list of alias file types, +for back compatibility), +.q hash +(if +.sm NEWDB +is specified), +.q dbm +(if +.sm NDBM +is specified), +.q stab +(internal symbol table \*- not normally used +unless you have no other database lookup), +or +.q nis +(if +.sm NIS +is specified). +If a list of +.i spec s +are provided, +.i sendmail +searches them in order. +.ip AliasWait=\fItimeout\fP +[a] +If set, +wait up to +.i timeout +(units default to minutes) +for an +.q @:@ +entry to exist in the alias database +before starting up. +If it does not appear in the +.i timeout +interval +rebuild the database +(if the +.b AutoRebuildAliases +option is also set) +or issue a warning. +.ip AutoRebuildAliases +[D] +If set, +rebuild the alias database if necessary and possible. +If this option is not set, +.i sendmail +will never rebuild the alias database +unless explicitly requested +using +.b \-bi . +Not recommended \(em can cause thrashing. +.ip BlankSub=\fIc\fP +[B] +Set the blank substitution character to +.i c . +Unquoted spaces in addresses are replaced by this character. +Defaults to space (i.e., no change is made). +.ip CheckAliases +[n] +Validate the RHS of aliases when rebuilding the alias database. +.ip CheckpointInterval=\fIN\fP +[C] +Checkpoints the queue every +.i N +(default 10) +addresses sent. +If your system crashes during delivery to a large list, +this prevents retransmission to any but the last +.I N +recipients. +.ip ClassFactor=\fIfact\fP +[z] +The indicated +.i fact or +is multiplied by the message class +(determined by the Precedence: field in the user header +and the +.b P +lines in the configuration file) +and subtracted from the priority. +Thus, messages with a higher Priority: will be favored. +Defaults to 1800. +.ip ColonOkInAddr +[no short name] +If set, colons are acceptable in e-mail addresses +(e.g., +.q host:user ). +If not set, colons indicate the beginning of a RFC 822 group construct +(\c +.q "groupname: member1, member2, ... memberN;" ). +Doubled colons are always acceptable +(\c +.q nodename::user ) +and proper route-addr nesting is understood +(\c +.q <@relay:user@host> ). +Furthermore, this option defaults on if the configuration version level +is less than 6 (for back compatibility). +However, it must be off for full compatibility with RFC 822. +.ip ConnectionCacheSize=\fIN\fP +[k] +The maximum number of open connections that will be cached at a time. +The default is one. +This delays closing the current connection until +either this invocation of +.i sendmail +needs to connect to another host +or it terminates. +Setting it to zero defaults to the old behavior, +that is, connections are closed immediately. +Since this consumes file descriptors, +the connection cache should be kept small: +4 is probably a practical maximum. +.ip ConnectionCacheTimeout=\fItimeout\fP +[K] +The maximum amount of time a cached connection will be permitted to idle +without activity. +If this time is exceeded, +the connection is immediately closed. +This value should be small (on the order of ten minutes). +Before +.i sendmail +uses a cached connection, +it always sends a RSET command +to check the connection; +if this fails, it reopens the connection. +This keeps your end from failing if the other end times out. +The point of this option is to be a good network neighbor +and avoid using up excessive resources +on the other end. +The default is five minutes. +.ip DaemonPortOptions=\fIoptions\fP +[O] +Set server SMTP options. +The options are +.i key=value +pairs. +Known keys are: +.(b +.ta 1i +Port Name/number of listening port (defaults to "smtp") +Addr Address mask (defaults INADDR_ANY) +Family Address family (defaults to INET) +Listen Size of listen queue (defaults to 10) +SndBufSize Size of TCP send buffer +RcvBufSize Size of TCP receive buffer +.)b +The +.i Addr ess +mask may be a numeric address in dot notation +or a network name. +.ip DefaultCharSet=\fIcharset\fP +[no short name] +When a message that has 8-bit characters but is not in MIME format +is converted to MIME +(see the EightBitMode option) +a character set must be included in the Content-Type: header. +This character set is normally set from the Charset= field +of the mailer descriptor. +If that is not set, the value of this option is used. +If this option is not set, the value +.q unknown-8bit +is used. +.ip DefaultUser=\fIuser:group\fP +[u] +Set the default userid for mailers to +.i user:group . +If +.i group +is omitted and +.i user +is a user name +(as opposed to a numeric user id) +the default group listed in the /etc/passwd file for that user is used +as the default group. +Both +.i user +and +.i group +may be numeric. +Mailers without the +.i S +flag in the mailer definition +will run as this user. +Defaults to 1:1. +The value can also be given as a symbolic user name.\** +.(f +\**The old +.b g +option has been combined into the +.b DefaultUser +option. +.)f +.ip DeliveryMode=\fIx\fP +[d] +Deliver in mode +.i x . +Legal modes are: +.(b +.ta 4n +i Deliver interactively (synchronously) +b Deliver in background (asynchronously) +q Just queue the message (deliver during queue run) +d Defer delivery and all map lookups (deliver during queue run) +.)b +Defaults to ``b'' if no option is specified, +``i'' if it is specified but given no argument +(i.e., ``Od'' is equivalent to ``Odi''). +The +.b \-v +command line flag sets this to +.b i . +.ip DialDelay=\fIsleeptime\fP +[no short name] +Dial-on-demand network connections can see timeouts +if a connection is opened before the call is set up. +If this is set to an interval and a connection times out +on the first connection being attempted +.i sendmail +will sleep for this amount of time and try again. +This should give your system time to establish the connection +to your service provider. +Units default to seconds, so +.q DialDelay=5 +uses a five second delay. +Defaults to zero +(no retry). +.ip DontExpandCnames +[no short name] +The standards say that all host addresses used in a mail message +must be fully canonical. +For example, if your host is named +.q Cruft.Foo.ORG +and also has an alias of +.q FTP.Foo.ORG , +the former name must be used at all times. +This is enforced during host name canonification +($[ ... $] lookups). +If this option is set, the protocols are ignored and the +.q wrong +thing is done. +However, the IETF is moving toward changing this standard, +so the behaviour may become acceptable. +Please note that hosts downstream may still rewrite the address +to be the true canonical name however. +.ip DontInitGroups +[no short name] +If set, +.i sendmail +will avoid using the initgroups(3) call. +If you are running NIS, +this causes a sequential scan of the groups.byname map, +which can cause your NIS server to be badly overloaded in a large domain. +The cost of this is that the only group found for users +will be their primary group (the one in the password file), +which will make file access permissions somewhat more restrictive. +Has no effect on systems that don't have group lists. +.ip DontPruneRoutes +[R] +Normally, +.i sendmail +tries to eliminate any unnecessary explicit routes +when sending an error message +(as discussed in RFC 1123 \(sc 5.2.6). +For example, +when sending an error message to +.(b +<@known1,@known2,@known3:user@unknown> +.)b +.i sendmail +will strip off the +.q @known1,@known2 +in order to make the route as direct as possible. +However, if the +.b R +option is set, this will be disabled, +and the mail will be sent to the first address in the route, +even if later addresses are known. +This may be useful if you are caught behind a firewall. +.ip EightBitMode=\fIaction\fP +[8] +Set handling of eight-bit data. +There are two kinds of eight-bit data: +that declared as such using the +.b BODY=8BITMIME +ESMTP declaration or the +.b \-B8BITMIME +command line flag, +and undeclared 8-bit data, that is, +input that just happens to be eight bits. +There are three basic operations that can happen: +undeclared 8-bit data can be automatically converted to 8BITMIME, +undeclared 8-bit data can be passed as-is without conversion to MIME +(``just send 8''), +and declared 8-bit data can be converted to 7-bits +for transmission to a non-8BITMIME mailer. +The possible +.i action s +are: +.(b +.\" r Reject undeclared 8-bit data; +.\" don't convert 8BITMIME\(->7BIT (``reject'') + s Reject undeclared 8-bit data (``strict'') +.\" do convert 8BITMIME\(->7BIT (``strict'') +.\" c Convert undeclared 8-bit data to MIME; +.\" don't convert 8BITMIME\(->7BIT (``convert'') + m Convert undeclared 8-bit data to MIME (``mime'') +.\" do convert 8BITMIME\(->7BIT (``mime'') +.\" j Pass undeclared 8-bit data; +.\" don't convert 8BITMIME\(->7BIT (``just send 8'') + p Pass undeclared 8-bit data (``pass'') +.\" do convert 8BITMIME\(->7BIT (``pass'') +.\" a Adaptive algorithm: see below +.)b +.\"The adaptive algorithm is to accept 8-bit data, +.\"converting it to 8BITMIME only if the receiver understands that, +.\"otherwise just passing it as undeclared 8-bit data; +.\"8BITMIME\(->7BIT conversions are done. +In all cases properly declared 8BITMIME data will be converted to 7BIT +as needed. +.ip ErrorHeader=\fIfile-or-message\fP +[E] +Prepend error messages with the indicated message. +If it begins with a slash, +it is assumed to be the pathname of a file +containing a message (this is the recommended setting). +Otherwise, it is a literal message. +The error file might contain the name, email address, and/or phone number +of a local postmaster who could provide assistance +in to end users. +If the option is missing or null, +or if it names a file which does not exist or which is not readable, +no message is printed. +.ip ErrorMode=\fIx\fP +[e] +Dispose of errors using mode +.i x . +The values for +.i x +are: +.(b +p Print error messages (default) +q No messages, just give exit status +m Mail back errors +w Write back errors (mail if user not logged in) +e Mail back errors and give zero exit stat always +.)b +.ip FallbackMXhost=\fIfallbackhost\fP +[V] +If specified, the +.i fallbackhost +acts like a very low priority MX +on every host. +This is intended to be used by sites with poor network connectivity. +.ip ForkEachJob +[Y] +If set, +deliver each job that is run from the queue in a separate process. +Use this option if you are short of memory, +since the default tends to consume considerable amounts of memory +while the queue is being processed. +.ip ForwardPath=\fIpath\fP +[J] +Set the path for searching for users' .forward files. +The default is +.q $z/.forward . +Some sites that use the automounter may prefer to change this to +.q /var/forward/$u +to search a file with the same name as the user in a system directory. +It can also be set to a sequence of paths separated by colons; +.i sendmail +stops at the first file it can successfully and safely open. +For example, +.q /var/forward/$u:$z/.forward +will search first in /var/forward/\c +.i username +and then in +.i ~username /.forward +(but only if the first file does not exist). +.ip HelpFile=\fIfile\fP +[H] +Specify the help file +for SMTP. +.ip HoldExpensive +[c] +If an outgoing mailer is marked as being expensive, +don't connect immediately. +This requires that queueing be compiled in, +since it will depend on a queue run process to +actually send the mail. +.ip IgnoreDots +[i] +Ignore dots in incoming messages. +This is always disabled (that is, dots are always accepted) +when reading SMTP mail. +.ip LogLevel=\fIn\fP +[L] +Set the default log level to +.i n . +Defaults to 9. +.ip M\fIx\|value\fP +[no long version] +Set the macro +.i x +to +.i value . +This is intended only for use from the command line. +The +.b \-M +flag is preferred. +.ip MatchGECOS +[G] +Allow fuzzy matching on the GECOS field. +If this flag is set, +and the usual user name lookups fail +(that is, there is no alias with this name and a +.i getpwnam +fails), +sequentially search the password file +for a matching entry in the GECOS field. +This also requires that MATCHGECOS +be turned on during compilation. +This option is not recommended. +.ip MaxHopCount=\fIN\fP +[h] +The maximum hop count. +Messages that have been processed more than +.i N +times are assumed to be in a loop and are rejected. +Defaults to 25. +.ip MaxHostStatAge=\fIage\fP +[no short name] +Not yet implemented. +This option specifies how long host status information will be retained. +For example, if a host is found to be down, +connections to that host will not be retried for this interval. +The units default to minutes. +.ip MaxQueueRunSize=\fIN\fP +[no short name] +The maximum number of jobs that will be processed +in a single queue run. +If not set, there is no limit on the size. +If you have very large queues or a very short queue run interval +this could be unstable. +However, since the first +.i N +jobs in queue directory order are run (rather than the +.i N +highest priority jobs) +this should be set as high as possible to avoid +.q losing +jobs that happen to fall late in the queue directory. +.ip MeToo +[m] +Send to me too, +even if I am in an alias expansion. +.ip MaxMessageSize=\fIN\fP +[no short name] +Specify the maximum message size +to be advertised in the ESMTP EHLO response. +Messages larger than this will be rejected. +.ip MinFreeBlocks=\fIN\fP +[b] +Insist on at least +.i N +blocks free on the filesystem that holds the queue files +before accepting email via SMTP. +If there is insufficient space +.i sendmail +gives a 452 response +to the MAIL command. +This invites the sender to try again later. +.ip MinQueueAge=\fPage\fP +[no short name] +Don't process any queued jobs +that have been in the queue less than the indicated time interval. +This is intended to allow you to get responsiveness +by processing the queue fairly frequently +without thrashing your system by trying jobs too often. +The default units are minutes. +.ip NoRecipientAction +[no short name] +The action to take when you receive a message that has no valid +recipient headers (To:, Cc:, Bcc:). +It can be +.b None +to pass the message on unmodified, +which violates the protocol, +.b Add-To +to add a To: header with any recipients it can find in the envelope +(which might expose Bcc: recipients), +.b Add-Apparently-To +to add an Apparently-To: header +(this is only for back-compatibility +and is officially deprecated), +.b Add-To-Undisclosed +to add a header +.q "To: undisclosed-recipients:;" +to make the header legal without disclosing anything, +or +.b Add-Bcc +to add an empty Bcc: header. +.ip OldStyleHeaders +[o] +Assume that the headers may be in old format, +i.e., +spaces delimit names. +This actually turns on +an adaptive algorithm: +if any recipient address contains a comma, parenthesis, +or angle bracket, +it will be assumed that commas already exist. +If this flag is not on, +only commas delimit names. +Headers are always output with commas between the names. +Defaults to off. +.ip OperatorChars=\fIcharlist\fP +[$o macro] +The list of characters that are considered to be +.q operators , +that is, characters that delimit tokens. +All operator characters are tokens by themselves; +sequences of non-operator characters are also tokens. +White space characters separate tokens +but are not tokens themselves \(em for example, +.q AAA.BBB +has three tokens, but +.q "AAA BBB" +has two. +If not set, OperatorChars defaults to +.q \&.\|:\|@\|[\|] ; +additionally, the characters +.q (\|)\|<\|>\|,\|; +are always operators. +.ip PostmasterCopy=\fIpostmaster\fP +[P] +If set, +copies of error messages will be sent to the named +.i postmaster . +Only the header of the failed message is sent. +Since most errors are user problems, +this is probably not a good idea on large sites, +and arguably contains all sorts of privacy violations, +but it seems to be popular with certain operating systems vendors. +Defaults to no postmaster copies. +.ip PrivacyOptions=\fI\|opt,opt,...\fP +[p] +Set the privacy +.i opt ions. +``Privacy'' is really a misnomer; +many of these are just a way of insisting on stricter adherence +to the SMTP protocol. +The +.i opt ions +can be selected from: +.(b +.ta \w'needvrfyhelo'u+3n +public Allow open access +needmailhelo Insist on HELO or EHLO command before MAIL +needexpnhelo Insist on HELO or EHLO command before EXPN +noexpn Disallow EXPN entirely +needvrfyhelo Insist on HELO or EHLO command before VRFY +novrfy Disallow VRFY entirely +restrictmailq Restrict mailq command +restrictqrun Restrict \-q command line flag +noreceipts Don't return success DSNs +goaway Disallow essentially all SMTP status queries +authwarnings Put X-Authentication-Warning: headers in messages +.)b +The +.q goaway +pseudo-flag sets all flags except +.q restrictmailq +and +.q restrictqrun . +If mailq is restricted, +only people in the same group as the queue directory +can print the queue. +If queue runs are restricted, +only root and the owner of the queue directory +can run the queue. +Authentication Warnings add warnings about various conditions +that may indicate attempts to spoof the mail system, +such as using an non-standard queue directory. +.ip QueueDirectory=\fIdir\fP +[Q] +Use the named +.i dir +as the queue directory. +.ip QueueFactor=\fIfactor\fP +[q] +Use +.i factor +as the multiplier in the map function +to decide when to just queue up jobs rather than run them. +This value is divided by the difference between the current load average +and the load average limit +(\c +.b QueueLA +option) +to determine the maximum message priority +that will be sent. +Defaults to 600000. +.ip QueueLA=\fILA\fP +[x] +When the system load average exceeds +.i LA , +just queue messages +(i.e., don't try to send them). +Defaults to 8. +.ip QueueSortOrder=\fIalgorithm\fP +[no short name] +Sets the +.i algorithm +used for sorting the queue. +Only the first character of the value is used. +Legal values are +.q host +(to order by the name of the first host name of the first recipient) +and +.q priority +(to order strictly by message priority). +Host ordering makes better use of the connection cache, +but may tend to process low priority messages +that go to a single host +over high priority messages that go to several hosts; +it probably shouldn't be used on slow network links. +Priority ordering is the default. +.ip ResolverOptions=\fIoptions\fP +[I] +Set resolver options. +Values can be set using +.b + \c +.i flag +and cleared using +.b \- \c +.i flag ; +the +.i flag s +can be +.q debug , +.q aaonly , +.q usevc , +.q primary , +.q igntc , +.q recurse , +.q defnames , +.q stayopen , +or +.q dnsrch . +The string +.q HasWildcardMX +(without a +.b + +or +.b \- ) +can be specified to turn off matching against MX records +when doing name canonifications. +.b N.B. +Prior to 8.7, +this option indicated that the name server be responding +in order to accept addresses. +This has been replaced by checking to see +if the +.q dns +method is listed in the service switch entry for the +.q hosts +service. +.ip SmtpGreetingMessage=\fImessage\fP +[$e macro] +The message printed when the SMTP server starts up. +Defaults to +.q "$j Sendmail $v ready at $b". +.ip Timeout.\fItype\fP=\|\fItimeout\fP +[r; subsumes old T option as well] +Set timeout values. +The actual timeout is indicated by the +.i type . +The recognized timeouts and their default values, and their +minimum values specified in RFC 1123 section 5.3.2 are: +.(b +.ta \w'datafinal'u+3n +initial wait for initial greeting message [5m, 5m] +helo reply to HELO or EHLO command [5m, none] +mail reply to MAIL command [10m, 5m] +rcpt reply to RCPT command [1h, 5m] +datainit reply to DATA command [5m, 2m] +datablock data block read [1h, 3m] +datafinal reply to final ``.'' in data [1h, 10m] +rset reply to RSET command [5m, none] +quit reply to QUIT command [2m, none] +misc reply to NOOP and VERB commands [2m, none] +ident IDENT protocol timeout [30s, none] +fileopen\(dg timeout on opening .forward and :include: files [60s, none] +command\(dg command read [1h, 5m] +queuereturn\(dg how long until a message is returned [5d, 5d] +queuewarn\(dg how long until a warning is sent [none, none] +.)b +All but those marked with a dagger (\(dg) +apply to client SMTP. +If the message is submitted using the +.sm NOTIFY +.sm SMTP +extension, +warning messages will only be sent if +.sm NOTIFY=DELAY +is specified. +The queuereturn and queuewarn timeouts +can be further qualified with a tag based on the Precedence: field +in the message; +they must be one of +.q urgent +(indicating a positive non-zero precedence) +.q normal +(indicating a zero precedence), or +.q non-urgent +(indicating negative precedences). +For example, setting +.q Timeout.queuewarn.urgent=1h +sets the warning timeout for urgent messages only +to one hour. +The default if no precedence is indicated +is to set the timeout for all precedences. +.ip RecipientFactor=\fIfact\fP +[y] +The indicated +.i fact or +is added to the priority (thus +.i lowering +the priority of the job) +for each recipient, +i.e., this value penalizes jobs with large numbers of recipients. +Defaults to 30000. +.ip RefuseLA=\fILA\fP +[X] +When the system load average exceeds +.i LA , +refuse incoming SMTP connections. +Defaults to 12. +.ip RetryFactor=\fIfact\fP +[Z] +The +.i fact or +is added to the priority +every time a job is processed. +Thus, +each time a job is processed, +its priority will be decreased by the indicated value. +In most environments this should be positive, +since hosts that are down are all too often down for a long time. +Defaults to 90000. +.ip SaveFromLine +[f] +Save +Unix-style +.q From +lines at the front of headers. +Normally they are assumed redundant +and discarded. +.ip SendMIMEErrors +[j] +If set, send error messages in MIME format +(see RFC1521 and RFC1344 for details). +.ip ServiceSwitchFile=\fIfilename\fP +[no short name] +If your host operating system has a service switch abstraction +(e.g., /etc/nsswitch.conf on Solaris +or /etc/svc.conf on Ultrix and DEC OSF/1) +that service will be consulted and this option is ignored. +Otherwise, this is the name of a file +that provides the list of methods used to implement particular services. +The syntax is a series of lines, +each of which is a sequence of words. +The first word is the service name, +and following words are service types. +The services that +.i sendmail +consults directly are +.q aliases +and +.q hosts. +Service types can be +.q dns , +.q nis , +.q nisplus , +or +.q files +(with the caveat that the appropriate support +must be compiled in +before the service can be referenced). +If ServiceSwitchFile is not specified, it defaults to /etc/service.switch. +If that file does not exist, the default switch is: +.(b +aliases files +hosts dns nis files +.)b +The default file is +.q /etc/service.switch . +.ip SevenBitInput +[7] +Strip input to seven bits for compatibility with old systems. +This shouldn't be necessary. +.ip StatusFile=\fIfile\fP +[S] +Log summary statistics in the named +.i file . +If not set, +no summary statistics are saved. +This file does not grow in size. +It can be printed using the +.i mailstats (8) +program. +.ip SuperSafe +[s] +Be super-safe when running things, +i.e., +always instantiate the queue file, +even if you are going to attempt immediate delivery. +.i Sendmail +always instantiates the queue file +before returning control the client +under any circumstances. +This should really +.i always +be set. +.ip TempFileMode=\fImode\fP +[F] +The file mode for queue files. +It is interpreted in octal by default. +Defaults to 0600. +.ip TimeZoneSpec=\fItzinfo\fP +[t] +Set the local time zone info to +.i tzinfo +\*- for example, +.q PST8PDT . +Actually, if this is not set, +the TZ environment variable is cleared (so the system default is used); +if set but null, the user's TZ variable is used, +and if set and non-null the TZ variable is set to this value. +.ip TryNullMXList +[w] +If this system is the +.q best +(that is, lowest preference) +MX for a given host, +its configuration rules should normally detect this situation +and treat that condition specially +by forwarding the mail to a UUCP feed, +treating it as local, +or whatever. +However, in some cases (such as Internet firewalls) +you may want to try to connect directly to that host +as though it had no MX records at all. +Setting this option causes +.i sendmail +to try this. +The downside is that errors in your configuration +are likely to be diagnosed as +.q "host unknown" +or +.q "message timed out" +instead of something more meaningful. +This option is disrecommended. +.ip UnixFromLine=\fIfromline\fP +[$l macro] +Defines the format used when +.i sendmail +must add a UNIX-style From_ line +(that is, a line beginning +.q From<space>user ). +Defaults to +.q "From $g $d" . +Don't change this unless your system uses a different UNIX mailbox format +(very unlikely). +.ip UseErrorsTo +[l] +If there is an +.q Errors-To: +header, send error messages to the addresses listed there. +They normally go to the envelope sender. +Use of this option causes +.i sendmail +to violate RFC 1123. +This option is disrecommended and deprecated. +.ip UserDatabaseSpec=\fIudbspec\fP +[U] +The user database specification. +.ip Verbose +[v] +Run in verbose mode. +If this is set, +.i sendmail +adjusts options +.b HoldExpensive +(old +.b c ) +and +.b DeliveryMode +(old +.b d ) +so that all mail is delivered completely +in a single job +so that you can see the entire delivery process. +Option +.b Verbose +should +.i never +be set in the configuration file; +it is intended for command line use only. +.lp +All options can be specified on the command line using the +\-O or \-o flag, +but most will cause +.i sendmail +to relinquish its setuid permissions. +The options that will not cause this are +MinFreeBlocks [b], +DeliveryMode [d], +ErrorMode [e], +IgnoreDots [i], +LogLevel [L], +MeToo [m], +OldStyleHeaders [o], +PrivacyOptions [p], +Timeouts [r], +SuperSafe [s], +Verbose [v], +CheckpointInterval [C], +and +SevenBitInput [7]. +Also, M (define macro) when defining the r or s macros +is also considered +.q safe . +.sh 2 "P \*- Precedence Definitions" +.pp +Values for the +.q "Precedence:" +field may be defined using the +.b P +control line. +The syntax of this field is: +.(b +\fBP\fP\fIname\fP\fB=\fP\fInum\fP +.)b +When the +.i name +is found in a +.q Precedence: +field, +the message class is set to +.i num . +Higher numbers mean higher precedence. +Numbers less than zero +have the special property +that if an error occurs during processing +the body of the message will not be returned; +this is expected to be used for +.q "bulk" +mail such as through mailing lists. +The default precedence is zero. +For example, +our list of precedences is: +.(b +Pfirst-class=0 +Pspecial-delivery=100 +Plist=\-30 +Pbulk=\-60 +Pjunk=\-100 +.)b +People writing mailing list exploders +are encouraged to use +.q "Precedence: list" . +Older versions of +.i sendmail +(which discarded all error returns for negative precedences) +didn't recognize this name, giving it a default precedence of zero. +This allows list maintainers to see error returns +on both old and new versions of +.i sendmail . +.sh 2 "V \*- Configuration Version Level" +.pp +To provide compatibility with old configuration files, +the +.b V +line has been added to define some very basic semantics +of the configuration file. +These are not intended to be long term supports; +rather, they describe compatibility features +which will probably be removed in future releases. +.pp +.b N.B.: +these version +.i levels +have nothing +to do with the version +.i number +on the files. +For example, +as of this writing +version 8 config files +(specifically, 8.7) +used version level 6 configurations. +.pp +.q Old +configuration files are defined as version level one. +Version level two files make the following changes: +.np +Host name canonification ($[ ... $]) +appends a dot if the name is recognized; +this gives the config file a way of finding out if anything matched. +(Actually, this just initializes the +.q host +map with the +.q \-a. +flag \*- you can reset it to anything you prefer +by declaring the map explicitly.) +.np +Default host name extension is consistent throughout processing; +version level one configurations turned off domain extension +(that is, adding the local domain name) +during certain points in processing. +Version level two configurations are expected to include a trailing dot +to indicate that the name is already canonical. +.np +Local names that are not aliases +are passed through a new distinguished ruleset five; +this can be used to append a local relay. +This behaviour can be prevented by resolving the local name +with an initial `@'. +That is, something that resolves to a local mailer and a user name of +.q vikki +will be passed through ruleset five, +but a user name of +.q @vikki +will have the `@' stripped, +will not be passed through ruleset five, +but will otherwise be treated the same as the prior example. +The expectation is that this might be used to implement a policy +where mail sent to +.q vikki +was handled by a central hub, +but mail sent to +.q vikki@localhost +was delivered directly. +.pp +Version level three files +allow # initiated comments on all lines. +Exceptions are backslash escaped # marks +and the $# syntax. +.pp +Version level four configurations +are completely equivalent to level three +for historical reasons. +.pp +Version level five configuration files +change the default definition of +.b $w +to be just the first component of the hostname. +.pp +Version level six configuration files +change many of the local processing options +(such as aliasing and matching the beginning of the address for +`|' characters) +to be mailer flags; +this allows fine-grained control over the special local processing. +Level six configuration files may also use long option names. +The +.b ColonOkInAddr +option (to allow colons in the local-part of addresses) +defaults +.b on +for lower numbered configuration files; +the configuration file requires some additional intelligence +to properly handle the RFC 822 group construct. +.pp +The +.b V +line may have an optional +.b / \c +.i vendor +to indicate that this configuration file uses modifications +specific to a particular vendor\**. +.(f +\**And of course, vendors are encouraged to add themselves +to the list of recognized vendors by editing the routine +.i setvendor +in +.i conf.c . +Please send e-mail to sendmail@CS.Berkeley.EDU +to register your vendor dialect. +.)f +You may use +.q /Berkeley +to emphasize that this configuration file +uses the Berkeley dialect of +.i sendmail . +.sh 2 "K \*- Key File Declaration" +.pp +Special maps can be defined using the line: +.(b +Kmapname mapclass arguments +.)b +The +.i mapname +is the handle by which this map is referenced in the rewriting rules. +The +.i mapclass +is the name of a type of map; +these are compiled in to +.i sendmail . +The +.i arguments +are interpreted depending on the class; +typically, +there would be a single argument naming the file containing the map. +.pp +Maps are referenced using the syntax: +.(b +$( \fImap\fP \fIkey\fP $@ \fIarguments\fP $: \fIdefault\fP $) +.)b +where either or both of the +.i arguments +or +.i default +portion may be omitted. +The +.i "$@ arguments" +may appear more than once. +The indicated +.i key +and +.i arguments +are passed to the appropriate mapping function. +If it returns a value, it replaces the input. +If it does not return a value and the +.i default +is specified, the +.i default +replaces the input. +Otherwise, the input is unchanged. +.pp +During replacement of either a map value or default +the string +.q %\fIn\fP +(where +.i n +is a digit) +is replaced by the corresponding +.i argument . +Argument zero +is always the database key. +For example, the rule +.(b +.ta 1.5i +R$\- ! $+ $: $(uucp $1 $@ $2 $: %1 @ %0 . UUCP $) +.)b +Looks up the UUCP name in a (user defined) UUCP map; +if not found it turns it into +.q \&.UUCP +form. +The database might contain records like: +.(b +decvax %1@%0.DEC.COM +research %1@%0.ATT.COM +.)b +.pp +The built in map with both name and class +.q host +is the host name canonicalization lookup. +Thus, +the syntax: +.(b +$(host \fIhostname\fP$) +.)b +is equivalent to: +.(b +$[\fIhostname\fP$] +.)b +.pp +There are many defined classes. +.ip dbm +Database lookups using the ndbm(3) library. +.i Sendmail +must be compiled with +.b NDBM +defined. +.ip btree +Database lookups using the btree interface to the Berkeley db(3) library. +.i Sendmail +must be compiled with +.b NEWDB +defined. +.ip hash +Database lookups using the hash interface to the Berkeley db(3) library. +.i Sendmail +must be compiled with +.b NEWDB +defined. +.ip nis +NIS lookups. +.i Sendmail +must be compiled with +.b NIS +defined. +.ip nisplus +NIS+ lookups. +.i Sendmail +must be compiled with +.b NISPLUS +defined. +The argument is the name of the table to use for lookups, +and the +.b \-k +and +.b \-v +flags may be used to set the key and value columns respectively. +.ip hesiod +Hesiod lookups. +.i Sendmail +must be compiled with +.b HESIOD +defined. +.ip netinfo +NeXT NetInfo lookups. +.i Sendmail +must be compiled with +.b NETINFO +defined. +.ip text +Text file lookups. +The format of the text file is defined by the +.b \-k +(key field number), +.b \-v +(value field number), +and +.b \-z +(field delimiter) +flags. +.ip stab +Internal symbol table lookups. +Used internally for aliasing. +.ip implicit +Really should be called +.q alias +\(em this is used to get the default lookups +for alias files, +and is the default if no class is specified for alias files. +.ip user +Looks up users using +.i getpwnam (3). +The +.b \-v +flag can be used to specify the name of the field to return +(although this is normally used only to check the existence +of a user). +.ip host +Canonifies host domain names. +Given a host name it calls the name server +to find the canonical name for that host. +.ip sequence +The arguments on the `K' line are a list of maps; +the resulting map searches the argument maps in order +until it finds a match for the indicated key. +For example, if the key definition is: +.(b +Kmap1 ... +Kmap2 ... +Kseqmap sequence map1 map2 +.)b +then a lookup against +.q seqmap +first does a lookup in map1. +If that is found, it returns immediately. +Otherwise, the same key is used for map2. +.ip switch +Much like the +.q sequence +map except that the order of maps is determined by the service switch. +The argument is the name of the service to be looked up; +the values from the service switch are appended to the map name +to create new map names. +For example, consider the key definition: +.(b +Kali switch aliases +.)b +together with the service switch entry: +.(b +aliases nis files +.)b +This causes a query against the map +.q ali +to search maps named +.q ali.nis +and +.q ali.files +in that order. +.ip dequote +Strip double quotes (") from a name. +It does not strip backslashes, +and will not strip quotes if the resulting string +would contain unscannable syntax +(that is, basic errors like unbalanced angle brackets; +more sophisticated errors such as unknown hosts are not checked). +The intent is for use when trying to accept mail from systems such as +DECnet +that routinely quote odd syntax such as +.(b +"49ers::ubell" +.)b +A typical usage is probably something like: +.(b +Kdequote dequote + +\&... + +R$\- $: $(dequote $1 $) +R$\- $+ $: $>3 $1 $2 +.)b +Care must be taken to prevent unexpected results; +for example, +.(b +"|someprogram < input > output" +.)b +will have quotes stripped, +but the result is probably not what you had in mind. +Fortunately these cases are rare. +.pp +Most of these accept as arguments the same optional flags +and a filename +(or a mapname for NIS; +the filename is the root of the database path, +so that +.q .db +or some other extension appropriate for the database type +will be added to get the actual database name). +Known flags are: +.ip "\-o" +Indicates that this map is optional \*- that is, +if it cannot be opened, +no error is produced, +and +.i sendmail +will behave as if the map existed but was empty. +.ip "\-N, \-O" +If neither +.b \-N +or +.b \-O +are specified, +.i sendmail +uses an adaptive algorithm to decide whether or not to look for null bytes +on the end of keys. +It starts by trying both; +if it finds any key with a null byte it never tries again without a null byte +and vice versa. +If +.b \-N +is specified it never tries without a null byte and +if +.b \-O +is specified it never tries with a null byte. +Setting one of +these can speed matches but are never necessary. +If both +.b \-N +and +.b \-O +are specified, +.i sendmail +will never try any matches at all \(em +that is, everything will appear to fail. +.ip "\-a\fIx\fP" +Append the string +.i x +on successful matches. +For example, the default +.i host +map appends a dot on successful matches. +.ip "\-f" +Do not fold upper to lower case before looking up the key. +.ip "\-m" +Match only (without replacing the value). +If you only care about the existence of a key and not the value +(as you might when searching the NIS map +.q hosts.byname +for example), +this flag prevents the map from substituting the value. +However, +The \-a argument is still appended on a match, +and the default is still taken if the match fails. +.ip "\-k\fIkeycol\fP" +The key column name (for NIS+) or number +(for text lookups). +.ip "\-v\fIvalcol\fP" +The value column name (for NIS+) or number +(for text lookups). +.ip "\-z\fIdelim\fP" +The column delimiter (for text lookups). +It can be a single character or one of the special strings +.q \|\en +or +.q \|\et +to indicate newline or tab respectively. +If omitted entirely, +the column separator is any sequence of whitespace. +.ip "\-s\fIspacesub\fP +For the dequote map only, +the character to use to replace space characters +after a successful dequote. +.pp +The +.i dbm +map appends the strings +.q \&.pag +and +.q \&.dir +to the given filename; +the two +.i db -based +maps append +.q \&.db . +For example, the map specification +.(b +Kuucp dbm \-o \-N /usr/lib/uucpmap +.)b +specifies an optional map named +.q uucp +of class +.q dbm ; +it always has null bytes at the end of every string, +and the data is located in +/usr/lib/uucpmap.{dir,pag}. +.pp +The program +.i makemap (8) +can be used to build any of the three database-oriented maps. +It takes the following flags: +.ip \-f +Do not fold upper to lower case in the map. +.ip \-N +Include null bytes in keys. +.ip \-o +Append to an existing (old) file. +.ip \-r +Allow replacement of existing keys; +normally, re-inserting an existing key is an error. +.ip \-v +Print what is happening. +.lp +The +.i sendmail +daemon does not have to be restarted to read the new maps +as long as you change them in place; +file locking is used so that the maps won't be read +while they are being updated.\** +.(f +\**That is, don't create new maps and then use +.i mv (1) +to move them into place. +Since the maps are already open +the new maps will never be seen. +.)f +.pp +New classes can be added in the routine +.b setupmaps +in file +.b conf.c . +.sh 2 "The User Database" +.pp +If you have a version of +.i sendmail +with the user database package +compiled in, +the handling of sender and recipient addresses +is modified. +.pp +The location of this database is controlled with the +.b UserDatabaseSpec +option. +.sh 3 "Structure of the user database" +.pp +The database is a sorted (BTree-based) structure. +User records are stored with the key: +.(b +\fIuser-name\fP\fB:\fP\fIfield-name\fP +.)b +The sorted database format ensures that user records are clustered together. +Meta-information is always stored with a leading colon. +.pp +Field names define both the syntax and semantics of the value. +Defined fields include: +.nr ii 1i +.ip maildrop +The delivery address for this user. +There may be multiple values of this record. +In particular, +mailing lists will have one +.i maildrop +record for each user on the list. +.ip "mailname" +The outgoing mailname for this user. +For each outgoing name, +there should be an appropriate +.i maildrop +record for that name to allow return mail. +See also +.i :default:mailname . +.ip mailsender +Changes any mail sent to this address to have the indicated envelope sender. +This is intended for mailing lists, +and will normally be the name of an appropriate -request address. +It is very similar to the owner-\c +.i list +syntax in the alias file. +.ip fullname +The full name of the user. +.ip office-address +The office address for this user. +.ip office-phone +The office phone number for this user. +.ip office-fax +The office FAX number for this user. +.ip home-address +The home address for this user. +.ip home-phone +The home phone number for this user. +.ip home-fax +The home FAX number for this user. +.ip project +A (short) description of the project this person is affiliated with. +In the University this is often just the name of their graduate advisor. +.ip plan +A pointer to a file from which plan information can be gathered. +.pp +As of this writing, +only a few of these fields are actually being used by +.i sendmail : +.i maildrop +and +.i mailname . +A +.i finger +program that uses the other fields is planned. +.sh 3 "User database semantics" +.pp +When the rewriting rules submit an address to the local mailer, +the user name is passed through the alias file. +If no alias is found (or if the alias points back to the same address), +the name (with +.q :maildrop +appended) +is then used as a key in the user database. +If no match occurs (or if the maildrop points at the same address), +forwarding is tried. +.pp +If the first token of the user name returned by ruleset 0 +is an +.q @ +sign, the user database lookup is skipped. +The intent is that the user database will act as a set of defaults +for a cluster (in our case, the Computer Science Division); +mail sent to a specific machine should ignore these defaults. +.pp +When mail is sent, +the name of the sending user is looked up in the database. +If that user has a +.q mailname +record, +the value of that record is used as their outgoing name. +For example, I might have a record: +.(b +eric:mailname Eric.Allman@CS.Berkeley.EDU +.)b +This would cause my outgoing mail to be sent as Eric.Allman. +.pp +If a +.q maildrop +is found for the user, +but no corresponding +.q mailname +record exists, +the record +.q :default:mailname +is consulted. +If present, this is the name of a host to override the local host. +For example, in our case we would set it to +.q CS.Berkeley.EDU . +The effect is that anyone known in the database +gets their outgoing mail stamped as +.q user@CS.Berkeley.EDU , +but people not listed in the database use the local hostname. +.sh 3 "Creating the database\**" +.(f +\**These instructions are known to be incomplete. +A future version of the user database is planned +including things such as finger service \*- and good documentation. +.)f +.pp +The user database is built from a text file +using the +.i makemap +utility +(in the distribution in the makemap subdirectory). +The text file is a series of lines corresponding to userdb records; +each line has a key and a value separated by white space. +The key is always in the format described above \*- +for example: +.(b +eric:maildrop +.)b +This file is normally installed in a system directory; +for example, it might be called +.i /etc/userdb . +To make the database version of the map, run the program: +.(b +makemap btree /etc/userdb.db < /etc/userdb +.)b +Then create a config file that uses this. +For example, using the V8 M4 configuration, include the +following line in your .mc file: +.(b +define(\`confUSERDB_SPEC\', /etc/userdb.db) +.)b +.sh 1 "OTHER CONFIGURATION" +.pp +There are some configuration changes that can be made by +recompiling +.i sendmail . +This section describes what changes can be made +and what has to be modified to make them. +In most cases this should be unnecessary +unless you are porting +.i sendmail +to a new environment. +.sh 2 "Parameters in src/Makefile" +.pp +These parameters are intended to describe the compilation environment, +not site policy, +and should normally be defined in src/Makefile. +.ip NDBM +If set, +the new version of the DBM library +that allows multiple databases will be used. +If neither NDBM nor NEWDB are set, +a much less efficient method of alias lookup is used. +.ip NEWDB +If set, use the new database package from Berkeley (from 4.4BSD). +This package is substantially faster than DBM or NDBM. +If NEWDB and NDBM are both set, +.i sendmail +will read DBM files, +but will create and use NEWDB files. +.ip NIS +Include support for NIS. +If set together with +.i both +NEWDB and NDBM, +.i sendmail +will create both DBM and NEWDB files if and only if +an alias file includes the substring +.q /yp/ +in the name. +This is intended for compatibility with Sun Microsystems' +.i mkalias +program used on YP masters. +.ip NISPLUS +Compile in support for NIS+. +.ip NETINFO +Compile in support for NetInfo (NeXT stations). +.ip HESIOD +Compile in support for Hesiod. +.ip _PATH_SENDMAILCF +The pathname of the sendmail.cf file. +.ip _PATH_SENDMAILPID +The pathname of the sendmail.pid file. +.pp +There are also several compilation flags to indicate the environment +such as +.q _AIX3 +and +.q _SCO_unix_ . +See the READ_ME +file for the latest scoop on these flags. +.sh 2 "Parameters in src/conf.h" +.pp +Parameters and compilation options +are defined in conf.h. +Most of these need not normally be tweaked; +common parameters are all in sendmail.cf. +However, the sizes of certain primitive vectors, etc., +are included in this file. +The numbers following the parameters +are their default value. +.pp +This document is not the best source of information +for compilation flags in conf.h \(em +see src/READ_ME or src/conf.h itself. +.nr ii 1.2i +.ip "MAXLINE [2048]" +The maximum line length of any input line. +If message lines exceed this length +they will still be processed correctly; +however, header lines, +configuration file lines, +alias lines, +etc., +must fit within this limit. +.ip "MAXNAME [256]" +The maximum length of any name, +such as a host or a user name. +.ip "MAXPV [40]" +The maximum number of parameters to any mailer. +This limits the number of recipients that may be passed in one transaction. +It can be set to any arbitrary number above about 10, +since +.i sendmail +will break up a delivery into smaller batches as needed. +A higher number may reduce load on your system, however. +.ip "MAXATOM [100]" +The maximum number of atoms +(tokens) +in a single address. +For example, +the address +.q "eric@CS.Berkeley.EDU" +is seven atoms. +.ip "MAXMAILERS [25]" +The maximum number of mailers that may be defined +in the configuration file. +.ip "MAXRWSETS [200]" +The maximum number of rewriting sets +that may be defined. +The first half of these are reserved for numeric specification +(e.g., ``S92''), +while the upper half are reserved for auto-numbering +(e.g., ``Sfoo''). +Thus, with a value of 200 an attempt to use ``S99'' will succeed, +but ``S100'' will fail. +.ip "MAXPRIORITIES [25]" +The maximum number of values for the +.q Precedence: +field that may be defined +(using the +.b P +line in sendmail.cf). +.ip "MAXUSERENVIRON [100]" +The maximum number of items in the user environment +that will be passed to subordinate mailers. +.ip "MAXMXHOSTS [20]" +The maximum number of MX records we will accept for any single host. +.ip "MAXALIASDB [12]" +The maximum number of alias databases that can be open at any time. +Note that there may also be an open file limit. +.ip "MAXMAPSTACK [12]" +The maximum number of maps that may be "stacked" in a +.b sequence +class map. +.ip "MAXMIMEARGS [20]" +The maximum number of arguments in a MIME Content-Type: header; +additional arguments will be ignored. +.ip "MAXMIMENESTING [20]" +The maximum depth to which MIME messages may be nested +(that is, nested Message or Multipart documents; +this does not limit the number of components in a single Multipart document). +.lp +A number of other compilation options exist. +These specify whether or not specific code should be compiled in. +Ones marked with \(dg +are 0/1 valued. +.nr ii 1.2i +.ip NETINET\(dg +If set, +support for Internet protocol networking is compiled in. +Previous versions of +.i sendmail +referred to this as +.sm DAEMON ; +this old usage is now incorrect. +Defaults on; +turn it off in the Makefile +if your system doesn't support the Internet protocols. +.ip NETISO\(dg +If set, +support for ISO protocol networking is compiled in +(it may be appropriate to #define this in the Makefile instead of conf.h). +.ip LOG +If set, +the +.i syslog +routine in use at some sites is used. +This makes an informational log record +for each message processed, +and makes a higher priority log record +for internal system errors. +.b "STRONGLY RECOMMENDED" +\(em if you want no logging, turn it off in the configuration file. +.ip MATCHGECOS\(dg +Compile in the code to do ``fuzzy matching'' on the GECOS field +in /etc/passwd. +This also requires that the +.b MatchGECOS +option be turned on. +.ip NAMED_BIND\(dg +Compile in code to use the +Berkeley Internet Name Domain (BIND) server +to resolve TCP/IP host names. +.ip NOTUNIX +If you are using a non-UNIX mail format, +you can set this flag to turn off special processing +of UNIX-style +.q "From " +lines. +.ip QUEUE +This flag should be set to compile in the queueing code. +If this is not set, +mailers must accept the mail immediately +or it will be returned to the sender. +.ip SMTP +If set, +the code to handle user and server SMTP will be compiled in. +This is only necessary if your machine has some mailer +that speaks SMTP +(this means most machines everywhere). +.ip USERDB\(dg +Include the +.b experimental +Berkeley user information database package. +This adds a new level of local name expansion +between aliasing and forwarding. +It also uses the NEWDB package. +This may change in future releases. +.lp +The following options are normally turned on +in per-operating-system clauses in conf.h. +.ip IDENTPROTO\(dg +Compile in the IDENT protocol as defined in RFC 1413. +This defaults on for all systems except Ultrix, +which apparently has the interesting +.q feature +that when it receives a +.q "host unreachable" +message it closes all open connections to that host. +Since some firewall gateways send this error code +when you access an unauthorized port (such as 113, used by IDENT), +Ultrix cannot receive email from such hosts. +.ip SYSTEM5 +Set all of the compilation parameters appropriate for System V. +.ip HASFLOCK\(dg +Use Berkeley-style +.b flock +instead of System V +.b lockf +to do file locking. +Due to the highly unusual semantics of locks +across forks in +.b lockf , +this should always be used if at all possible. +.ip HASINITGROUPS +Set this if your system has the +.i initgroups() +call +(if you have multiple group support). +This is the default if SYSTEM5 is +.i not +defined or if you are on HPUX. +.ip HASUNAME +Set this if you have the +.i uname (2) +system call (or corresponding library routine). +Set by default if +SYSTEM5 +is set. +.ip HASGETDTABLESIZE +Set this if you have the +.i getdtablesize (2) +system call. +.ip HASWAITPID +Set this if you have the +.i haswaitpid (2) +system call. +.ip SFS_TYPE +The mechanism that can be used to get file system capacity information. +The values can be one of +SFS_USTAT (use the ustat(2) syscall), +SFS_4ARGS (use the four argument statfs(2) syscall), +SFS_VFS (use the two argument statfs(2) syscall including <sys/vfs.h>), +SFS_MOUNT (use the two argument statfs(2) syscall including <sys/mount.h>), +SFS_STATFS (use the two argument statfs(2) syscall including <sys/statfs.h>), +SFS_STATVFS (use the two argument statfs(2) syscall including <sys/statvfs.h>), +or +SFS_NONE (no way to get this information). +.ip LA_TYPE +The load average type. +Details are described below. +.lp +The are several built-in ways of computing the load average. +.i Sendmail +tries to auto-configure them based on imperfect guesses; +you can select one using the +.i cc +option +.b \-DLA_TYPE= \c +.i type , +where +.i type +is: +.ip LA_INT +The kernel stores the load average in the kernel as an array of long integers. +The actual values are scaled by a factor FSCALE +(default 256). +.ip LA_SHORT +The kernel stores the load average in the kernel as an array of short integers. +The actual values are scaled by a factor FSCALE +(default 256). +.ip LA_FLOAT +The kernel stores the load average in the kernel as an array of +double precision floats. +.ip LA_MACH +Use MACH-style load averages. +.ip LA_SUBR +Call the +.i getloadavg +routine to get the load average as an array of doubles. +.ip LA_ZERO +Always return zero as the load average. +This is the fallback case. +.lp +If type +.sm LA_INT , +.sm LA_SHORT , +or +.sm LA_FLOAT +is specified, +you may also need to specify +.sm _PATH_UNIX +(the path to your system binary) +and +.sm LA_AVENRUN +(the name of the variable containing the load average in the kernel; +usually +.q _avenrun +or +.q avenrun ). +.sh 2 "Configuration in src/conf.c" +.pp +The following changes can be made in conf.c. +.sh 3 "Built-in Header Semantics" +.pp +Not all header semantics are defined in the configuration file. +Header lines that should only be included by certain mailers +(as well as other more obscure semantics) +must be specified in the +.i HdrInfo +table in +.i conf.c . +This table contains the header name +(which should be in all lower case) +and a set of header control flags (described below), +The flags are: +.ip H_ACHECK +Normally when the check is made to see if a header line is compatible +with a mailer, +.i sendmail +will not delete an existing line. +If this flag is set, +.i sendmail +will delete +even existing header lines. +That is, +if this bit is set and the mailer does not have flag bits set +that intersect with the required mailer flags +in the header definition in +sendmail.cf, +the header line is +.i always +deleted. +.ip H_EOH +If this header field is set, +treat it like a blank line, +i.e., +it will signal the end of the header +and the beginning of the message text. +.ip H_FORCE +Add this header entry +even if one existed in the message before. +If a header entry does not have this bit set, +.i sendmail +will not add another header line if a header line +of this name already existed. +This would normally be used to stamp the message +by everyone who handled it. +.ip H_TRACE +If set, +this is a timestamp +(trace) +field. +If the number of trace fields in a message +exceeds a preset amount +the message is returned +on the assumption that it has an aliasing loop. +.ip H_RCPT +If set, +this field contains recipient addresses. +This is used by the +.b \-t +flag to determine who to send to +when it is collecting recipients from the message. +.ip H_FROM +This flag indicates that this field +specifies a sender. +The order of these fields in the +.i HdrInfo +table specifies +.i sendmail 's +preference +for which field to return error messages to. +.ip H_ERRORSTO +Addresses in this header should receive error messages. +.ip H_CTE +This header is a Content-Transfer-Encoding header. +.ip H_CTYPE +This header is a Content-Type header. +.ip H_STRIPVAL +Strip the value from the header (for Bcc:). +.nr ii 5n +.lp +Let's look at a sample +.i HdrInfo +specification: +.(b +.ta 4n +\w'"content-transfer-encoding", 'u +struct hdrinfo HdrInfo[] = +\&{ + /* originator fields, most to least significant */ + "resent-sender", H_FROM, + "resent-from", H_FROM, + "sender", H_FROM, + "from", H_FROM, + "full-name", H_ACHECK, + "errors-to", H_FROM\^|\^H_ERRORSTO, + /* destination fields */ + "to", H_RCPT, + "resent-to", H_RCPT, + "cc", H_RCPT, + "bcc", H_RCPT\^|\^H_STRIPVAL, + /* message identification and control */ + "message", H_EOH, + "text", H_EOH, + /* trace fields */ + "received", H_TRACE\^|\^H_FORCE, + /* miscellaneous fields */ + "content-transfer-encoding", H_CTE, + "content-type", H_CTYPE, + + NULL, 0, +}; +.)b +This structure indicates that the +.q To: , +.q Resent-To: , +and +.q Cc: +fields +all specify recipient addresses. +Any +.q Full-Name: +field will be deleted unless the required mailer flag +(indicated in the configuration file) +is specified. +The +.q Message: +and +.q Text: +fields will terminate the header; +these are used by random dissenters around the network world. +The +.q Received: +field will always be added, +and can be used to trace messages. +.pp +There are a number of important points here. +First, +header fields are not added automatically just because they are in the +.i HdrInfo +structure; +they must be specified in the configuration file +in order to be added to the message. +Any header fields mentioned in the configuration file but not +mentioned in the +.i HdrInfo +structure have default processing performed; +that is, +they are added unless they were in the message already. +Second, +the +.i HdrInfo +structure only specifies cliched processing; +certain headers are processed specially by ad hoc code +regardless of the status specified in +.i HdrInfo . +For example, +the +.q Sender: +and +.q From: +fields are always scanned on ARPANET mail +to determine the sender\**; +.(f +\**Actually, this is no longer true in SMTP; +this information is contained in the envelope. +The older ARPANET protocols did not completely distinguish +envelope from header. +.)f +this is used to perform the +.q "return to sender" +function. +The +.q "From:" +and +.q "Full-Name:" +fields are used to determine the full name of the sender +if possible; +this is stored in the macro +.b $x +and used in a number of ways. +.sh 3 "Restricting Use of Email" +.pp +If it is necessary to restrict mail through a relay, +the +.i checkcompat +routine can be modified. +This routine is called for every recipient address. +It returns an exit status +indicating the status of the message. +The status +.sm EX_OK +accepts the address, +.sm EX_TEMPFAIL +queues the message for a later try, +and other values +(commonly +.sm EX_UNAVAILABLE ) +reject the message. +It is up to +.i checkcompat +to print an error message +(using +.i usrerr ) +if the message is rejected. +For example, +.i checkcompat +could read: +.(b +.re +.sz -1 +.ta 4n +4n +4n +4n +4n +4n +4n +int +checkcompat(to, e) + register ADDRESS *to; + register ENVELOPE *e; +\&{ + register STAB *s; + + s = stab("private", ST_MAILER, ST_FIND); + if (s != NULL && e\->e_from.q_mailer != LocalMailer && + to->q_mailer == s->s_mailer) + { + usrerr("No private net mail allowed through this machine"); + return (EX_UNAVAILABLE); + } + if (MsgSize > 50000 && bitnset(M_LOCALMAILER, to\->q_mailer)) + { + usrerr("Message too large for non-local delivery"); + e\->e_flags |= EF_NORETURN; + return (EX_UNAVAILABLE); + } + return (EX_OK); +} +.sz +.)b +This would reject messages greater than 50000 bytes +unless they were local. +The +.i EF_NORETURN +flag can be set in +.i e\(->e_flags +to suppress the return of the actual body +of the message in the error return. +The actual use of this routine is highly dependent on the +implementation, +and use should be limited. +.sh 3 "Load Average Computation" +.pp +The routine +.i getla +should return an approximation of the current system load average +as an integer. +There are several versions included on compilation flags +as described above. +.sh 3 "New Database Map Classes" +.pp +New key maps can be added by creating a class initialization function +and a lookup function. +These are then added to the routine +.i setupmaps. +.pp +The initialization function is called as +.(b +\fIxxx\fP_map_init(MAP *map, char *mapname, char *args) +.)b +The +.i map +is an internal data structure. +The +.i mapname +is the name of the map (used for error messages). +The +.i args +is a pointer to the rest of the configuration file line; +flags and filenames can be extracted from this line. +The initialization function must return +.sm TRUE +if it successfully opened the map, +.sm FALSE +otherwise. +.pp +The lookup function is called as +.(b +\fIxxx\fP_map_lookup(MAP *map, char buf[], int bufsize, char **av, int *statp) +.)b +The +.i map +defines the map internally. +The parameters +.i buf +and +.i bufsize +have the input key. +This may be (and often is) used destructively. +The +.i av +is a list of arguments passed in from the rewrite line. +The lookup function should return a pointer to the new value. +IF the map lookup fails, +.i *statp +should be set to an exit status code; +in particular, it should be set to +.sm EX_TEMPFAIL +if recovery is to be attempted by the higher level code. +.sh 3 "Queueing Function" +.pp +The routine +.i shouldqueue +is called to decide if a message should be queued +or processed immediately. +Typically this compares the message priority to the current load average. +The default definition is: +.(b +bool +shouldqueue(pri, ctime) + long pri; + time_t ctime; +{ + if (CurrentLA < QueueLA) + return (FALSE); + return (pri > (QueueFactor / (CurrentLA \- QueueLA + 1))); +} +.)b +If the current load average +(global variable +.i CurrentLA , +which is set before this function is called) +is less than the low threshold load average +(option +.b x , +variable +.i QueueLA ), +.i shouldqueue +returns +.sm FALSE +immediately +(that is, it should +.i not +queue). +If the current load average exceeds the high threshold load average +(option +.b X , +variable +.i RefuseLA ), +.i shouldqueue +returns +.sm TRUE +immediately. +Otherwise, it computes the function based on the message priority, +the queue factor +(option +.b q , +global variable +.i QueueFactor ), +and the current and threshold load averages. +.pp +An implementation wishing to take the actual age of the message into account +can also use the +.i ctime +parameter, +which is the time that the message was first submitted to +.i sendmail . +Note that the +.i pri +parameter is already weighted +by the number of times the message has been tried +(although this tends to lower the priority of the message with time); +the expectation is that the +.i ctime +would be used as an +.q "escape clause" +to ensure that messages are eventually processed. +.sh 3 "Refusing Incoming SMTP Connections" +.pp +The function +.i refuseconnections +returns +.sm TRUE +if incoming SMTP connections should be refused. +The current implementation is based exclusively on the current load average +and the refuse load average option +(option +.b X , +global variable +.i RefuseLA ): +.(b +bool +refuseconnections() +{ + return (CurrentLA >= RefuseLA); +} +.)b +A more clever implementation +could look at more system resources. +.sh 3 "Load Average Computation" +.pp +The routine +.i getla +returns the current load average (as a rounded integer). +The distribution includes several possible implementations. +If you are porting to a new environment +you may need to add some new tweaks.\** +.(f +\**If you do, please send updates to +sendmail@CS.Berkeley.EDU. +.)f +.sh 2 "Configuration in src/daemon.c" +.pp +The file +.i src/daemon.c +contains a number of routines that are dependent +on the local networking environment. +The version supplied assumes you have BSD style sockets. +.pp +In previous releases, +we recommended that you modify the routine +.i maphostname +if you wanted to generalize +.b $[ +\&...\& +.b $] +lookups. +We now recommend that you create a new keyed map instead. +.sh 1 "CHANGES IN VERSION 8" +.pp +The following summarizes changes +since the last commonly available version of +.i sendmail +(5.67). +For a detailed list, +consult the file +RELEASE_NOTES +in the root directory of the +.i sendmail +distribution. +.sh 2 "Connection Caching" +.pp +Instead of closing SMTP connections immediately, +those connections are cached for possible future use. +The advent of MX records made this effective for mailing lists; +in addition, +substantial performance improvements can be expected for queue processing. +.sh 2 "MX Piggybacking" +.pp +If two hosts with different names in a single message +happen to have the same set of MX hosts, +they can be sent in the same transaction. +Version 8 notices this and tries to batch the messages. +.sh 2 "RFC 1123 Compliance" +.pp +A number of changes have been made to make +.i sendmail +.q "conditionally compliant" +(that is, +.i sendmail +satisfies all of the +.q MUST +clauses and most but not all of the +.q SHOULD +clauses in RFC 1123). +.pp +The major areas of change are (numbers are RFC 1123 section numbers): +.nr ii \w'5.3.1.1\0\0'u +.ip 5.2.7 +Response to RCPT command is fast. +.ip 5.2.8 +Numeric IP addresses are logged in Received: lines. +.ip 5.2.17 +Self domain literal is properly handled. +.ip 5.3.2 +Better control over individual timeouts. +.ip 5.3.3 +Error messages are sent as +.q From:<> . +.ip 5.3.3 +Error messages are never sent to +.q <> . +.ip 5.3.3 +Route-addrs are pruned. +.lp +The areas in which +.i sendmail +is not +.q "unconditionally compliant" +are: +.ip 5.2.6 +.i Sendmail +does do header munging. +.ip 5.2.10 +.i Sendmail +doesn't always use the exact SMTP message text +as listed in RFC 821. +.ip 5.3.1.1 +.i Sendmail +doesn't guarantee only one connect for each host in queue runs. +.ip 5.3.1.1 +.i Sendmail +doesn't always provide adequate concurrency limits. +.sh 2 "Extended SMTP Support" +.pp +Version 8 includes both sending and receiving support for Extended +SMTP support as defined by RFC 1651 (basic) and RFC 1653 (SIZE); +and limited support for RFC 1652 (BODY). +.sh 2 "Eight-Bit Clean" +.pp +Previous versions of +.i sendmail +used the 0200 bit for quoting. +This version avoids that use. +However, for compatibility with RFC 822, +you can set option `7' to get seven bit stripping. +.pp +Individual mailers can still produce seven bit output using the +`7' mailer flag. +.sh 2 "User Database" +.pp +The user database is an as-yet experimental attempt +to provide unified large-site name support. +We are installing it at Berkeley; +future versions may show significant modifications. +.sh 2 "Improved BIND Support" +.pp +The BIND support, +particularly for MX records, +had a number of annoying +.q features +which have been removed in this release. +In particular, +these more tightly bind (pun intended) the name server to +.i sendmail , +so that the name server resolution rules are incorporated directly into +.b sendmail . +.sh 2 "Keyed Files" +.pp +Generalized keyed files is an idea taken directly from +.sm IDA +.i sendmail +(albeit with a completely different implementation). +They can be useful on large sites. +.pp +Version 8 also understands YP. +.sh 2 "Multi-Word Classes" +.pp +Classes can now be multiple words. +For example, +.(b +CShofmann.CS.Berkeley.EDU +.)b +allows you to match the entire string +.q hofmann.CS.Berkeley.EDU +using the single construct +.q $=S . +.sh 2 "Deferred Macro Expansion" +.pp +The +.b $& \c +.i x +construct has been adopted from +.sm IDA . +.sh 2 "IDENT Protocol Support" +.pp +The IDENT protocol as defined in RFC 1413 is supported. +.sh 2 "Parsing Bug Fixes" +.pp +A number of small bugs having to do with things like +backslash-escaped quotes inside of comments +have been fixed. +.sh 2 "Separate Envelope/Header Processing" +.pp +Since the From: line is passed in separately from the envelope sender, +these have both been made visible; +the +.b $g +macro is set to the envelope sender during processing +of mailer argument vectors +and the header sender during processing of headers. +.pp +It is also possible to specify separate per-mailer +envelope and header processing. +The +.b S enderRWSet +and +.b R ecipientRWset +arguments for mailers +can be specified as +.i envelope/header +to give different rewritings for envelope versus header addresses. +.sh 2 "Owner-List Propagates to Envelope" +.pp +When an alias has an associated owner\-list name, +that alias is used to change the envelope sender address. +This will cause downstream errors to be returned to that owner. +.sh 2 "Dynamic Header Allocation" +.pp +The fixed size limit on header lines has been eliminated. +.sh 2 "New Command Line Flags" +.pp +The +.b \-B +flag has been added to pass in body type information. +.pp +The +.b \-p +flag has been added +to pass in protocol information. +.pp +The +.b \-X +flag has been added +to allow logging of all protocol in and out of +.i sendmail +for debugging. +.pp +The +.b \-O +flag simplies setting long-form options. +.sh 2 "Enhanced Command Line Flags" +.pp +The +.b \-q +flag can limit limit a queue run to specific recipients, senders, or queue ids +using +.b \-qR\c +.i substring , +.b \-qS\c +.i substring , +or +.b \-qI\c +.i substring +respectively. +.sh 2 "New and Old Configuration Line Types" +.pp +The +.b K +line has been added to declare database maps. +.pp +The +.b V +line has been added to declare the configuration version level. +.pp +The +.b M +line has a +.q D= +field that lets you change into a temporary directory while that mailer +is running. +It also has a +.q U= +field to allow you to set the user and group id to be used +when running the mailer. +.sh 2 "New Options" +.pp +Several new options have been added, +many to support new features, +others to allow tuning that was previously available +only by recompiling. +They are described in detail in Section 5.1.5. +Briefly, +.nr ii 0.5i +.ip b +Insist on a minimum number of disk blocks. +.ip C +Set checkpoint interval. +.ip E +Default error message. +.ip G +Enable GECOS matching. +.ip h +Maximum hop count. +.ip j +Send errors in MIME-encapsulated format. +.ip J +Forward file path. +.ip k +Connection cache size +.ip K +Connection cache lifetime. +.ip l +Enable Errors-To: header. +These headers violate RFC 1123; +this option is included to provide back compatibility +with old versions of +.i sendmail . +.ip O +Set incoming SMTP daemon options, such as an alternate SMTP port. +.ip p +Privacy options. +.ip R +Don't prune route-addrs. +.ip U +User database spec. +.ip V +Fallback +.q MX +host. +.ip w +.q "Best MX" +handling technique. +.ip 7 +Do not run eight bit clean. +.ip 8 +Eight bit data handling mode. +.sh 2 "Extended Options" +.pp +The +.b r +(read timeout), +.b I +(use BIND), +and +.b T +(queue timeout) +options have been extended to pass in more information. +.sh 2 "New Mailer Flags" +.pp +Several new mailer flags have been added. +.ip a +Try to use ESMTP when creating a connection. +If this is not set, +.i sendmail +will still try if the other end hints that it knows about ESMTP +in its greeting message; +this flag says to try even if it doesn't hint. +If the EHLO (extended hello) +command fails, +.i sendmail +falls back to old SMTP. +.ip A +Try the user part of addresses for this mailer as aliases. +.ip b +Ensure that there is a blank line at the end of all messages. +.ip c +Strip all comments from addresses; +this should only be used as a last resort +when dealing with cranky mailers. +.ip g +Never use the null sender as the envelope sender, +even when running SMTP. +Although this violates RFC 1123, +it may be necessary when you must deal with some obnoxious old hosts. +.ip k +Turn off the loopback check in the HELO protocol; +doing this may cause mailer loops. +.ip o +Always run the mailer as the recipient of the message. +.ip w +This user should have a passwd file entry. +.ip 5 +Try ruleset 5 if no local aliases. +.ip 7 +Strip all output to 7 bits. +.ip : +Check for :include: files. +.ip | +Check for |program addresses. +.ip / +Check for /file addresses. +.ip @ +Check this user against the user database. +.sh 2 "Long Option Names" +.pp +All options can be specified using long names, +and some new options can only be specified with long names. +.sh 2 "New Pre-Defined Macros" +.pp +The following macros are pre-defined: +.ip $k +The UUCP node name, +nominally from +.i uname (2) +call. +.ip $m +The domain part of our full hostname. +.ip $_ +The RFC 1413-provided sender address. +.sh 2 "New LHS Token" +.pp +Version 8 allows +.b $@ +on the Left Hand Side of an +.q R +line to match zero tokens. +This is intended to be used to match the null input. +.sh 2 "Bigger Defaults" +.pp +Version 8 allows up to 100 rulesets instead of 30. +It is recommended that rulesets 0\-9 be reserved for +.i sendmail 's +dedicated use in future releases. +.pp +The total number of MX records that can be used has been raised to 20. +.pp +The number of queued messages that can be handled at one time +has been raised from 600 to 1000. +.sh 2 "Different Default Tuning Parameters" +.pp +Version 8 has changed the default parameters +for tuning queue costs +to make the number of recipients more important +than the size of the message (for small messages). +This is reasonable if you are connected with reasonably fast links. +.sh 2 "Auto-Quoting in Addresses" +.pp +Previously, the +.q "Full Name <email address>" +syntax would generate incorrect protocol output +if +.q "Full Name" +had special characters such as dot. +This version puts quotes around such names. +.sh 2 "Symbolic Names On Error Mailer" +.pp +Several names have been built in to the $@ portion of the $#error +mailer. +.sh 2 "SMTP VRFY Doesn't Expand" +.pp +Previous versions of +.i sendmail +treated VRFY and EXPN the same. +In this version, +VRFY doesn't expand aliases or follow .forward files. +EXPN still does. +.pp +As an optimization, if you run with your default delivery mode being +queue-only or deliver-in-background, +the RCPT command will also not chase aliases and .forward files. +It will chase them when it processes the queue. +.sh 2 "[IPC] Mailers Allow Multiple Hosts" +.pp +When an address resolves to a mailer that has +.q [IPC] +as its +.q Path , +the $@ part (host name) +can be a colon-separated list of hosts instead of a single hostname. +This asks +.i sendmail +to search the list for the first entry that is available +exactly as though it were an MX record. +The intent is to route internal traffic through internal networks +without publishing an MX record to the net. +MX expansion is still done on the individual items. +.sh 2 "Aliases Extended" +.pp +The implementation has been merged with maps. +Among other things, +this supports NIS-based aliases. +.sh 2 "Portability and Security Enhancements" +.pp +A number of internal changes have been made to enhance portability. +.pp +Several fixes have been made to increase the paranoia factor. +.sh 2 "Miscellaneous Changes" +.pp +.i Sendmail +writes a +.i /etc/sendmail.pid +file with the current process id of the SMTP daemon. +.pp +Two people using the same program in their .forward file +are considered different +so that duplicate elimination doesn't delete one of them. +.pp +The +.i mailstats +program prints mailer names +and gets the location of the +.i sendmail.st +file from +.i /etc/sendmail.cf . +.pp +Many minor bugs have been fixed, such as handling of backslashes +inside of quotes. +.pp +A hook (ruleset 5) has been added +to allow rewriting of local addresses after aliasing. +.sh 1 "ACKNOWLEDGEMENTS" +.pp +I've worked on +.i sendmail +for many years, +and many employers have been remarkably patient +about letting me work on a large project +that was not part of my official job. +This includes time on the INGRES Project at +the University of California at Berkeley, +at Britton Lee, +and again on the Mammoth and Titan Projects at Berkeley. +.pp +Much of the second wave of improvements +should be credited to Bryan Costales of ICSI. +As he passed me drafts of his book on +.i sendmail +I was inspired to start working on things again. +Bryan was also available to bounce ideas off of. +.pp +Many, many people contributed chunks of code and ideas to +.i sendmail . +It has proven to be a group network effort. +Version 8 in particular was a group project. +The following people made notable contributions: +.(l +John Beck, Hewlett-Packard +Keith Bostic, CSRG, University of California, Berkeley +Andrew Cheng, Sun Microsystems +Michael J. Corrigan, University of California, San Diego +Bryan Costales, International Computer Science Institute +Pa\*:r (Pell) Emanuelsson +Craig Everhart, Transarc Corporation +Tom Ivar Helbekkmo, Norwegian School of Economics +Allan E. Johannesen, WPI +Jonathan Kamens, OpenVision Technologies, Inc. +Takahiro Kanbe, Fuji Xerox Information Systems Co., Ltd. +Brian Kantor, University of California, San Diego +Murray S. Kucherawy, HookUp Communication Corp. +Bruce Lilly, Sony U.S. +Karl London +Motonori Nakamura, Ritsumeikan University & Kyoto University +John Gardiner Myers, Carnegie Mellon University +Neil Rickert, Northern Illinois University +Eric Schnoebelen, Convex Computer Corp. +Eric Wassenaar, National Institute for Nuclear and High Energy Physics, Amsterdam +Christophe Wolfhugel, Pasteur Institute & Herve Schauer Consultants (Paris) +.)l +I apologize for anyone I have omitted, misspelled, misattributed, or +otherwise missed. +At this point, I suspect that at least a hundred people +have contributed code, +and many more have contributed ideas, comments, and encouragement. +I've tried to list them in the RELEASE_NOTES in the distribution directory. +I appreciate their contribution as well. +.pp +Special thanks are reserved for Michael Corrigan and Christophe Wolfhugel, +who besides being wonderful guinea pigs and contributors +have also consented to be added to the ``sendmail@CS.Berkeley.EDU'' list +and, by answering the bulk of the questions sent to that list, +have freed me up to do other work. +.++ A +.+c "COMMAND LINE FLAGS" +.ba 0 +.nr ii 1i +.pp +Arguments must be presented with flags before addresses. +The flags are: +.ip \-b\fIx\fP +Set operation mode to +.i x . +Operation modes are: +.(b +.ta 4n +m Deliver mail (default) +s Speak SMTP on input side +a\(dg ``Arpanet'' mode (get envelope sender information from header) +d Run as a daemon +t Run in test mode +v Just verify addresses, don't collect or deliver +i Initialize the alias database +p Print the mail queue +.)b +.(f +\(dgDeprecated. +.)f +.ip \-B\fItype\fP +Indicate body type. +.ip \-C\fIfile\fP +Use a different configuration file. +.i Sendmail +runs as the invoking user (rather than root) +when this flag is specified. +.ip \-d\fIlevel\fP +Set debugging level. +.ip "\-f\ \fIaddr\fP" +The sender's machine address is +.i addr . +.ip \-F\fIname\fP +Sets the full name of this user to +.i name . +.ip "\-h\ \fIcnt\fP" +Sets the +.q "hop count" +to +.i cnt . +This represents the number of times this message has been processed +by +.i sendmail +(to the extent that it is supported by the underlying networks). +.i Cnt +is incremented during processing, +and if it reaches +MAXHOP +(currently 30) +.i sendmail +throws away the message with an error. +.ip \-n +Don't do aliasing or forwarding. +.ip "\-r\ \fIaddr\fP" +An obsolete form of +.b \-f . +.ip \-o\fIx\|value\fP +Set option +.i x +to the specified +.i value . +These options are described in Section 5.6. +.ip \-O\fIoption\fP\fB=\fP\fIvalue\fP +Set +.i option +to the specified +.i value +(for long form option names). +These options are described in Section 5.6. +.ip \-M\fIx\|value +Set macro +.i x +to the specified +.i value . +.ip \-p\fIprotocol\fP +Set the sending protocol. +Programs are encouraged to set this. +The protocol field can be in the form +.i protocol \c +.b : \c +.i host +to set both the sending protocol and sending host. +For example, +.q \-pUUCP:uunet +sets the sending protocol to UUCP +and the sending host to uunet. +(Some existing programs use \-oM to set the r and s macros; +this is equivalent to using \-p.) +.ip \-q\fItime\fP +Try to process the queued up mail. +If the time is given, +a +.i sendmail +will run through the queue at the specified interval +to deliver queued mail; +otherwise, it only runs once. +.ip \-q\fIXstring\fP +Run the queue once, +limiting the jobs to those matching +.i Xstring . +The key letter +.i X +can be +.b I +to limit based on queue identifier, +.b R +to limit based on recipient, +or +.b S +to limit based on sender. +A particular queued job is accepted if one of the corresponding addresses +contains the indicated +.i string . +.ip \-t +Read the header for +.q To: , +.q Cc: , +and +.q Bcc: +lines, and send to everyone listed in those lists. +The +.q Bcc: +line will be deleted before sending. +Any addresses in the argument vector will be deleted +from the send list. +.ip "\-X \fIlogfile\fP" +Log all traffic in and out of +.i sendmail +in the indicated +.i logfile +for debugging mailer problems. +This produces a lot of data very quickly and should be used sparingly. +.pp +There are a number of options that may be specified as +primitive flags. +These are the e, i, m, and v options. +Also, +the f option +may be specified as the +.b \-s +flag. +.+c "QUEUE FILE FORMATS" +.pp +This appendix describes the format of the queue files. +These files live in the directory defined by the +.b Q +option in the +.i sendmail.cf +file, usually +.i /var/spool/mqueue +or +.i /usr/spool/mqueue . +.pp +All queue files have the name +\fIx\fP\|\fBf\fP\fIAAA99999\fP +where +.i AAA99999 +is the +.i id +for this message +and the +.i x +is a type. +The first letter of the id encodes the hour of the day +that the message was received by the system +(with A being the hour between midnight and 1:00AM). +All files with the same id collectively define one message. +.pp +The types are: +.nr ii 0.5i +.ip d +The data file. +The message body (excluding the header) is kept in this file. +.ip q +The queue control file. +This file contains the information necessary to process the job. +.ip t +A temporary file. +These are an image of the +.b qf +file when it is being rebuilt. +It should be renamed to a +.b qf +file very quickly. +.ip x +A transcript file, +existing during the life of a session +showing everything that happens +during that session. +.pp +The +.b qf +file is structured as a series of lines +each beginning with a code letter. +The lines are as follows: +.ip V +The version number of the queue file format, +used to allow new +.i sendmail +binaries to read queue files created by older versions. +Defaults to version zero. +Must be the first line of the file if present. +.ip H +A header definition. +There may be any number of these lines. +The order is important: +they represent the order in the final message. +These use the same syntax +as header definitions in the configuration file. +.ip C +The controlling address. +The syntax is +.q localuser:aliasname . +Recipient addresses following this line +will be flagged so that deliveries will be run as the +.i localuser +(a user name from the /etc/passwd file); +.i aliasname +is the name of the alias that expanded to this address +(used for printing messages). +.ip Q +The ``original recipient'', +specified by the ORCPT= field in an ESMTP transaction. +Used exclusively for Delivery Status Notifications. +It applies only to the immediately following `R' line. +.ip R +A recipient address. +This will normally be completely aliased, +but is actually realiased when the job is processed. +There will be one line +for each recipient. +Version 1 qf files +also include a leading colon-terminated list of flags, +which can be +`S' to return a message on successful final delivery, +`F' to return a message on failure, +`D' to return a message if the message is delayed, +`B' to indicate that the body should be returned, +`N' to suppress returning the body, +and +`P' to declare this as a ``primary'' (command line or SMTP-session) address. +.ip S +The sender address. +There may only be one of these lines. +.ip T +The job creation time. +This is used to compute when to time out the job. +.ip P +The current message priority. +This is used to order the queue. +Higher numbers mean lower priorities. +The priority changes +as the message sits in the queue. +The initial priority depends on the message class +and the size of the message. +.ip M +A message. +This line is printed by the +.i mailq +command, +and is generally used to store status information. +It can contain any text. +.ip F +Flag bits, represented as one letter per flag. +Defined flag bits are +.b r +indicating that this is a response message +and +.b w +indicating that a warning message has been sent +announcing that the mail has been delayed. +.ip N +The total number of delivery attempts. +.ip K +The time (as seconds since January 1, 1970) +of the last delivery attempt. +.ip I +The i-number of the data file; +this can be used to recover your mail queue +after a disastrous disk crash. +.ip $ +A macro definition. +The values of certain macros +(as of this writing, only +.b $r +and +.b $s ) +are passed through to the queue run phase. +.ip B +The body type. +The remainder of the line is a text string defining the body type. +If this field is missing, +the body type is assumed to be +.q "undefined" +and no special processing is attempted. +Legal values are +.q 7BIT +and +.q 8BITMIME . +.ip O +The original MTS value (from the ESMTP transaction). +For Deliver Status Notifications only. +.ip Z +The original envelope id (from the ESMTP transaction). +For Deliver Status Notifications only. +.pp +As an example, +the following is a queue file sent to +.q eric@mammoth.Berkeley.EDU +and +.q bostic@okeeffe.CS.Berkeley.EDU \**: +.(f +\**This example is contrived and probably inaccurate for your environment. +Glance over it to get an idea; +nothing can replace looking at what your own system generates. +.)f +.(b +P835771 +T404261372 +Seric +Ceric:sendmail@vangogh.CS.Berkeley.EDU +Reric@mammoth.Berkeley.EDU +Rbostic@okeeffe.CS.Berkeley.EDU +H?P?return-path: <owner-sendmail@vangogh.CS.Berkeley.EDU> +Hreceived: by vangogh.CS.Berkeley.EDU (5.108/2.7) id AAA06703; + Fri, 17 Jul 92 00:28:55 -0700 +Hreceived: from mail.CS.Berkeley.EDU by vangogh.CS.Berkeley.EDU (5.108/2.7) + id AAA06698; Fri, 17 Jul 92 00:28:54 -0700 +Hreceived: from [128.32.31.21] by mail.CS.Berkeley.EDU (5.96/2.5) + id AA22777; Fri, 17 Jul 92 03:29:14 -0400 +Hreceived: by foo.bar.baz.de (5.57/Ultrix3.0-C) + id AA22757; Fri, 17 Jul 92 09:31:25 GMT +H?F?from: eric@foo.bar.baz.de (Eric Allman) +H?x?full-name: Eric Allman +Hmessage-id: <9207170931.AA22757@foo.bar.baz.de> +HTo: sendmail@vangogh.CS.Berkeley.EDU +Hsubject: this is an example message +.)b +This shows +the person who sent the message, +the submission time +(in seconds since January 1, 1970), +the message priority, +the message class, +the recipients, +and the headers for the message. +.+c "SUMMARY OF SUPPORT FILES" +.pp +This is a summary of the support files +that +.i sendmail +creates or generates. +Many of these can be changed by editing the sendmail.cf file; +check there to find the actual pathnames. +.nr ii 1i +.ip "/usr/\*(SD/sendmail" +The binary of +.i sendmail . +.ip /usr/\*(SB/newaliases +A link to /usr/\*(SD/sendmail; +causes the alias database to be rebuilt. +Running this program is completely equivalent to giving +.i sendmail +the +.b \-bi +flag. +.ip /usr/\*(SB/mailq +Prints a listing of the mail queue. +This program is equivalent to using the +.b \-bp +flag to +.i sendmail . +.ip /etc/sendmail.cf +The configuration file, +in textual form. +.ip /usr/lib/sendmail.hf +The SMTP help file. +.ip /etc/sendmail.st +A statistics file; need not be present. +.ip /etc/sendmail.pid +Created in daemon mode; +it contains the process id of the current SMTP daemon. +If you use this in scripts; +use ``head \-1'' to get just the first line; +later versions of +.i sendmail +may add information to subsequent lines. +.ip /etc/aliases +The textual version of the alias file. +.ip /etc/aliases.{pag,dir} +The alias file in +.i dbm \|(3) +format. +.ip /var/spool/mqueue +The directory in which the mail queue +and temporary files reside. +.ip /var/spool/mqueue/qf* +Control (queue) files for messages. +.ip /var/spool/mqueue/df* +Data files. +.ip /var/spool/mqueue/tf* +Temporary versions of the qf files, +used during queue file rebuild. +.ip /var/spool/mqueue/xf* +A transcript of the current session. +.\".ro +.\".ls 1 +.\".tp +.\".sp 2i +.\".in 0 +.\".ce 100 +.\".sz 24 +.\".b SENDMAIL +.\".sz 14 +.\".sp +.\"INSTALLATION AND OPERATION GUIDE +.\".sp +.\".sz 10 +.\"Eric Allman +.\"Britton-Lee, Inc. +.\".sp +.\"Version 8.70 +.\".ce 0 +.bp 2 +.rs +.sp |4i +.ce 2 +This page intentionally left blank; +replace it with a blank sheet for double-sided output. +.bp 3 +.ce +.sz 12 +TABLE OF CONTENTS +.sz 10 +.sp +.\" remove some things to avoid "out of temp file space" problem +.rm sh +.rm (x +.rm )x +.rm ip +.rm pp +.rm lp +.rm he +.rm fo +.rm eh +.rm oh +.rm ef +.rm of +.xp diff --git a/usr.sbin/sendmail/doc/op/op.ps b/usr.sbin/sendmail/doc/op/op.ps new file mode 100644 index 000000000000..355b3fc8c9a9 --- /dev/null +++ b/usr.sbin/sendmail/doc/op/op.ps @@ -0,0 +1,5944 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.08 +%%DocumentNeededResources: font Times-Bold +%%+ font Times-Roman +%%+ font Times-Italic +%%+ font Symbol +%%DocumentSuppliedResources: procset grops 1.08 0 +%%Pages: 69 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.08 0 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Bold +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Italic +%%IncludeResource: font Symbol +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL +792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron +/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space +/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft +/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four +/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C +/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash +/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q +/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase +/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger +/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus +/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu +/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright +/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde +/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute +/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls +/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute +/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve +/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex +/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE +/Times-Roman@0 ENC0/Times-Roman RE/Times-Bold@0 ENC0/Times-Bold RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 16/Times-Bold@0 SF(SENDMAIL)244.888 143.4 Q/F1 12/Times-Bold@0 SF(INST) +170.172 172.2 Q(ALLA)-1.08 E(TION AND OPERA)-1.14 E(TION GUIDE)-1.14 E/F2 10 +/Times-Roman@0 SF(Eric Allman)263.42 196.2 Q -.15(Pa)233.085 208.2 S +(ng\346a Reference Systems).15 E(eric@Sendmail.ORG)245.205 220.2 Q -1.11(Ve) +262.725 244.2 S(rsion 8.70)1.11 E -.15(Fo)236.965 268.2 S 2.5(rS).15 G +(endmail V)258.765 268.2 Q(ersion 8.7)-1.11 E/F3 10/Times-Italic@0 SF(Sendmail) +97 312.6 Q F2 .482(implements a general purpose internetw)2.982 F .482 +(ork mail routing f)-.1 F .481(acility under the UNIX\256 operat-)-.1 F .378 +(ing system.)72 324.6 R .378(It is not tied to an)5.378 F 2.878(yo)-.15 G .378 +(ne transport protocol \212 its function may be lik)208.214 324.6 R .378 +(ened to a crossbar switch,)-.1 F 1.036 +(relaying messages from one domain into another)72 336.6 R 6.036(.I)-.55 G +3.536(nt)284.502 336.6 S 1.036 +(he process, it can do a limited amount of message)295.818 336.6 R .604(header\ + editing to put the message into a format that is appropriate for the recei)72 +348.6 R .604(ving domain.)-.25 F .604(All of this is)5.604 F +(done under the control of a con\214guration \214le.)72 360.6 Q .711 +(Due to the requirements of \215e)97 376.8 R .711(xibility for)-.15 F F3 +(sendmail)3.211 E F2 3.211(,t)C .71(he con\214guration \214le can seem some) +311.688 376.8 R .71(what unap-)-.25 F 2.893(proachable. Ho)72 388.8 R(we)-.25 E +-.15(ve)-.25 G 1.193 -.4(r, t).15 H .393(here are only a fe).4 F 2.893(wb)-.25 +G .394(asic con\214gurations for most sites, for which standard con\214gu-) +253.381 388.8 R .646(ration \214les ha)72 400.8 R .946 -.15(ve b)-.2 H .646 +(een supplied.).15 F .645(Most other con\214gurations can be b)5.646 F .645 +(uilt by adjusting an e)-.2 F .645(xisting con\214gura-)-.15 F +(tion \214les incrementally)72 412.8 Q(.)-.65 E F3(Sendmail)97 429 Q F2 .15 +(is based on RFC821 \(Simple Mail T)2.65 F .15 +(ransport Protocol\), RFC822 \(Internet Mail F)-.35 F .15(ormat Pro-)-.15 F +.423(tocol\), RFC1123 \(Internet Host Requirements\), RFC1521 \(MIME\), RFC165\ +1 \(SMTP Service Extensions\),)72 441 R .994 +(and a series of as-yet-draft standards describing Deli)72 453 R -.15(ve)-.25 G +.995(ry Status Noti\214cations \(DSNs\), a).15 F -.25(va)-.2 G .995 +(ilable from the).25 F 1.529 +(internet drafts sites as draft-ietf-notary-mime-deli)72 465 R -.15(ve)-.25 G +(ry-).15 E F3(XX)A F2 1.528(.txt, draft-ietf-notary-mime-report-)B F3(XX)A F2 +1.528(.txt, draft-)B(ietf-notary-smtp-drpt-)72 477 Q F3(XX)A F2 1.93 +(.txt, and draft-ietf-notary-status-)B F3(XX)A F2 1.93(.txt \(replace)B F3(XX) +4.43 E F2 1.93(by the latest draft number\).)4.43 F(Ho)72 489 Q(we)-.25 E -.15 +(ve)-.25 G .831 -.4(r, s).15 H(ince).4 E F3(sendmail)2.531 E F2 .031 +(is designed to w)2.531 F .031(ork in a wider w)-.1 F .03(orld, in man)-.1 F +2.53(yc)-.15 G .03(ases it can be con\214gured to e)365.12 489 R(xceed)-.15 E +(these protocols.)72 501 Q(These cases are described herein.)5 E(Although)97 +517.2 Q F3(sendmail)3.547 E F2 1.048(is intended to run without the need for m\ +onitoring, it has a number of features)3.547 F 1.972(that may be used to monit\ +or or adjust the operation under unusual circumstances.)72 529.2 R 1.972 +(These features are)6.972 F(described.)72 541.2 Q .816 +(Section one describes ho)97 557.4 R 3.316(wt)-.25 G 3.316(od)211.664 557.4 S +3.316(oab)224.98 557.4 S(asic)246.052 557.4 Q F3(sendmail)3.316 E F2 3.317 +(installation. Section)3.317 F(tw)3.317 E 3.317(oe)-.1 G .817 +(xplains the day-to-day)412.936 557.4 R .283(information you should kno)72 +569.4 R 2.783(wt)-.25 G 2.783(om)196.772 569.4 S .282 +(aintain your mail system.)212.335 569.4 R .282(If you ha)5.282 F .582 -.15 +(ve a r)-.2 H(elati).15 E -.15(ve)-.25 G .282(ly normal site, these tw).15 F(o) +-.1 E .634(sections should contain suf)72 581.4 R .635 +(\214cient information for you to install)-.25 F F3(sendmail)3.135 E F2 .635 +(and k)3.135 F .635(eep it happ)-.1 F 4.435 -.65(y. S)-.1 H .635(ection three) +.65 F .925(describes some parameters that may be safely tweak)72 593.4 R 3.425 +(ed. Section)-.1 F .925(four has information re)3.425 F -.05(ga)-.15 G .925 +(rding the com-).05 F .885(mand line ar)72 605.4 R 3.385(guments. Section)-.18 +F<8c76>3.385 E 3.385(ec)-.15 G .886 +(ontains the nitty-gritty information about the con\214guration \214le.)221.915 +605.4 R(This)5.886 E .005 +(section is for masochists and people who must write their o)72 617.4 R .004 +(wn con\214guration \214le.)-.25 F .004(Section six describes con-)5.004 F .886 +(\214guration that can be done at compile time.)72 629.4 R .886(Section se) +5.886 F -.15(ve)-.25 G 3.386(ng).15 G -2.15 -.25(iv e)322.098 629.4 T 3.386 +(sab).25 G .886(rief description of dif)354.02 629.4 R .886(ferences in this) +-.25 F -.15(ve)72 641.4 S 1.62(rsion of).15 F F3(sendmail)4.12 E F2 6.62(.T)C +1.62(he appendix)169.2 641.4 R 1.62(es gi)-.15 F 1.92 -.15(ve a b)-.25 H 1.619 +(rief b).15 F 1.619(ut detailed e)-.2 F 1.619 +(xplanation of a number of features not)-.15 F +(described in the rest of the paper)72 653.4 Q(.)-.55 E/F4 10/Times-Bold@0 SF +-1.2(WA)97 669.6 S(RNING:)1.2 E F2(Se)3.267 E -.15(ve)-.25 G .767 +(ral major changes were introduced in v).15 F .767(ersion 8.7.)-.15 F -1.1(Yo) +5.767 G 3.267(us)1.1 G .767(hould not attempt to use)404.26 669.6 R +(this document for prior v)72 681.6 Q(ersions of)-.15 E F3(sendmail)2.5 E F2(.) +A F4(Sendmail Installation and Operation Guide)72 756 Q(SMM:08-1)457.9 756 Q EP +%%Page: 7 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-7)457.9 60 Q 2.5(1. B)72 96 R(ASIC INST)-.3 E(ALLA)-.9 E(TION)-.95 E/F1 +10/Times-Roman@0 SF .234(There are tw)112 112.2 R 2.733(ob)-.1 G .233 +(asic steps to installing)175.631 112.2 R/F2 10/Times-Italic@0 SF(sendmail) +2.733 E F1 5.233(.T)C .233(he hard part is to b)317.076 112.2 R .233 +(uild the con\214guration table.)-.2 F 1.185(This is a \214le that)87 124.2 R +F2(sendmail)3.686 E F1 1.186 +(reads when it starts up that describes the mailers it kno)3.686 F 1.186 +(ws about, ho)-.25 F 3.686(wt)-.25 G(o)499 124.2 Q .715(parse addresses, ho)87 +136.2 R 3.215(wt)-.25 G 3.215(or)178.315 136.2 S -.25(ew)189.86 136.2 S .715 +(rite the message header).25 F 3.215(,a)-.4 G .715(nd the settings of v)306.75 +136.2 R .714(arious options.)-.25 F .714(Although the)5.714 F .852 +(con\214guration table is quite comple)87 148.2 R .852 +(x, a con\214guration can usually be b)-.15 F .852(uilt by adjusting an e)-.2 F +.852(xisting of)-.15 F(f-)-.25 E 1.078(the-shelf con\214guration.)87 160.2 R +1.078(The second part is actually doing the installation, i.e., creating the n\ +ecessary)6.078 F(\214les, etc.)87 172.2 Q .192 +(The remainder of this section will describe the installation of)112 188.4 R F2 +(sendmail)2.692 E F1 .192(assuming you can use one)2.692 F 1.432(of the e)87 +200.4 R 1.432(xisting con\214gurations and that the standard installation para\ +meters are acceptable.)-.15 F 1.431(All path-)6.431 F 8.62(names and e)87 212.4 +R 8.62(xamples are gi)-.15 F -.15(ve)-.25 G 11.12(nf).15 G 8.62 +(rom the root of the)257.57 212.4 R F2(sendmail)378.16 212.4 Q F1 8.62 +(subtree, normally)425.39 212.4 R F2(/usr/sr)87 224.4 Q(c/usr)-.37 E +(.sbin/sendmail)-1.11 E F1(on 4.4BSD.)2.5 E .543(If you are loading this of)112 +240.6 R 3.042(ft)-.25 G .542(he tape, continue with the ne)222.766 240.6 R .542 +(xt section.)-.15 F .542(If you ha)5.542 F .842 -.15(ve a r)-.2 H .542 +(unning binary).15 F +(already on your system, you should probably skip to section 1.2.)87 252.6 Q F0 +2.5(1.1. Compiling)87 276.6 R(Sendmail)2.5 E F1(All)127 292.8 Q F2(sendmail) +2.934 E F1 .434(source is in the)2.934 F F2(sr)2.934 E(c)-.37 E F1 +(subdirectory)2.934 E 5.434(.I)-.65 G 2.934(fy)321.652 292.8 S .435 +(ou are running on a 4.4BSD system, com-)332.916 292.8 R .179 +(pile by typing \231mak)102 304.8 R 2.679(e\232. On)-.1 F .179 +(other systems, you may ha)2.679 F .479 -.15(ve t)-.2 H 2.679(om).15 G(ak) +350.719 304.8 Q 2.679(es)-.1 G .178(ome other adjustments.)371.068 304.8 R .178 +(On most)5.178 F(systems, you can do the appropriate compilation by typing)102 +316.8 Q(sh mak)142 333 Q(esendmail)-.1 E .364(This will lea)102 349.2 R .664 +-.15(ve t)-.2 H .364(he binary in an appropriately named subdirectory).15 F +5.364(.I)-.65 G 2.864(tw)377.37 349.2 S .364(orks for multiple object v)390.134 +349.2 R(er)-.15 E(-)-.2 E(sions compiled out of the same directory)102 361.2 Q +(.)-.65 E F0 2.5(1.1.1. T)102 385.2 R(weaking the Mak)-.74 E(e\214le)-.1 E F2 +(Sendmail)142 401.4 Q F1 2.181(supports tw)4.681 F 4.681(od)-.1 G(if)247.053 +401.4 Q 2.181(ferent formats for the local \(on disk\) v)-.25 F 2.18 +(ersion of databases,)-.15 F(notably the)117 413.4 Q F2(aliases)2.5 E F1 2.5 +(database. At)2.5 F(least one of these should be de\214ned if at all possible.) +2.5 E 39.5(NDBM The)117 429.6 R -.74(``)3.166 G(ne).74 E 3.166(wD)-.25 G(BM') +240.432 429.6 Q 3.166('f)-.74 G .666(ormat, a)268.408 429.6 R -.25(va)-.2 G +.666(ilable on nearly all systems around today).25 F 5.667(.T)-.65 G(his)492.33 +429.6 Q -.1(wa)189 441.6 S 3.541(st).1 G 1.041 +(he preferred format prior to 4.4BSD.)210.771 441.6 R 1.041(It allo)6.041 F +1.041(ws such comple)-.25 F 3.54(xt)-.15 G 1.04(hings as)470.46 441.6 R +(multiple databases and closing a currently open database.)189 453.6 Q 32.84 +(NEWDB The)117 469.8 R(ne)3.323 E 3.323(wd)-.25 G .824 +(atabase package from Berk)232.606 469.8 R(ele)-.1 E 4.624 -.65(y. I)-.15 H +3.324(fy).65 G .824(ou ha)382.716 469.8 R 1.124 -.15(ve t)-.2 H .824 +(his, use it.).15 F .824(It allo)5.824 F(ws)-.25 E .839 +(long records, multiple open databases, real in-memory caching, and so forth.) +189 481.8 R -1.1(Yo)189 493.8 S 3.581(uc)1.1 G 1.081 +(an de\214ne this in conjunction with one of the other tw)213.141 493.8 R 1.082 +(o; if you do, old)-.1 F .693(databases are read, b)189 505.8 R .693 +(ut when a ne)-.2 F 3.193(wd)-.25 G .693 +(atabase is created it will be in NEWDB)341.681 505.8 R 2.851(format. As)189 +517.8 R 2.851(an)2.851 G .351(asty hack, if you ha)249.763 517.8 R .652 -.15 +(ve N)-.2 H .352(EWDB, NDBM, and NIS de\214ned, and).15 F .952 +(if the alias \214le name includes the substring \231/yp/\232,)189 529.8 R F2 +(sendmail)3.451 E F1 .951(will create both)3.451 F(ne)189 541.8 Q 3.975(wa)-.25 +G 1.475(nd old v)213.825 541.8 R 1.475(ersions of the alias \214le during a) +-.15 F F2(ne)3.976 E(walias)-.15 E F1 3.976(command. This)3.976 F(is)3.976 E +.711(required because the Sun NIS/YP system reads the DBM v)189 553.8 R .71 +(ersion of the alias)-.15 F 2.5(\214le. It')189 565.8 R 2.5(su)-.55 G +(gly as sin, b)229.56 565.8 Q(ut it w)-.2 E(orks.)-.1 E 1.112 +(If neither of these are de\214ned,)117 582 R F2(sendmail)3.612 E F1 1.112 +(reads the alias \214le into memory on e)3.612 F -.15(ve)-.25 G 1.112(ry in).15 +F -.2(vo)-.4 G(cation.).2 E 1.043(This can be slo)117 594 R 3.543(wa)-.25 G +1.043(nd should be a)195.352 594 R -.2(vo)-.2 G 3.543(ided. There).2 F 1.043 +(are also se)3.543 F -.15(ve)-.25 G 1.042(ral methods for remote database).15 F +(access:)117 606 Q 53.39(NIS Sun')117 622.2 R 2.5(sN)-.55 G(etw)220.95 622.2 Q +(ork Information Services \(formerly YP\).)-.1 E 28.94(NISPLUS Sun')117 638.4 R +2.5(sN)-.55 G(IS+ services.)220.95 638.4 Q 26.73(NETINFO NeXT')117 654.6 R 2.5 +(sN)-.55 G(etInfo service.)230.38 654.6 Q 32.84(HESIOD Hesiod)117 670.8 R +(service \(from Athena\).)2.5 E .042(Other compilation \215ags are set in conf\ +.h and should be prede\214ned for you unless you are porting)117 687 R(to a ne) +117 699 Q 2.5(we)-.25 G -.4(nv)157.57 699 S(ironment.).4 E EP +%%Page: 8 3 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 198.36(SMM:08-8 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E 2.5(1.1.2. Compilation)102 96 R +(and installation)2.5 E/F1 10/Times-Roman@0 SF .309 +(After making the local system con\214guration described abo)142 112.2 R -.15 +(ve)-.15 G 2.808(,Y).15 G .308(ou should be able to com-)398.86 112.2 R +(pile and install the system.)117 124.2 Q(The script \231mak)5 E +(esendmail\232 is the best approach on most systems:)-.1 E(sh mak)157 140.4 Q +(esendmail)-.1 E(This will use)117 156.6 Q/F2 10/Times-Italic@0 SF(uname)2.5 E +F1(\(1\) to select the correct Mak)A(e\214le for your en)-.1 E(vironment.)-.4 E +-1.1(Yo)142 172.8 S 2.5(um)1.1 G(ay be able to install using)168.4 172.8 Q +(sh mak)157 189 Q(esendmail install)-.1 E 3.346 +(This should install the binary in /usr/sbin and create links from /usr/bin/ne) +117 205.2 R -.1(wa)-.25 G 3.346(liases and).1 F 1.577 +(/usr/bin/mailq to /usr/sbin/sendmail.)117 217.2 R 1.577 +(On 4.4BSD systems it will also format and install man)6.577 F(pages.)117 229.2 +Q F0 2.5(1.2. Con\214guration)87 253.2 R(Files)2.5 E F2(Sendmail)127 269.4 Q F1 +2.079(cannot operate without a con\214guration \214le.)4.579 F 2.079 +(The con\214guration de\214nes the mail)7.079 F(deli)102 281.4 Q -.15(ve)-.25 G +.889(ry mechanisms understood at this site, ho).15 F 3.389(wt)-.25 G 3.389(oa) +309.783 281.4 S .889(ccess them, ho)322.612 281.4 R 3.388(wt)-.25 G 3.388(of) +396.128 281.4 S(orw)407.846 281.4 Q .888(ard email to remote)-.1 F .088 +(mail systems, and a number of tuning parameters.)102 293.4 R .088 +(This con\214guration \214le is detailed in the later por)5.088 F(-)-.2 E +(tion of this document.)102 305.4 Q(The)127 321.6 Q F2(sendmail)2.764 E F1 .264 +(con\214guration can be daunting at \214rst.)2.764 F .264(The w)5.264 F .264 +(orld is comple)-.1 F .264(x, and the mail con-)-.15 F .108 +(\214guration re\215ects that.)102 333.6 R .108(The distrib)5.108 F .109 +(ution includes an m4-based con\214guration package that hides a lot)-.2 F +(of the comple)102 345.6 Q(xity)-.15 E(.)-.65 E .47 +(These con\214guration \214les are simpler than old v)127 361.8 R .47 +(ersions lar)-.15 F .47(gely because the w)-.18 F .47(orld has become)-.1 F +1.448(simpler; in particular)102 373.8 R 3.948(,t)-.4 G -.15(ex)197.604 373.8 S +1.448(t-based host \214les are of).15 F 1.449(\214cially eliminated, ob)-.25 F +1.449(viating the need to \231hide\232)-.15 F(hosts behind a re)102 385.8 Q +(gistered internet g)-.15 E(ate)-.05 E -.1(wa)-.25 G -.65(y.).1 G .092(These \ +\214les also assume that most of your neighbors use domain-based UUCP addressi\ +ng; that)127 402 R .361(is, instead of naming hosts as \231host!user\232 the) +102 414 R 2.861(yw)-.15 G .361(ill use \231host.domain!user\232.)299.435 414 R +.361(The con\214guration \214les)5.361 F(can be customized to w)102 426 Q +(ork around this, b)-.1 E(ut it is more comple)-.2 E(x.)-.15 E .658 +(Our con\214guration \214les are processed by)127 442.2 R F2(m4)3.158 E F1 .658 +(to f)3.158 F .657(acilitate local customization; the directory)-.1 F F2(cf) +3.157 E F1 .396(of the)102 454.2 R F2(sendmail)2.896 E F1(distrib)2.896 E .396 +(ution directory contains the source \214les.)-.2 F .396 +(This directory contains se)5.396 F -.15(ve)-.25 G .397(ral sub-).15 F +(directories:)102 466.2 Q 61.73(cf Both)102 482.4 R .56 +(site-dependent and site-independent descriptions of hosts.)3.06 F .56 +(These can be lit-)5.56 F .445(eral host names \(e.g., \231ucb)174 494.4 R -.25 +(va)-.15 G .445(x.mc\232\) when the hosts are g).25 F(ate)-.05 E -.1(wa)-.25 G +.445(ys or more general).1 F 3.589(descriptions \(such as \231tcpproto.mc\232 \ +as a general description of an SMTP-)174 506.4 R .536(connected host or \231uu\ +cpproto.mc\232 as a general description of a UUCP-connected)174 518.4 R 3.291 +(host\). Files)174 530.4 R(ending)3.291 E F0(.mc)3.291 E F1(\(`)3.291 E .791 +(`Master Con\214guration')-.74 F .791('\) are the input descriptions; the)-.74 +F 2.14(output is in the corresponding)174 542.4 R F0(.cf)4.64 E F1 4.64 +(\214le. The)4.64 F 2.14(general structure of these \214les is)4.64 F +(described belo)174 554.4 Q -.65(w.)-.25 G 39.5(domain Site-dependent)102 570.6 +R .428(subdomain descriptions.)2.928 F .428(These are tied to the w)5.428 F +.428(ay your or)-.1 F -.05(ga)-.18 G(niza-).05 E .292(tion w)174 582.6 R .292 +(ants to do addressing.)-.1 F -.15(Fo)5.292 G 2.792(re).15 G(xample,)313.122 +582.6 Q F0(domain/cs.exposed.m4)2.792 E F1 .292(is our descrip-)2.792 F .443 +(tion for hosts in the CS.Berk)174 594.6 R(ele)-.1 E -.65(y.)-.15 G .443 +(EDU subdomain that w).65 F .442(ant their indi)-.1 F .442(vidual host-)-.25 F +.962(name to be e)174 606.6 R .963(xternally visible;)-.15 F F0 +(domain/cs.hidden.m4)3.463 E F1 .963(is the same e)3.463 F .963(xcept that the) +-.15 F 2.628(hostname is hidden \(e)174 618.6 R -.15(ve)-.25 G 2.628 +(rything looks lik).15 F 5.128(ei)-.1 G 5.128(tc)362.038 618.6 S 2.627 +(omes from CS.Berk)374.386 618.6 R(ele)-.1 E -.65(y.)-.15 G(EDU\).).65 E +(These are referenced using the)174 630.6 Q/F3 9/Times-Roman@0 SF(DOMAIN)2.5 E +F0(m4)2.5 E F1(macro in the)2.5 E F0(.mc)2.5 E F1(\214le.)2.5 E 41.74 +(feature De\214nitions)102 646.8 R .728 +(of speci\214c features that some particular host in your site might w)3.228 F +(ant.)-.1 E 2.467(These are referenced using the)174 658.8 R F3(FEA)4.966 E +(TURE)-.999 E F0(m4)4.966 E F1 4.966(macro. An)4.966 F -.15(ex)4.966 G 2.466 +(ample feature is).15 F 1.316(use_cw_\214le \(which tells)174 670.8 R F2 +(sendmail)3.816 E F1 1.317(to read an /etc/sendmail.cw \214le on startup to) +3.816 F(\214nd the set of local names\).)174 682.8 Q 50.62(hack Local)102 699 R +1.886(hacks, referenced using the)4.387 F F3(HA)4.386 E(CK)-.36 E F0(m4)4.386 E +F1 4.386(macro. T)4.386 F 1.886(ry to a)-.35 F -.2(vo)-.2 G 1.886(id these.).2 +F(The)6.886 E(point of ha)174 711 Q(ving them here is to mak)-.2 E 2.5(ei)-.1 G +2.5(tc)325.91 711 S(lear that the)335.63 711 Q 2.5(ys)-.15 G(mell.)394.08 711 Q +EP +%%Page: 9 4 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-9)457.9 60 Q/F1 10/Times-Roman@0 SF 56.72(m4 Site-independent)102 96 R +/F2 10/Times-Italic@0 SF(m4)2.538 E F1 .038(\(1\) include \214les that ha)B +.338 -.15(ve i)-.2 H .038(nformation common to all con\214gu-).15 F +(ration \214les.)174 108 Q +(This can be thought of as a \231#include\232 directory)5 E(.)-.65 E 43.95 +(mailer De\214nitions)102 124.2 R .152(of mailers, referenced using the)2.653 F +/F3 9/Times-Roman@0 SF(MAILER)2.652 E F0(m4)2.652 E F1 2.652(macro. The)2.652 F +.152(mailer types)2.652 F 1.786(that are kno)174 136.2 R 1.787 +(wn in this distrib)-.25 F 1.787(ution are f)-.2 F 1.787 +(ax, local, smtp, uucp, and usenet.)-.1 F -.15(Fo)6.787 G(r).15 E -.15(ex)174 +148.2 S(ample, to include support for the UUCP-based mailers, use \231MAILER\(\ +uucp\)\232.).15 E 43.39(ostype De\214nitions)102 164.4 R 1.157(describing v) +3.657 F 1.157(arious operating system en)-.25 F 1.156 +(vironments \(such as the loca-)-.4 F(tion of support \214les\).)174 176.4 Q +(These are referenced using the)5 E F3(OSTYPE)2.5 E F0(m4)2.5 E F1(macro.)2.5 E +60.61(sh Shell)102 192.6 R(\214les used by the)2.5 E F0(m4)2.5 E F1 -.2(bu)2.5 +G(ild process.).2 E -1.1(Yo)5 G 2.5(us)1.1 G(houldn')362.97 192.6 Q 2.5(th)-.18 +G -2.25 -.2(av e)404.18 192.6 T(to mess with these.)2.7 E 30.61 +(sitecon\214g Local)102 208.8 R .49 +(site con\214guration information, such as UUCP connecti)2.99 F(vity)-.25 E +5.49(.T)-.65 G(he)450.61 208.8 Q 2.99(yn)-.15 G(ormally)472.89 208.8 Q +(contain lists of site information, for e)174 220.8 Q(xample:)-.15 E +(SITE\(contessa\))214 237 Q(SITE\(hoptoad\))214 249 Q(SITE\(nkainc\))214 261 Q +(SITE\(well\))214 273 Q(The)174 289.2 Q 2.5(ya)-.15 G +(re referenced using the SITECONFIG macro:)201.34 289.2 Q +(SITECONFIG\(site.con\214g.\214le, name_of_site, X\))214 305.4 Q(where)174 +321.6 Q F2(X)2.704 E F1 .204(is the macro/class name to use.)2.704 F .203 +(It can be U \(indicating locally connected)5.204 F(hosts\) or one of W)174 +333.6 Q 2.5(,X)-.92 G 2.5(,o)259.73 333.6 S 2.5(rYf)269.73 333.6 S +(or up to three remote UUCP hubs.)288.61 333.6 Q .756(If you are in a ne)127 +349.8 R 3.256(wd)-.25 G .756(omain \(e.g., a compan)214.036 349.8 R .757 +(y\), you will probably w)-.15 F .757(ant to create a cf/domain)-.1 F .871 +(\214le for your domain.)102 361.8 R .871 +(This consists primarily of relay de\214nitions: for e)5.871 F .87 +(xample, Berk)-.15 F(ele)-.1 E(y')-.15 E 3.37(sd)-.55 G(omain)479 361.8 Q .16 +(de\214nition de\214nes relays for BitNET)102 373.8 R 2.66(,C)-.74 G(SNET) +257.61 373.8 Q 2.66(,a)-.74 G .16(nd UUCP)291.47 373.8 R 5.16(.O)-1.11 G 2.66 +(ft)344.57 373.8 S .16(hese, only the UUCP relay is particu-)353.34 373.8 R .46 +(larly speci\214c to Berk)102 385.8 R(ele)-.1 E 4.26 -.65(y. A)-.15 H .46 +(ll of these are internet-style domain names.).65 F .46(Please check to mak) +5.46 F 2.96(ec)-.1 G(er)493.1 385.8 Q(-)-.2 E(tain the)102 397.8 Q 2.5(ya)-.15 +G(re reasonable for your domain.)143.51 397.8 Q 1.406(Subdomains at Berk)127 +414 R(ele)-.1 E 3.906(ya)-.15 G 1.407 +(re also represented in the cf/domain directory)235.678 414 R 6.407(.F)-.65 G +1.407(or e)439.406 414 R 1.407(xample, the)-.15 F 1.491(domain cs-e)102 426 R +1.491(xposed is the Computer Science subdomain with the local hostname sho)-.15 +F 1.49(wn to other)-.25 F 1.41(users; cs-hidden mak)102 438 R 1.411 +(es users appear to be from the CS.Berk)-.1 F(ele)-.1 E -.65(y.)-.15 G 1.411 +(EDU subdomain \(with no local).65 F 1.084(host information included\).)102 450 +R -1.1(Yo)6.084 G 3.584(uw)1.1 G 1.084(ill probably ha)246.336 450 R 1.384 -.15 +(ve t)-.2 H 3.584(ou).15 G 1.083(pdate this directory to be appropriate for) +335.872 450 R(your domain.)102 462 Q -1.1(Yo)127 478.2 S 4.372(uw)1.1 G 1.872 +(ill ha)154.712 478.2 R 2.172 -.15(ve t)-.2 H 4.372(ou).15 G 1.872 +(se or create)207.478 478.2 R F0(.mc)4.372 E F1 1.872(\214les in the)4.372 F F2 +(cf/cf)4.372 E F1 1.873(subdirectory for your hosts.)4.373 F 1.873(This is) +6.873 F(detailed in the cf/README \214le.)102 490.2 Q F0 2.5(1.3. Details)87 +514.2 R(of Installation Files)2.5 E F1 +(This subsection describes the \214les that comprise the)127 530.4 Q F2 +(sendmail)2.5 E F1(installation.)2.5 E F0 2.5(1.3.1. /usr/sbin/sendmail)102 +554.4 R F1 .079(The binary for)142 572.6 R F2(sendmail)2.579 E F1 .079 +(is located in /usr/sbin)2.579 F/F4 7/Times-Roman@0 SF(1)326.703 568.6 Q F1 +5.079(.I)330.203 572.6 S 2.579(ts)341.112 572.6 S .08(hould be setuid root.) +350.361 572.6 R -.15(Fo)5.08 G 2.58(rs).15 G .08(ecurity rea-)458.11 572.6 R +(sons, /, /usr)117 586.6 Q 2.5(,a)-.4 G(nd /usr/sbin should be o)171.6 586.6 Q +(wned by root, mode 755)-.25 E F4(2)364.4 582.6 Q F1(.)367.9 586.6 Q F0 2.5 +(1.3.2. /etc/sendmail.cf)102 610.6 R F1 .699 +(This is the con\214guration \214le for)142 628.8 R F2(sendmail)3.199 E F4(3) +311.744 624.8 Q F1 5.698(.T)315.244 628.8 S .698 +(his and /etc/sendmail.pid are the only non-)329.552 628.8 R .32 LW 76 638.4 72 +638.4 DL 80 638.4 76 638.4 DL 84 638.4 80 638.4 DL 88 638.4 84 638.4 DL 92 +638.4 88 638.4 DL 96 638.4 92 638.4 DL 100 638.4 96 638.4 DL 104 638.4 100 +638.4 DL 108 638.4 104 638.4 DL 112 638.4 108 638.4 DL 116 638.4 112 638.4 DL +120 638.4 116 638.4 DL 124 638.4 120 638.4 DL 128 638.4 124 638.4 DL 132 638.4 +128 638.4 DL 136 638.4 132 638.4 DL 140 638.4 136 638.4 DL 144 638.4 140 638.4 +DL 148 638.4 144 638.4 DL 152 638.4 148 638.4 DL 156 638.4 152 638.4 DL 160 +638.4 156 638.4 DL 164 638.4 160 638.4 DL 168 638.4 164 638.4 DL 172 638.4 168 +638.4 DL 176 638.4 172 638.4 DL 180 638.4 176 638.4 DL 184 638.4 180 638.4 DL +188 638.4 184 638.4 DL 192 638.4 188 638.4 DL 196 638.4 192 638.4 DL 200 638.4 +196 638.4 DL 204 638.4 200 638.4 DL 208 638.4 204 638.4 DL 212 638.4 208 638.4 +DL 216 638.4 212 638.4 DL/F5 5/Times-Roman@0 SF(1)93.6 648.8 Q/F6 8 +/Times-Roman@0 SF .385(This is usually /usr/sbin on 4.4BSD and ne)3.2 J .385 +(wer systems; man)-.2 F 2.385(ys)-.12 G .385(ystems install it in /usr/lib) +302.966 652 R 4.384(.I)-.32 G .384(understand it is in /usr/ucblib on)398.744 +652 R(System V Release 4.)72 661.6 Q F5(2)93.6 672 Q F6 .15(Some v)3.2 J .15 +(endors ship them o)-.12 F .15 +(wned by bin; this creates a security hole that is not actually related to)-.2 +F/F7 8/Times-Italic@0 SF(sendmail)2.15 E F6 4.15(.O)C .149(ther important di-) +447.262 675.2 R(rectories that should ha)72 684.8 Q .24 -.12(ve r)-.16 H +(estricti).12 E .24 -.12(ve o)-.2 H(wnerships and permissions are /bin, /usr/b\ +in, /etc, /usr/etc, /lib, and /usr/lib)-.08 E(.)-.32 E F5(3)93.6 695.2 Q F6 +(Actually)3.2 I 2.276(,t)-.52 G .276(he pathname v)129.632 698.4 R .276 +(aries depending on the operating system; /etc is the preferred directory)-.2 F +4.276(.S)-.52 G .277(ome older systems install it)415.332 698.4 R(in)72 708 Q +/F8 8/Times-Bold@0 SF(/usr/lib/sendmail.cf)2 E F6 2(,a)C(nd I')153.344 708 Q +.24 -.12(ve a)-.4 H(lso seen it in).12 E F8(/usr/ucblib)2 E F6(and)2 E F8 +(/etc/mail)2 E F6 4(.I)C 2(fy)313.928 708 S(ou w)322.592 708 Q(ant to mo)-.08 E +.24 -.12(ve t)-.12 H(his \214le, change).12 E F7(sr)2 E(c/conf)-.296 E(.h)-.12 +E F6(.)A EP +%%Page: 10 5 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-10 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF +(library \214le names compiled into)117 98 Q/F2 10/Times-Italic@0 SF(sendmail) +2.5 E/F3 7/Times-Roman@0 SF(4)283.38 94 Q F1(.)286.88 98 Q .721 +(The con\214guration \214le is normally created using the distrib)142 114.2 R +.721(ution \214les described abo)-.2 F -.15(ve)-.15 G 5.72(.I).15 G(f)500.67 +114.2 Q .64(you ha)117 126.2 R .94 -.15(ve a p)-.2 H .64 +(articularly unusual system con\214guration you may need to create a special v) +.15 F(ersion.)-.15 E +(The format of this \214le is detailed in later sections of this document.)117 +138.2 Q F0 2.5(1.3.3. /usr/bin/newaliases)102 162.2 R F1(The)142 178.4 Q F2(ne) +2.5 E(waliases)-.15 E F1(command should just be a link to)2.5 E F2(sendmail)2.5 +E F1(:)A(rm \255f /usr/bin/ne)157 194.6 Q -.1(wa)-.25 G(liases).1 E +(ln \255s /usr/sbin/sendmail /usr/bin/ne)157 206.6 Q -.1(wa)-.25 G(liases).1 E +(This can be installed in whate)117 222.8 Q -.15(ve)-.25 G 2.5(rs).15 G +(earch path you prefer for your system.)254.91 222.8 Q F0 2.5(1.3.4. /v)102 +246.8 R(ar/spool/mqueue)-.1 E F1 .218(The directory)142 263 R F2 +(/var/spool/mqueue)2.718 E F1 .217(should be created to hold the mail queue.) +2.718 F .217(This directory)5.217 F(should be mode 700 and o)117 275 Q +(wned by root.)-.25 E(The actual path of this directory is de\214ned in the)142 +291.2 Q F0(Q)2.5 E F1(option of the)2.5 E F2(sendmail.cf)2.5 E F1(\214le.)2.5 E +F0 2.5(1.3.5. /etc/aliases*)102 315.2 R F1 1.492 +(The system aliases are held in \231/etc/aliases\232.)142 331.4 R 3.992(As) +6.492 G 1.492(ample is gi)350.006 331.4 R -.15(ve)-.25 G 3.993(ni).15 G 3.993 +<6e99>417.694 331.4 S 1.493(lib/aliases\232 which)431.127 331.4 R +(includes some aliases which)117 343.4 Q F2(must)2.5 E F1(be de\214ned:)2.5 E +(cp lib/aliases /etc/aliases)157 359.6 Q F2(edit /etc/aliases)157 371.6 Q F1 +-1.1(Yo)117 387.8 S 2.5(us)1.1 G(hould e)139.51 387.8 Q +(xtend this \214le with an)-.15 E 2.5(ya)-.15 G +(liases that are apropos to your system.)267.54 387.8 Q(Normally)142 404 Q F2 +(sendmail)3.61 E F1 1.109(looks at a v)3.61 F 1.109 +(ersion of these \214les maintained by the)-.15 F F2(dbm)3.609 E F1 1.109 +(\(3\) or)1.666 F F2(db)3.609 E F1(\(3\))1.666 E 3.46(routines. These)117 416 R +.96(are stored either in \231/etc/aliases.dir\232 and \231/etc/aliases.pag\232\ + or \231/etc/aliases.db\232)3.46 F 1.022 +(depending on which database package you are using.)117 428 R 1.022 +(These can initially be created as empty)6.022 F(\214les, b)117 440 Q(ut the) +-.2 E 2.5(yw)-.15 G(ill ha)180.54 440 Q .3 -.15(ve t)-.2 H 2.5(ob).15 G 2.5(ei) +227.69 440 S(nitialized promptly)237.41 440 Q 5(.T)-.65 G +(hese should be mode 644:)326.76 440 Q(cp /de)157 456.2 Q +(v/null /etc/aliases.dir)-.25 E(cp /de)157 468.2 Q(v/null /etc/aliases.pag)-.25 +E(chmod 644 /etc/aliases.*)157 480.2 Q(ne)157 492.2 Q -.1(wa)-.25 G(liases).1 E +(The)117 508.4 Q F2(db)2.79 E F1 .29(routines preset the mode reasonably)2.79 F +2.79(,s)-.65 G 2.79(ot)301.68 508.4 S .29(his step can be skipped.)312.25 508.4 +R .29(The actual path of this)5.29 F(\214le is de\214ned in the)117 520.4 Q F0 +(A)2.5 E F1(option of the)2.5 E F2(sendmail.cf)2.5 E F1(\214le.)2.5 E F0 2.5 +(1.3.6. /etc/r)102 544.4 R(c)-.18 E F1 .156 +(It will be necessary to start up the)142 560.6 R F2(sendmail)2.655 E F1 .155 +(daemon when your system reboots.)2.655 F .155(This dae-)5.155 F 1.537 +(mon performs tw)117 572.6 R 4.037(of)-.1 G 1.537 +(unctions: it listens on the SMTP sock)201.221 572.6 R 1.537 +(et for connections \(to recei)-.1 F 1.838 -.15(ve m)-.25 H(ail).15 E .442(fro\ +m a remote system\) and it processes the queue periodically to insure that mai\ +l gets deli)117 584.6 R -.15(ve)-.25 G(red).15 E(when hosts come up.)117 596.6 +Q .505(Add the follo)142 612.8 R .505(wing lines to \231/etc/rc\232 \(or \231/\ +etc/rc.local\232 as appropriate\) in the area where it)-.25 F +(is starting up the daemons:)117 624.8 Q .32 LW 76 669.2 72 669.2 DL 80 669.2 +76 669.2 DL 84 669.2 80 669.2 DL 88 669.2 84 669.2 DL 92 669.2 88 669.2 DL 96 +669.2 92 669.2 DL 100 669.2 96 669.2 DL 104 669.2 100 669.2 DL 108 669.2 104 +669.2 DL 112 669.2 108 669.2 DL 116 669.2 112 669.2 DL 120 669.2 116 669.2 DL +124 669.2 120 669.2 DL 128 669.2 124 669.2 DL 132 669.2 128 669.2 DL 136 669.2 +132 669.2 DL 140 669.2 136 669.2 DL 144 669.2 140 669.2 DL 148 669.2 144 669.2 +DL 152 669.2 148 669.2 DL 156 669.2 152 669.2 DL 160 669.2 156 669.2 DL 164 +669.2 160 669.2 DL 168 669.2 164 669.2 DL 172 669.2 168 669.2 DL 176 669.2 172 +669.2 DL 180 669.2 176 669.2 DL 184 669.2 180 669.2 DL 188 669.2 184 669.2 DL +192 669.2 188 669.2 DL 196 669.2 192 669.2 DL 200 669.2 196 669.2 DL 204 669.2 +200 669.2 DL 208 669.2 204 669.2 DL 212 669.2 208 669.2 DL 216 669.2 212 669.2 +DL/F4 5/Times-Roman@0 SF(4)93.6 679.6 Q/F5 8/Times-Roman@0 SF .588 +(The system libraries can reference other \214les; in particular)3.2 J 2.589 +(,s)-.32 G .589(ystem library subroutines that)294.805 682.8 R/F6 8 +/Times-Italic@0 SF(sendmail)2.589 E F5 .589(calls probably reference)2.589 F F6 +(/etc/passwd)72 692.4 Q F5(and)2 E F6(/etc/r)2 E(esolv)-.296 E(.conf)-.592 E F5 +(.)A EP +%%Page: 11 6 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-11)452.9 60 Q/F1 10/Times-Roman@0 SF +(if [ \255f /usr/sbin/sendmail \255a \255f /etc/sendmail.cf ]; then)157 96 Q +(\(cd /v)193 108 Q(ar/spool/mqueue; rm \255f [lnx]f*\))-.25 E +(/usr/sbin/sendmail \255bd \255q30m &)193 120 Q(echo \255n ' sendmail' >/de)193 +132 Q(v/console)-.25 E<8c>157 144 Q .174 +(The \231cd\232 and \231rm\232 commands insure that all lock \214les ha)117 +160.2 R .473 -.15(ve b)-.2 H .173(een remo).15 F -.15(ve)-.15 G .173(d; e).15 F +.173(xtraneous lock \214les)-.15 F .004 +(may be left around if the system goes do)117 172.2 R .005 +(wn in the middle of processing a message.)-.25 F .005(The line that)5.005 F +2.294(actually in)117 184.2 R -.2(vo)-.4 G -.1(ke).2 G(s).1 E/F2 10 +/Times-Italic@0 SF(sendmail)4.794 E F1 2.294(has tw)4.794 F 4.794<6f8d>-.1 G +2.293(ags: \231\255bd\232 causes it to listen on the SMTP port, and)272.94 +184.2 R(\231\255q30m\232 causes it to run the queue e)117 196.2 Q -.15(ve)-.25 +G(ry half hour).15 E(.)-.55 E .378(Some people use a more comple)142 212.4 R +2.879(xs)-.15 G .379(tartup script, remo)285.209 212.4 R .379 +(ving zero length qf \214les and df \214les)-.15 F 1.121 +(for which there is no qf \214le.)117 224.4 R -.15(Fo)6.121 G 3.621(re).15 G +1.12(xample, see Figure 1 for an e)262.868 224.4 R 1.12(xample of a comple)-.15 +F 3.62(xs)-.15 G(tartup)480.67 224.4 Q(script.)117 236.4 Q .755 +(If you are not running a v)142 252.6 R .755(ersion of UNIX that supports Berk) +-.15 F(ele)-.1 E 3.256(yT)-.15 G(CP/IP)416.722 252.6 Q 3.256(,d)-1.11 G 3.256 +(on)450.268 252.6 S .756(ot include)463.524 252.6 R(the)117 264.6 Q F0(\255bd) +2.5 E F1(\215ag.)2.5 E F0 2.5(1.3.7. /usr/lib/sendmail.hf)102 288.6 R F1 2.078 +(This is the help \214le used by the SMTP)142 304.8 R F0(HELP)4.578 E F1 4.578 +(command. It)4.578 F 2.078(should be copied from)4.578 F +(\231lib/sendmail.hf\232:)117 316.8 Q(cp lib/sendmail.hf /usr/lib)157 333 Q +(The actual path of this \214le is de\214ned in the)117 349.2 Q F0(H)2.5 E F1 +(option of the)2.5 E F2(sendmail.cf)2.5 E F1(\214le.)2.5 E F0 2.5 +(1.3.8. /etc/sendmail.st)102 373.2 R F1 3.04 +(If you wish to collect statistics about your mail traf)142 389.4 R 3.04 +(\214c, you should create the \214le)-.25 F(\231/etc/sendmail.st\232:)117 401.4 +Q(cp /de)157 417.6 Q(v/null /etc/sendmail.st)-.25 E(chmod 666 /etc/sendmail.st) +157 429.6 Q .716(This \214le does not gro)117 445.8 R 4.516 -.65(w. I)-.25 H +3.216(ti).65 G 3.216(sp)231.506 445.8 S .716 +(rinted with the program \231mailstats/mailstats.c.)243.612 445.8 R 5.715<9a54> +-.7 G .715(he actual path)447.03 445.8 R(of this \214le is de\214ned in the)117 +457.8 Q F0(S)2.5 E F1(option of the)2.5 E F2(sendmail.cf)2.5 E F1(\214le.)2.5 E +F0 2.5(1.3.9. /usr/bin/mailq)102 481.8 R F1(If)142 498 Q F2(sendmail)3.439 E F1 +.939(is in)3.439 F -.2(vo)-.4 G -.1(ke).2 G 3.439(da).1 G 3.439<7399>241.156 +498 S(mailq,)252.925 498 Q 3.439<9a69>-.7 G 3.439(tw)288.164 498 S .939 +(ill simulate the)301.603 498 R F0(\255bp)3.439 E F1 .94(\215ag \(i.e.,)3.44 F +F2(sendmail)3.44 E F1 .94(will print)3.44 F +(the contents of the mail queue; see belo)117 510 Q 2.5(w\). This)-.25 F +(should be a link to /usr/sbin/sendmail.)2.5 E F0 2.5(2. NORMAL)72 534 R(OPERA) +2.5 E(TIONS)-.95 E 2.5(2.1. The)87 558 R(System Log)2.5 E F1 1.511 +(The system log is supported by the)127 574.2 R F2(syslo)4.011 E(gd)-.1 E F1 +1.511(\(8\) program.)1.666 F 1.511(All messages from)6.511 F F2(sendmail)4.011 +E F1(are)4.011 E(logged under the)102 588.2 Q/F3 9/Times-Roman@0 SF(LOG_MAIL) +2.5 E F1 -.1(fa)2.5 G(cility).1 E/F4 7/Times-Roman@0 SF(5)248.43 584.2 Q F1(.) +251.93 588.2 Q F0 2.5(2.1.1. F)102 612.2 R(ormat)-.25 E F1 .574(Each line in t\ +he system log consists of a timestamp, the name of the machine that gener)142 +628.4 R(-)-.2 E .849(ated it \(for logging from se)117 640.4 R -.15(ve)-.25 G +.849(ral machines o).15 F -.15(ve)-.15 G 3.349(rt).15 G .848 +(he local area netw)316.942 640.4 R .848(ork\), the w)-.1 F .848 +(ord \231sendmail:\232,)-.1 F(and a message)117 654.4 Q F4(6)174.76 650.4 Q F1 +5(.M)178.26 654.4 S(ost messages are a sequence of)194.65 654.4 Q F2(name)2.5 E +F1(=)A F2(value)A F1(pairs.)2.5 E .32 LW 76 665.2 72 665.2 DL 80 665.2 76 665.2 +DL 84 665.2 80 665.2 DL 88 665.2 84 665.2 DL 92 665.2 88 665.2 DL 96 665.2 92 +665.2 DL 100 665.2 96 665.2 DL 104 665.2 100 665.2 DL 108 665.2 104 665.2 DL +112 665.2 108 665.2 DL 116 665.2 112 665.2 DL 120 665.2 116 665.2 DL 124 665.2 +120 665.2 DL 128 665.2 124 665.2 DL 132 665.2 128 665.2 DL 136 665.2 132 665.2 +DL 140 665.2 136 665.2 DL 144 665.2 140 665.2 DL 148 665.2 144 665.2 DL 152 +665.2 148 665.2 DL 156 665.2 152 665.2 DL 160 665.2 156 665.2 DL 164 665.2 160 +665.2 DL 168 665.2 164 665.2 DL 172 665.2 168 665.2 DL 176 665.2 172 665.2 DL +180 665.2 176 665.2 DL 184 665.2 180 665.2 DL 188 665.2 184 665.2 DL 192 665.2 +188 665.2 DL 196 665.2 192 665.2 DL 200 665.2 196 665.2 DL 204 665.2 200 665.2 +DL 208 665.2 204 665.2 DL 212 665.2 208 665.2 DL 216 665.2 212 665.2 DL/F5 5 +/Times-Roman@0 SF(5)93.6 675.6 Q/F6 8/Times-Roman@0 SF +(Except on Ultrix, which does not support f)3.2 I(acilities in the syslog.)-.08 +E F5(6)93.6 689.2 Q F6(This format may v)3.2 I(ary slightly if your v)-.2 E +(endor has changed the syntax.)-.12 E EP +%%Page: 12 7 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-12 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E .4 LW 77 108 72 108 DL 79 108 74 108 DL +84 108 79 108 DL 89 108 84 108 DL 94 108 89 108 DL 99 108 94 108 DL 104 108 99 +108 DL 109 108 104 108 DL 114 108 109 108 DL 119 108 114 108 DL 124 108 119 108 +DL 129 108 124 108 DL 134 108 129 108 DL 139 108 134 108 DL 144 108 139 108 DL +149 108 144 108 DL 154 108 149 108 DL 159 108 154 108 DL 164 108 159 108 DL 169 +108 164 108 DL 174 108 169 108 DL 179 108 174 108 DL 184 108 179 108 DL 189 108 +184 108 DL 194 108 189 108 DL 199 108 194 108 DL 204 108 199 108 DL 209 108 204 +108 DL 214 108 209 108 DL 219 108 214 108 DL 224 108 219 108 DL 229 108 224 108 +DL 234 108 229 108 DL 239 108 234 108 DL 244 108 239 108 DL 249 108 244 108 DL +254 108 249 108 DL 259 108 254 108 DL 264 108 259 108 DL 269 108 264 108 DL 274 +108 269 108 DL 279 108 274 108 DL 284 108 279 108 DL 289 108 284 108 DL 294 108 +289 108 DL 299 108 294 108 DL 304 108 299 108 DL 309 108 304 108 DL 314 108 309 +108 DL 319 108 314 108 DL 324 108 319 108 DL 329 108 324 108 DL 334 108 329 108 +DL 339 108 334 108 DL 344 108 339 108 DL 349 108 344 108 DL 354 108 349 108 DL +359 108 354 108 DL 364 108 359 108 DL 369 108 364 108 DL 374 108 369 108 DL 379 +108 374 108 DL 384 108 379 108 DL 389 108 384 108 DL 394 108 389 108 DL 399 108 +394 108 DL 404 108 399 108 DL 409 108 404 108 DL 414 108 409 108 DL 419 108 414 +108 DL 424 108 419 108 DL 429 108 424 108 DL 434 108 429 108 DL 439 108 434 108 +DL 444 108 439 108 DL 449 108 444 108 DL 454 108 449 108 DL 459 108 454 108 DL +464 108 459 108 DL 469 108 464 108 DL 474 108 469 108 DL 479 108 474 108 DL 484 +108 479 108 DL 489 108 484 108 DL 494 108 489 108 DL 499 108 494 108 DL 504 108 +499 108 DL/F1 10/Times-Roman@0 SF 2.5(#r)72 132 S(emo)82.83 132 Q .3 -.15(ve z) +-.15 H(ero length qf \214les).15 E(for qf)72 144 Q(\214le in qf*)-.25 E(do)72 +156 Q(if [ \255r $qf)108 168 Q(\214le ])-.25 E(then)108 180 Q(if [ ! \255s $qf) +144 192 Q(\214le ])-.25 E(then)144 204 Q(echo \255n " <zero: $qf)180 216 Q +(\214le>" > /de)-.25 E(v/console)-.25 E(rm \255f $qf)180 228 Q(\214le)-.25 E +<8c>144 240 Q<8c>108 252 Q(done)72 264 Q 2.5(#r)72 276 S +(ename tf \214les to be qf if the qf does not e)82.83 276 Q(xist)-.15 E(for tf) +72 288 Q(\214le in tf*)-.25 E(do)72 300 Q(qf)108 312 Q(\214le=`echo $tf)-.25 E +(\214le | sed ')-.25 E(s/t/q/'`)-.55 E(if [ \255r $tf)108 324 Q +(\214le \255a ! \255f $qf)-.25 E(\214le ])-.25 E(then)108 336 Q +(echo \255n " <reco)144 348 Q -.15(ve)-.15 G(ring: $tf).15 E(\214le>" > /de) +-.25 E(v/console)-.25 E(mv $tf)144 360 Q(\214le $qf)-.25 E(\214le)-.25 E(else) +108 372 Q(echo \255n " <e)144 384 Q(xtra: $tf)-.15 E(\214le>" > /de)-.25 E +(v/console)-.25 E(rm \255f $tf)144 396 Q(\214le)-.25 E<8c>108 408 Q(done)72 420 +Q 2.5(#r)72 432 S(emo)82.83 432 Q .3 -.15(ve d)-.15 H 2.5<668c>.15 G +(les with no corresponding qf \214les)128.08 432 Q(for df)72 444 Q +(\214le in df*)-.25 E(do)72 456 Q(qf)108 468 Q(\214le=`echo $df)-.25 E +(\214le | sed ')-.25 E(s/d/q/'`)-.55 E(if [ \255r $df)108 480 Q +(\214le \255a ! \255f $qf)-.25 E(\214le ])-.25 E(then)108 492 Q +(echo \255n " <incomplete: $df)144 504 Q(\214le>" > /de)-.25 E(v/console)-.25 E +(mv $df)144 516 Q(\214le `echo $df)-.25 E(\214le | sed ')-.25 E(s/d/D/'`)-.55 E +<8c>108 528 Q(done)72 540 Q 2.5(#a)72 552 S(nnounce \214les that ha)83.94 552 Q +.3 -.15(ve b)-.2 H(een sa).15 E -.15(ve)-.2 G 2.5(dd).15 G(uring disaster reco) +229.32 552 Q -.15(ve)-.15 G(ry).15 E(for xf)72 564 Q(\214le in [A-Z]f*)-.25 E +(do)72 576 Q(echo \255n " <panic: $xf)108 588 Q(\214le>" > /de)-.25 E +(v/console)-.25 E(done)72 600 Q(Figure 1 \212 A comple)214.47 624 Q 2.5(xs)-.15 +G(tartup script)313.48 624 Q 77 636 72 636 DL 79 636 74 636 DL 84 636 79 636 DL +89 636 84 636 DL 94 636 89 636 DL 99 636 94 636 DL 104 636 99 636 DL 109 636 +104 636 DL 114 636 109 636 DL 119 636 114 636 DL 124 636 119 636 DL 129 636 124 +636 DL 134 636 129 636 DL 139 636 134 636 DL 144 636 139 636 DL 149 636 144 636 +DL 154 636 149 636 DL 159 636 154 636 DL 164 636 159 636 DL 169 636 164 636 DL +174 636 169 636 DL 179 636 174 636 DL 184 636 179 636 DL 189 636 184 636 DL 194 +636 189 636 DL 199 636 194 636 DL 204 636 199 636 DL 209 636 204 636 DL 214 636 +209 636 DL 219 636 214 636 DL 224 636 219 636 DL 229 636 224 636 DL 234 636 229 +636 DL 239 636 234 636 DL 244 636 239 636 DL 249 636 244 636 DL 254 636 249 636 +DL 259 636 254 636 DL 264 636 259 636 DL 269 636 264 636 DL 274 636 269 636 DL +279 636 274 636 DL 284 636 279 636 DL 289 636 284 636 DL 294 636 289 636 DL 299 +636 294 636 DL 304 636 299 636 DL 309 636 304 636 DL 314 636 309 636 DL 319 636 +314 636 DL 324 636 319 636 DL 329 636 324 636 DL 334 636 329 636 DL 339 636 334 +636 DL 344 636 339 636 DL 349 636 344 636 DL 354 636 349 636 DL 359 636 354 636 +DL 364 636 359 636 DL 369 636 364 636 DL 374 636 369 636 DL 379 636 374 636 DL +384 636 379 636 DL 389 636 384 636 DL 394 636 389 636 DL 399 636 394 636 DL 404 +636 399 636 DL 409 636 404 636 DL 414 636 409 636 DL 419 636 414 636 DL 424 636 +419 636 DL 429 636 424 636 DL 434 636 429 636 DL 439 636 434 636 DL 444 636 439 +636 DL 449 636 444 636 DL 454 636 449 636 DL 459 636 454 636 DL 464 636 459 636 +DL 469 636 464 636 DL 474 636 469 636 DL 479 636 474 636 DL 484 636 479 636 DL +489 636 484 636 DL 494 636 489 636 DL 499 636 494 636 DL 504 636 499 636 DL .68 +(The tw)142 672 R 3.18(om)-.1 G .68 +(ost common lines are logged when a message is processed.)186.59 672 R .68 +(The \214rst logs the)5.68 F .376(receipt of a message; there will be e)117 684 +R .376(xactly one of these per message.)-.15 F .376(Some \214elds may be omit-) +5.376 F(ted if the)117 696 Q 2.5(yd)-.15 G 2.5(on)164.9 696 S +(ot contain interesting information.)177.4 696 Q(Fields are:)5 E 50.06 +(from The)117 712.2 R(en)2.5 E -.15(ve)-.4 G(lope sender address.).15 E EP +%%Page: 13 8 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-13)452.9 60 Q/F1 10/Times-Roman@0 SF 53.95(size The)117 96 R +(size of the message in bytes.)2.5 E 50.06(class The)117 112.2 R +(class \(i.e., numeric precedence\) of the message.)2.5 E 58.39(pri The)117 +128.4 R(initial message priority \(used for queue sorting\).)2.5 E 45.06 +(nrcpts The)117 144.6 R 1.514(number of en)4.014 F -.15(ve)-.4 G 1.515 +(lope recipients for this message \(after aliasing and for).15 F(-)-.2 E -.1 +(wa)189 156.6 S(rding\).).1 E 45.05(msgid The)117 172.8 R +(message id of the message \(from the header\).)2.5 E 48.39(proto The)117 189 R +(protocol used to recei)2.5 E .3 -.15(ve t)-.25 H +(his message \(e.g., ESMTP or UUCP\)).15 E 49.51(relay The)117 205.2 R +(machine from which it w)2.5 E(as recei)-.1 E -.15(ve)-.25 G(d.).15 E .43 +(There is also one line logged per deli)117 221.4 R -.15(ve)-.25 G .43 +(ry attempt \(so there can be se).15 F -.15(ve)-.25 G .43 +(ral per message if deli).15 F(v-)-.25 E +(ery is deferred or there are multiple recipients\).)117 233.4 Q(Fields are:)5 +E 61.72(to A)117 249.6 R(comma-separated list of the recipients to this mailer) +2.5 E(.)-.55 E 41.73(ctladdr The)117 265.8 R -.74(``)2.726 G .226 +(controlling user').74 F .226 +(', that is, the name of the user whose credentials we use)-.74 F(for deli)189 +277.8 Q -.15(ve)-.25 G(ry).15 E(.)-.65 E 47.84(delay The)117 294 R 1.303 +(total delay between the time this message w)3.804 F 1.303(as recei)-.1 F -.15 +(ve)-.25 G 3.803(da).15 G 1.303(nd the time it)447.031 294 R -.1(wa)189 306 S +2.5(sd).1 G(eli)211.95 306 Q -.15(ve)-.25 G(red.).15 E 42.84(xdelay The)117 +322.2 R .116(amount of time needed in this deli)2.615 F -.15(ve)-.25 G .116 +(ry attempt \(normally indicati).15 F .416 -.15(ve o)-.25 H 2.616(ft).15 G(he) +494.56 322.2 Q(speed of the connection\).)189 334.2 Q 43.95(mailer The)117 +350.4 R(name of the mailer used to deli)2.5 E -.15(ve)-.25 G 2.5(rt).15 G 2.5 +(ot)348.57 350.4 S(his recipient.)358.85 350.4 Q 49.51(relay The)117 366.6 R +(name of the host that actually accepted \(or rejected\) this recipient.)2.5 E +55.61(stat The)117 382.8 R(deli)2.5 E -.15(ve)-.25 G(ry status.).15 E +(Not all \214elds are present in all messages; for e)117 399 Q +(xample, the relay is not listed for local deli)-.15 E -.15(ve)-.25 G(ries.).15 +E F0 2.5(2.1.2. Le)102 423 R -.1(ve)-.15 G(ls).1 E F1 .205(If you ha)142 439.2 +R -.15(ve)-.2 G/F2 10/Times-Italic@0 SF(syslo)2.855 E(gd)-.1 E F1 .205 +(\(8\) or an equi)1.666 F -.25(va)-.25 G .205 +(lent installed, you will be able to do logging.).25 F .204(There is)5.204 F +2.787(al)117 451.2 S(ar)127.007 451.2 Q .287 +(ge amount of information that can be logged.)-.18 F .287 +(The log is arranged as a succession of le)5.287 F -.15(ve)-.25 G(ls.).15 E +.651(At the lo)117 463.2 R .651(west le)-.25 F -.15(ve)-.25 G 3.151(lo).15 G +.651(nly e)201.724 463.2 R .651(xtremely strange situations are logged.)-.15 F +.65(At the highest le)5.651 F -.15(ve)-.25 G .65(l, e).15 F -.15(ve)-.25 G 3.15 +(nt).15 G(he)494.56 463.2 Q .825(most mundane and uninteresting e)117 475.2 R +-.15(ve)-.25 G .825(nts are recorded for posterity).15 F 5.826(.A)-.65 G 3.326 +(sac)400.266 475.2 S(on)419.688 475.2 Q -.15(ve)-.4 G .826(ntion, log le).15 F +-.15(ve)-.25 G(ls).15 E .201 +(under ten are considered generally \231useful;\232 log le)117 487.2 R -.15(ve) +-.25 G .201(ls abo).15 F .501 -.15(ve 6)-.15 H 2.701(4a).15 G .2(re reserv) +381.57 487.2 R .2(ed for deb)-.15 F .2(ugging pur)-.2 F(-)-.2 E 2.5(poses. Le) +117 499.2 R -.15(ve)-.25 G(ls from 11\25564 are reserv).15 E(ed for v)-.15 E +(erbose information that some sites might w)-.15 E(ant.)-.1 E 2.5(Ac)142 515.4 +S(omplete description of the log le)156.16 515.4 Q -.15(ve)-.25 G(ls is gi).15 +E -.15(ve)-.25 G 2.5(ni).15 G 2.5(ns)340.35 515.4 S(ection 4.6.)351.74 515.4 Q +F0 2.5(2.2. Dumping)87 539.4 R(State)2.5 E F1 -1.1(Yo)127 555.6 S 2.563(uc)1.1 +G .063(an ask)150.123 555.6 R F2(sendmail)2.563 E F1 .064 +(to log a dump of the open \214les and the connection cache by sending it a) +2.563 F/F3 9/Times-Roman@0 SF(SIGUSR1)102 567.6 Q F1 2.5(signal. The)2.5 F +(results are logged at)2.5 E F3(LOG_DEB)2.5 E(UG)-.09 E F1(priority)2.5 E(.) +-.65 E F0 2.5(2.3. The)87 591.6 R(Mail Queue)2.5 E F1 1.283 +(Sometimes a host cannot handle a message immediately)127 607.8 R 6.283(.F)-.65 +G 1.283(or e)374.224 607.8 R 1.283(xample, it may be do)-.15 F 1.282(wn or)-.25 +F -.15(ove)102 619.8 S .042(rloaded, causing it to refuse connections.).15 F +.043(The sending host is then e)5.043 F .043(xpected to sa)-.15 F .343 -.15 +(ve t)-.2 H .043(his message).15 F(in its mail queue and attempt to deli)102 +631.8 Q -.15(ve)-.25 G 2.5(ri).15 G 2.5(tl)263.26 631.8 S(ater)271.32 631.8 Q +(.)-.55 E .568 +(Under normal conditions the mail queue will be processed transparently)127 648 +R 5.568(.H)-.65 G -.25(ow)434.764 648 S -2.15 -.25(ev e).25 H 1.368 -.4(r, y) +.25 H .568(ou may).4 F .993(\214nd that manual interv)102 660 R .993 +(ention is sometimes necessary)-.15 F 5.993(.F)-.65 G .993(or e)332.711 660 R +.993(xample, if a major host is do)-.15 F .994(wn for a)-.25 F 1.699 +(period of time the queue may become clogged.)102 672 R(Although)6.699 E F2 +(sendmail)4.199 E F1 1.699(ought to reco)4.199 F -.15(ve)-.15 G 4.199(rg).15 G +(racefully)468.46 672 Q(when the host comes up, you may \214nd performance una\ +cceptably bad in the meantime.)102 684 Q EP +%%Page: 14 9 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-14 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E 2.5(2.3.1. Printing)102 96 R(the queue) +2.5 E/F1 10/Times-Roman@0 SF .526 +(The contents of the queue can be printed using the)142 112.2 R/F2 10 +/Times-Italic@0 SF(mailq)3.026 E F1 .526(command \(or by specifying the)3.026 F +F0(\255bp)117 124.2 Q F1(\215ag to)2.5 E F2(sendmail)2.5 E F1(\):)A(mailq)157 +140.4 Q 1.673(This will produce a listing of the queue id')117 156.6 R 1.673 +(s, the size of the message, the date the message)-.55 F +(entered the queue, and the sender and recipients.)117 168.6 Q F0 2.5(2.3.2. F) +102 192.6 R(or)-.25 E(cing the queue)-.18 E F2(Sendmail)142 208.8 Q F1 1.137 +(should run the queue automatically at interv)3.637 F 3.638(als. The)-.25 F +1.138(algorithm is to read and)3.638 F .355 +(sort the queue, and then to attempt to process all jobs in order)117 220.8 R +5.355(.W)-.55 G .355(hen it attempts to run the job,)384.37 220.8 R F2 +(sendmail)117 232.8 Q F1(\214rst checks to see if the job is lock)2.5 E 2.5 +(ed. If)-.1 F(so, it ignores the job)2.5 E(.)-.4 E .338 +(There is no attempt to insure that only one queue processor e)142 249 R .338 +(xists at an)-.15 F 2.838(yt)-.15 G .339(ime, since there)440.282 249 R .095 +(is no guarantee that a job cannot tak)117 261 R 2.595(ef)-.1 G(ore)272.07 261 +Q -.15(ve)-.25 G 2.595(rt).15 G 2.595(op)302.585 261 S .094(rocess \(ho)315.18 +261 R(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G F2(sendmail)2.994 E F1 .094 +(does include heuris-)2.594 F 1.086 +(tics to try to abort jobs that are taking absurd amounts of time; technically) +117 273 R 3.587(,t)-.65 G 1.087(his violates RFC)435.146 273 R .462(821, b)117 +285 R .461(ut is blessed by RFC 1123\).)-.2 F .461 +(Due to the locking algorithm, it is impossible for one job to)5.461 F 1.086 +(freeze the entire queue.)117 297 R(Ho)6.086 E(we)-.25 E -.15(ve)-.25 G 1.886 +-.4(r, a).15 H 3.586(nu).4 G(ncooperati)279.346 297 Q 1.386 -.15(ve r)-.25 H +1.086(ecipient host or a program recipient that).15 F(ne)117 309 Q -.15(ve)-.25 +G 3.351(rr).15 G .851(eturns can accumulate man)145.491 309 R 3.351(yp)-.15 G +.851(rocesses in your system.)269.825 309 R(Unfortunately)5.851 E 3.351(,t)-.65 +G .85(here is no com-)439.52 309 R(pletely general w)117 321 Q(ay to solv)-.1 E +2.5(et)-.15 G(his.)234.23 321 Q .082 +(In some cases, you may \214nd that a major host going do)142 337.2 R .083 +(wn for a couple of days may create)-.25 F 2.925(ap)117 349.2 S(rohibiti) +129.365 349.2 Q -.15(ve)-.25 G .425(ly lar).15 F .425(ge queue.)-.18 F .424 +(This will result in)5.425 F F2(sendmail)2.924 E F1 .424 +(spending an inordinate amount of time)2.924 F 1.084(sorting the queue.)117 +361.2 R 1.084(This situation can be \214x)6.084 F 1.084(ed by mo)-.15 F 1.085 +(ving the queue to a temporary place and)-.15 F .023(creating a ne)117 373.2 R +2.523(wq)-.25 G 2.523(ueue. The)182.629 373.2 R .022 +(old queue can be run later when the of)2.523 F .022 +(fending host returns to service.)-.25 F 1.6 -.8(To d)142 389.4 T 2.5(ot).8 G +(his, it is acceptable to mo)170.09 389.4 Q .3 -.15(ve t)-.15 H +(he entire queue directory:).15 E(cd /v)157 405.6 Q(ar/spool)-.25 E +(mv mqueue omqueue; mkdir mqueue; chmod 700 mqueue)157 417.6 Q -1.1(Yo)117 +433.8 S 2.708(us)1.1 G .208(hould then kill the e)139.718 433.8 R .209 +(xisting daemon \(since it will still be processing in the old queue direc-) +-.15 F(tory\) and create a ne)117 445.8 Q 2.5(wd)-.25 G(aemon.)213.1 445.8 Q +1.6 -.8(To r)142 462 T(un the old mail queue, run the follo).8 E(wing command:) +-.25 E(/usr/sbin/sendmail \255oQ/v)157 478.2 Q(ar/spool/omqueue \255q)-.25 E +(The)117 494.4 Q F0(\255oQ)2.868 E F1 .367 +(\215ag speci\214es an alternate queue directory and the)2.868 F F0<ad71>2.867 +E F1 .367(\215ag says to just run e)2.867 F -.15(ve)-.25 G .367(ry job in).15 F +.593(the queue.)117 506.4 R .593(If you ha)5.593 F .893 -.15(ve a t)-.2 H +(endenc).15 E 3.093(yt)-.15 G -2.1 -.25(ow a)263.111 506.4 T .593(rd v).25 F +-.1(oy)-.2 G .593(eurism, you can use the).1 F F0<ad76>3.094 E F1 .594 +(\215ag to w)3.094 F .594(atch what is)-.1 F(going on.)117 518.4 Q +(When the queue is \214nally emptied, you can remo)142 534.6 Q .3 -.15(ve t) +-.15 H(he directory:).15 E(rmdir /v)157 550.8 Q(ar/spool/omqueue)-.25 E F0 2.5 +(2.4. The)87 579 R(Ser)2.5 E(vice Switch)-.1 E F1 1.416(The implementation of \ +certain system services such as host and user name lookup is con-)127 595.2 R +.335(trolled by the service switch.)102 607.2 R .336 +(If the host operating system supports such a switch)5.335 F F2(sendmail)2.836 +E F1 .336(will use)2.836 F(the nati)102 619.2 Q .3 -.15(ve ve)-.25 H 2.5 +(rsion. Ultrix,).15 F(Solaris, and DEC OSF/1 are e)2.5 E +(xamples of such systems.)-.15 E .969(If the underlying operating system does \ +not support a service switch \(e.g., SunOS, HP-UX,)127 635.4 R .975(BSD\) then) +102 647.4 R F2(sendmail)3.475 E F1 .975(will pro)3.475 F .975 +(vide a stub implementation.)-.15 F(The)5.975 E F0(Ser)3.475 E(viceSwitchFile) +-.1 E F1 .975(option points to)3.475 F .382(the name of a \214le that has the \ +service de\214nitions Each line has the name of a service and the possi-)102 +659.4 R(ble implementations of that service.)102 671.4 Q -.15(Fo)5 G 2.5(re).15 +G(xample, the \214le:)270.57 671.4 Q 12.94(hosts dns)142 687.6 R(\214les nis) +2.5 E 6.84(aliases \214les)142 699.6 R(nis)2.5 E .328(will ask)102 715.8 R F2 +(sendmail)2.828 E F1 .328(to look for hosts in the Domain Name System \214rst.) +2.828 F .329(If the requested host name is)5.329 F EP +%%Page: 15 10 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-15)452.9 60 Q/F1 10/Times-Roman@0 SF .379 +(not found, it tries local \214les, and if that f)102 96 R .379 +(ails it tries NIS.)-.1 F(Similarly)5.379 E 2.879(,w)-.65 G .379 +(hen looking for aliases it will)385.166 96 R +(try the local \214les \214rst follo)102 108 Q(wed by NIS.)-.25 E 1.269 +(Service switches are not completely inte)127 124.2 R 3.769(grated. F)-.15 F +1.269(or e)-.15 F 1.269(xample, despite the f)-.15 F 1.27(act that the host)-.1 +F .294(entry listed in the abo)102 136.2 R .594 -.15(ve ex)-.15 H .293 +(ample speci\214es to look in NIS, on SunOS this w).15 F(on')-.1 E 2.793(th) +-.18 G .293(appen because the)430.664 136.2 R 1.398(system implementation of) +102 148.2 R/F2 10/Times-Italic@0 SF -.1(ge)3.898 G(thostbyname).1 E F1 1.398 +(\(3\) doesn')1.666 F 3.898(tu)-.18 G 1.399(nderstand this.)327.856 148.2 R +1.399(If there is enough demand)6.399 F F2(sendmail)102 160.2 Q F1 .015 +(may reimplement)2.515 F F2 -.1(ge)2.515 G(thostbyname).1 E F1(\(3\),)1.666 E +F2 -.1(ge)2.515 G(thostbyaddr).1 E F1(\(3\),)1.666 E F2 -.1(ge)2.515 G(tpwent) +.1 E F1 .014(\(3\), and the other system)1.666 F(routines that w)102 172.2 Q +(ould be necessary to mak)-.1 E 2.5(et)-.1 G(his w)272.05 172.2 Q +(ork seamlessly)-.1 E(.)-.65 E F0 2.5(2.5. The)87 196.2 R(Alias Database)2.5 E +F1 .36(The alias database e)127 212.4 R .36(xists in tw)-.15 F 2.86(of)-.1 G +2.861(orms. One)261.11 212.4 R .361(is a te)2.861 F .361 +(xt form, maintained in the \214le)-.15 F F2(/etc/aliases.)2.861 E F1 +(The aliases are of the form)102 224.4 Q(name: name1, name2, ...)142 240.6 Q +(Only local names may be aliased; e.g.,)102 256.8 Q(eric@prep.ai.MIT)142 273 Q +(.EDU: eric@CS.Berk)-.74 E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E 1.088 +(will not ha)102 291.2 R 1.388 -.15(ve t)-.2 H 1.088(he desired ef).15 F 1.088 +(fect \(e)-.25 F 1.088(xcept on prep.ai.MIT)-.15 F 1.088(.EDU, and the)-.74 F +3.588(yp)-.15 G 1.088(robably don')400.868 291.2 R 3.587(tw)-.18 G 1.087 +(ant me\))466.643 291.2 R/F3 7/Times-Roman@0 SF(7)498 287.2 Q F1(.)501.5 291.2 +Q .561(Aliases may be continued by starting an)102 303.2 R 3.061(yc)-.15 G .561 +(ontinuation lines with a space or a tab)277.697 303.2 R 5.562(.B)-.4 G .562 +(lank lines and)447.326 303.2 R(lines be)102 315.2 Q +(ginning with a sharp sign \(\231#\232\) are comments.)-.15 E 1.478 +(The second form is processed by the)127 333.4 R F2(ndbm)3.978 E F1(\(3\))1.666 +E F3(8)321.472 329.4 Q F1(or)328.95 333.4 Q F2(db)3.978 E F1 1.478 +(\(3\) library)1.666 F 6.478(.T)-.65 G 1.478(his form is in the \214les)409.66 +333.4 R F2(/etc/aliases.dir)102 345.4 Q F1(and)3.028 E F2(/etc/aliases.pa)3.028 +E -.15(g.)-.1 G F1 .528(This is the form that)5.678 F F2(sendmail)3.029 E F1 +.529(actually uses to resolv)3.029 F 3.029(ea)-.15 G(liases.)479.28 345.4 Q +(This technique is used to impro)102 357.4 Q .3 -.15(ve p)-.15 H(erformance.) +.15 E(The control of search order is actually set by the service switch.)127 +373.6 Q(Essentially)5 E 2.5(,t)-.65 G(he entry)437.96 373.6 Q -.35(OA)142 389.8 +S(switch:aliases).35 E .927(is al)102 406 R -.1(wa)-.1 G .927(ys added as the \ +\214rst alias entry; also, the \214rst alias \214le name without a class \(e.g\ +., without).1 F .268 +(\231nis:\232 on the front\) will be used as the name of the \214le for a `)102 +418 R(`\214les')-.74 E 2.769('e)-.74 G .269(ntry in the aliases switch.)382.535 +418 R -.15(Fo)5.269 G(r).15 E -.15(ex)102 430 S +(ample, if the con\214guration \214le contains).15 E -.35(OA)142 446.2 S +(/etc/aliases).35 E(and the service switch contains)102 462.4 Q 6.84 +(aliases nis)142 478.6 R(\214les nisplus)2.5 E 2.449(then aliases will \214rst\ + be searched in the NIS database, then in /etc/aliases, then in the NIS+)102 +494.8 R(database.)102 506.8 Q -1.1(Yo)127 523 S 2.5(uc)1.1 G(an also use)150.06 +523 Q/F4 9/Times-Roman@0 SF(NIS)2.5 E F1(-based alias \214les.)A -.15(Fo)5 G +2.5(re).15 G(xample, the speci\214cation:)305.069 523 Q -.35(OA)142 539.2 S +(/etc/aliases).35 E -.35(OA)142 551.2 S(nis:mail.aliases@my).35 E(.nis.domain) +-.65 E 1.725(will \214rst search the /etc/aliases \214le and then the map name\ +d \231mail.aliases\232 in \231my)102 567.4 R(.nis.domain\232.)-.65 E -.8(Wa)102 +579.4 S .59(rning: if you b).8 F .59(uild your o)-.2 F(wn)-.25 E F4(NIS)3.09 E +F1 .589(-based alias \214les, be sure to pro)B .589(vide the)-.15 F F0<ad6c> +3.089 E F1 .589(\215ag to)3.089 F F2(mak)3.089 E(edbm)-.1 E F1(\(8\))A .159 +(to map upper case letters in the k)102 591.4 R -.15(ey)-.1 G 2.659(st).15 G +2.659(ol)253.55 591.4 S -.25(ow)263.989 591.4 S .159 +(er case; otherwise, aliases with upper case letters in their).25 F(names w)102 +603.4 Q(on')-.1 E 2.5(tm)-.18 G(atch incoming addresses.)163.38 603.4 Q +(Additional \215ags can be added after the colon e)127 619.6 Q(xactly lik)-.15 +E 2.5(ea)-.1 G F0(K)A F1(line \212 for e)2.5 E(xample:)-.15 E -.35(OA)142 635.8 +S(nis:\255N mail.aliases@my).35 E(.nis.domain)-.65 E +(will search the appropriate NIS map and al)102 652 Q -.1(wa)-.1 G +(ys include null bytes in the k).1 E -.15(ey)-.1 G(.)-.5 E .32 LW 76 665.2 72 +665.2 DL 80 665.2 76 665.2 DL 84 665.2 80 665.2 DL 88 665.2 84 665.2 DL 92 +665.2 88 665.2 DL 96 665.2 92 665.2 DL 100 665.2 96 665.2 DL 104 665.2 100 +665.2 DL 108 665.2 104 665.2 DL 112 665.2 108 665.2 DL 116 665.2 112 665.2 DL +120 665.2 116 665.2 DL 124 665.2 120 665.2 DL 128 665.2 124 665.2 DL 132 665.2 +128 665.2 DL 136 665.2 132 665.2 DL 140 665.2 136 665.2 DL 144 665.2 140 665.2 +DL 148 665.2 144 665.2 DL 152 665.2 148 665.2 DL 156 665.2 152 665.2 DL 160 +665.2 156 665.2 DL 164 665.2 160 665.2 DL 168 665.2 164 665.2 DL 172 665.2 168 +665.2 DL 176 665.2 172 665.2 DL 180 665.2 176 665.2 DL 184 665.2 180 665.2 DL +188 665.2 184 665.2 DL 192 665.2 188 665.2 DL 196 665.2 192 665.2 DL 200 665.2 +196 665.2 DL 204 665.2 200 665.2 DL 208 665.2 204 665.2 DL 212 665.2 208 665.2 +DL 216 665.2 212 665.2 DL/F5 5/Times-Roman@0 SF(7)93.6 675.6 Q/F6 8 +/Times-Roman@0 SF(Actually)3.2 I 2(,a)-.52 G .24 -.12(ny m)130.684 678.8 T +(ailer that has the `).12 E 1.776 -.888(A' m)-.64 H(ailer \215ag set will perm\ +it aliasing; this is normally limited to the local mailer).888 E(.)-.44 E F5(8) +93.6 689.2 Q F6(The)3.2 I/F7 8/Times-Italic@0 SF(gdbm)2 E F6 +(package probably w)2 E(orks as well.)-.08 E EP +%%Page: 16 11 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-16 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E 2.5(2.5.1. Reb)102 96 R +(uilding the alias database)-.2 E/F1 10/Times-Roman@0 SF .542(The DB or DBM v) +142 112.2 R .542(ersion of the database may be reb)-.15 F .542(uilt e)-.2 F +.542(xplicitly by e)-.15 F -.15(xe)-.15 G .542(cuting the com-).15 F(mand)117 +124.2 Q(ne)157 140.4 Q -.1(wa)-.25 G(liases).1 E(This is equi)117 156.6 Q -.25 +(va)-.25 G(lent to gi).25 E(ving)-.25 E/F2 10/Times-Italic@0 SF(sendmail)2.5 E +F1(the)2.5 E F0(\255bi)2.5 E F1(\215ag:)2.5 E(/usr/sbin/sendmail \255bi)157 +172.8 Q 2.29(If the)142 193.2 R F0(Reb)4.79 E(uildAliases)-.2 E F1(\(old)4.79 E +F0(D)4.79 E F1 4.79(\)o)C 2.29(ption is speci\214ed in the con\214guration,) +280.19 193.2 R F2(sendmail)4.79 E F1(will)4.79 E(reb)117 205.2 Q .775 +(uild the alias database automatically if possible when it is out of date.)-.2 +F(Auto-reb)5.774 E .774(uild can be)-.2 F 1.853(dangerous on hea)117 217.2 R +1.853(vily loaded machines with lar)-.2 F 1.853 +(ge alias \214les; if it might tak)-.18 F 4.354(em)-.1 G 1.854(ore than the) +453.082 217.2 R(reb)117 229.2 Q 2.832(uild timeout \(option)-.2 F F0(AliasW) +5.332 E(ait)-.65 E F1 5.332(,o)C(ld)275.538 229.2 Q F0(a)5.332 E F1 5.332(,w)C +2.831(hich is normally \214v)308.702 229.2 R 5.331(em)-.15 G 2.831 +(inutes\) to reb)412.657 229.2 R 2.831(uild the)-.2 F +(database, there is a chance that se)117 241.2 Q -.15(ve)-.25 G +(ral processes will start the reb).15 E(uild process simultaneously)-.2 E(.) +-.65 E 1.77(If you ha)142 257.4 R 2.07 -.15(ve m)-.2 H 1.77 +(ultiple aliases databases speci\214ed, the).15 F F0(\255bi)4.27 E F1 1.77 +(\215ag reb)4.27 F 1.77(uilds all the database)-.2 F +(types it understands \(for e)117 269.4 Q(xample, it can reb)-.15 E +(uild NDBM databases b)-.2 E(ut not NIS databases\).)-.2 E F0 2.5(2.5.2. P)102 +293.4 R(otential pr)-.2 E(oblems)-.18 E F1 1.131 +(There are a number of problems that can occur with the alias database.)142 +309.6 R(The)6.13 E 3.63(ya)-.15 G 1.13(ll result)472.59 309.6 R 1.103(from a) +117 321.6 R F2(sendmail)3.603 E F1 1.103(process accessing the DBM v)3.603 F +1.103(ersion while it is only partially b)-.15 F 3.604(uilt. This)-.2 F(can) +3.604 E 1.249(happen under tw)117 333.6 R 3.749(oc)-.1 G 1.248 +(ircumstances: One process accesses the database while another process is) +199.237 333.6 R(reb)117 345.6 Q .518(uilding it, or the process reb)-.2 F .518 +(uilding the database dies \(due to being killed or a system crash\))-.2 F +(before completing the reb)117 357.6 Q(uild.)-.2 E .401 +(Sendmail has three techniques to try to relie)142 373.8 R .701 -.15(ve t)-.25 +H .401(hese problems.).15 F .4(First, it ignores interrupts)5.401 F .045 +(while reb)117 385.8 R .045(uilding the database; this a)-.2 F -.2(vo)-.2 G +.045(ids the problem of someone aborting the process lea).2 F .045(ving a)-.2 F +.177(partially reb)117 397.8 R .177(uilt database.)-.2 F .177 +(Second, it locks the database source \214le during the reb)5.177 F .176 +(uild \212 b)-.2 F .176(ut that)-.2 F .812(may not w)117 409.8 R .812(ork o)-.1 +F -.15(ve)-.15 G 3.312(rN).15 G .812(FS or if the \214le is unwritable.)205.388 +409.8 R .813(Third, at the end of the reb)5.813 F .813(uild it adds an)-.2 F +(alias of the form)117 421.8 Q(@: @)157 438 Q .336(\(which is not normally le) +117 454.2 R -.05(ga)-.15 G 2.836(l\). Before).05 F F2(sendmail)2.836 E F1 .336 +(will access the database, it checks to insure that)2.836 F(this entry e)117 +468.2 Q(xists)-.15 E/F3 7/Times-Roman@0 SF(9)179.63 464.2 Q F1(.)183.13 468.2 Q +F0 2.5(2.5.3. List)102 492.2 R -.1(ow)2.5 G(ners).1 E F1 .4 +(If an error occurs on sending to a certain address, say \231)142 508.4 R F2(x) +A F1<9a2c>A F2(sendmail)2.901 E F1 .401(will look for an alias)2.901 F .418 +(of the form \231o)117 520.4 R(wner)-.25 E(-)-.2 E F2(x)A F1 2.918<9a74>C 2.918 +(or)212.632 520.4 S(ecei)223.88 520.4 Q .718 -.15(ve t)-.25 H .418(he errors.) +.15 F .417(This is typically useful for a mailing list where the)5.418 F 1.116 +(submitter of the list has no control o)117 532.4 R -.15(ve)-.15 G 3.617(rt).15 +G 1.117(he maintenance of the list itself; in this case the list)288.4 532.4 R +(maintainer w)117 544.4 Q(ould be the o)-.1 E(wner of the list.)-.25 E -.15(Fo) +5 G 2.5(re).15 G(xample:)309.38 544.4 Q +(unix-wizards: eric@ucbarpa, wnj@monet, nosuchuser)157 560.6 Q(,)-.4 E +(sam@matisse)193 572.6 Q -.25(ow)157 584.6 S(ner).25 E +(-unix-wizards: unix-wizards-request)-.2 E(unix-wizards-request: eric@ucbarpa) +157 596.6 Q -.1(wo)117 612.8 S 1.959(uld cause \231eric@ucbarpa\232 to get the\ + error that will occur when someone sends to unix-).1 F +(wizards due to the inclusion of \231nosuchuser\232 on the list.)117 624.8 Q +.958(List o)142 641 R .958(wners also cause the en)-.25 F -.15(ve)-.4 G .959 +(lope sender address to be modi\214ed.).15 F .959(The contents of the)5.959 F +-.25(ow)117 653 S .429(ner alias are used if the).25 F 2.929(yp)-.15 G .429 +(oint to a single user)236.364 653 R 2.928(,o)-.4 G .428 +(therwise the name of the alias itself is used.)326.436 653 R -.15(Fo)117 665 S +3.454(rt).15 G .954(his reason, and to obe)136.974 665 R 3.454(yI)-.15 G .954 +(nternet con)239.354 665 R -.15(ve)-.4 G .954(ntions, the \231o).15 F(wner)-.25 +E .955(-\232 address normally points at the)-.2 F .504(\231-request\232 addres\ +s; this causes messages to go out with the typical Internet con)117 677 R -.15 +(ve)-.4 G .503(ntion of using).15 F .32 LW 76 686.6 72 686.6 DL 80 686.6 76 +686.6 DL 84 686.6 80 686.6 DL 88 686.6 84 686.6 DL 92 686.6 88 686.6 DL 96 +686.6 92 686.6 DL 100 686.6 96 686.6 DL 104 686.6 100 686.6 DL 108 686.6 104 +686.6 DL 112 686.6 108 686.6 DL 116 686.6 112 686.6 DL 120 686.6 116 686.6 DL +124 686.6 120 686.6 DL 128 686.6 124 686.6 DL 132 686.6 128 686.6 DL 136 686.6 +132 686.6 DL 140 686.6 136 686.6 DL 144 686.6 140 686.6 DL 148 686.6 144 686.6 +DL 152 686.6 148 686.6 DL 156 686.6 152 686.6 DL 160 686.6 156 686.6 DL 164 +686.6 160 686.6 DL 168 686.6 164 686.6 DL 172 686.6 168 686.6 DL 176 686.6 172 +686.6 DL 180 686.6 176 686.6 DL 184 686.6 180 686.6 DL 188 686.6 184 686.6 DL +192 686.6 188 686.6 DL 196 686.6 192 686.6 DL 200 686.6 196 686.6 DL 204 686.6 +200 686.6 DL 208 686.6 204 686.6 DL 212 686.6 208 686.6 DL 216 686.6 212 686.6 +DL/F4 5/Times-Roman@0 SF(9)93.6 697 Q/F5 8/Times-Roman@0 SF(The)3.2 I/F6 8 +/Times-Bold@0 SF(AliasW)2 E(ait)-.52 E F5 +(option is required in the con\214guration for this action to occur)2 E 4(.T) +-.44 G(his should normally be speci\214ed.)352.228 700.2 Q EP +%%Page: 17 12 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-17)452.9 60 Q/F1 10/Times-Roman@0 SF -.74(``)117 96 S/F2 10 +/Times-Italic@0 SF(list).74 E F1(-request')A 2.5('a)-.74 G 2.5(st)180.22 96 S +(he return address.)189.39 96 Q F0 2.5(2.6. User)87 120 R(Inf)2.5 E +(ormation Database)-.25 E F1 1.059(If you ha)127 136.2 R 1.359 -.15(ve a ve)-.2 +H 1.059(rsion of).15 F F2(sendmail)3.559 E F1 1.06 +(with the user information database compiled in, and you)3.559 F(ha)102 148.2 Q +2.206 -.15(ve s)-.2 H 1.906(peci\214ed one or more databases using the).15 F F0 +(U)4.406 E F1 1.905(option, the databases will be searched for a)4.406 F F2 +(user)102 160.2 Q F1(:maildrop entry)A 5(.I)-.65 G 2.5(ff)191.34 160.2 S +(ound, the mail will be sent to the speci\214ed address.)200.5 160.2 Q F0 2.5 +(2.7. P)87 184.2 R(er)-.2 E(-User F)-.37 E(orwarding \(.f)-.25 E +(orward Files\))-.25 E F1 .12(As an alternati)127 200.4 R .42 -.15(ve t)-.25 H +2.62(ot).15 G .12(he alias database, an)210.4 200.4 R 2.62(yu)-.15 G .121 +(ser may put a \214le with the name \231.forw)304.87 200.4 R .121 +(ard\232 in his)-.1 F .205(or her home directory)102 212.4 R 5.205(.I)-.65 G +2.705(ft)199.92 212.4 S .205(his \214le e)208.735 212.4 R(xists,)-.15 E F2 +(sendmail)2.705 E F1 .205 +(redirects mail for that user to the list of addresses)2.705 F .908 +(listed in the .forw)102 224.4 R .908(ard \214le.)-.1 F -.15(Fo)5.908 G 3.408 +(re).15 G .908 +(xample, if the home directory for user \231mckusick\232 has a .forw)233.978 +224.4 R(ard)-.1 E(\214le with contents:)102 236.4 Q(mckusick@ernie)142 252.6 Q +(kirk@calder)142 264.6 Q(then an)102 280.8 Q 2.5(ym)-.15 G(ail arri)146.29 +280.8 Q +(ving for \231mckusick\232 will be redirected to the speci\214ed accounts.)-.25 +E(Actually)127 297 Q 3.375(,t)-.65 G .874 +(he con\214guration \214le de\214nes a sequence of \214lenames to check.) +169.445 297 R .874(By def)5.874 F .874(ault, this is)-.1 F .687(the user')102 +309 R 3.187(s.)-.55 G(forw)146.424 309 Q .687(ard \214le, b)-.1 F .687 +(ut can be de\214ned to be more generally using the)-.2 F F0(J)3.187 E F1 3.188 +(option. If)3.188 F .688(you change)3.188 F .393(this, you will ha)102 321 R +.693 -.15(ve t)-.2 H 2.893(oi).15 G .393 +(nform your user base of the change; .forw)193.065 321 R .393 +(ard is pretty well incorporated into)-.1 F(the collecti)102 333 Q .3 -.15 +(ve s)-.25 H(ubconscious.).15 E F0 2.5(2.8. Special)87 357 R(Header Lines)2.5 E +F1(Se)127 373.2 Q -.15(ve)-.25 G 1.897(ral header lines ha).15 F 2.197 -.15 +(ve s)-.2 H 1.897 +(pecial interpretations de\214ned by the con\214guration \214le.).15 F(Others) +6.898 E(ha)102 385.2 Q 1.206 -.15(ve i)-.2 H .906(nterpretations b).15 F .906 +(uilt into)-.2 F F2(sendmail)3.406 E F1 .905 +(that cannot be changed without changing the code.)3.406 F(These)5.905 E -.2 +(bu)102 397.2 S(iltins are described here.).2 E F0 2.5(2.8.1. Err)102 421.2 R +(ors-T)-.18 E(o:)-.92 E F1 .22(If errors occur an)142 437.4 R .22 +(ywhere during processing, this header will cause error messages to go to)-.15 +F(the listed addresses.)117 449.4 Q(This is intended for mailing lists.)5 E +.385(The Errors-T)142 465.6 R .385(o: header w)-.8 F .384 +(as created in the bad old days when UUCP didn')-.1 F 2.884(tu)-.18 G .384 +(nderstand the)450.016 465.6 R .889(distinction between an en)117 477.6 R -.15 +(ve)-.4 G .889(lope and a header; this w).15 F .889(as a hack to pro)-.1 F .89 +(vide what should no)-.15 F 3.39(wb)-.25 G(e)499.56 477.6 Q .81 +(passed as the en)117 489.6 R -.15(ve)-.4 G .81(lope sender address.).15 F .809 +(It should go a)5.81 F -.1(wa)-.15 G 4.609 -.65(y. I).1 H 3.309(ti).65 G 3.309 +(so)374.125 489.6 S .809(nly used if the)386.324 489.6 R F0(UseErr)3.309 E +(orsT)-.18 E(o)-.92 E F1(option is set.)117 501.6 Q(The Errors-T)142 517.8 Q +(o: header is of)-.8 E(\214cial deprecated and will go a)-.25 E -.1(wa)-.15 G +2.5(yi).1 G 2.5(naf)392.3 517.8 S(uture release.)410.07 517.8 Q F0 2.5 +(2.8.2. A)102 541.8 R(ppar)-.25 E(ently-T)-.18 E(o:)-.92 E F1 .044 +(RFC 822 requires at least one recipient \214eld \(T)142 558 R .045 +(o:, Cc:, or Bcc: line\) in e)-.8 F -.15(ve)-.25 G .045(ry message.).15 F .045 +(If a)5.045 F .562 +(message comes in with no recipients listed in the message then)117 570 R F2 +(sendmail)3.062 E F1 .562(will adjust the header)3.062 F .085 +(based on the \231NoRecipientAction\232 option.)117 582 R .085 +(One of the possible actions is to add an \231)5.085 F(Apparently-)-.8 E -.8 +(To)117 594 S .08(:\232 header line for an).8 F 2.58(yr)-.15 G .08 +(ecipients it is a)218.36 594 R -.1(wa)-.15 G .08(re of.).1 F .08 +(This is not put in as a standard recipient line to)5.08 F -.1(wa)117 606 S +(rn an).1 E 2.5(yr)-.15 G(ecipients that the list is not complete.)159.51 606 Q +(The Apparently-T)142 622.2 Q(o: header is non-standard and is deprecated.)-.8 +E F0 2.5(2.8.3. Pr)102 646.2 R(ecedence)-.18 E F1 .425 +(The Precedence: header can be used as a crude control of message priority)142 +662.4 R 5.425(.I)-.65 G 2.925(tt)455.38 662.4 S .425(weaks the)463.865 662.4 R +(sort order in the queue and can be con\214gured to change the message timeout\ + v)117 674.4 Q(alues.)-.25 E EP +%%Page: 18 13 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-18 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E 2.5(2.9. IDENT)87 96 R(Pr)2.5 E +(otocol Support)-.18 E/F1 10/Times-Italic@0 SF(Sendmail)127 112.2 Q/F2 10 +/Times-Roman@0 SF 1.835(supports the IDENT protocol as de\214ned in RFC 1413.) +4.335 F 1.835(Although this enhances)6.835 F .289 +(identi\214cation of the author of an email message by doing a `)102 124.2 R +.29(`call back')-.74 F 2.79('t)-.74 G 2.79(ot)396.17 124.2 S .29 +(he originating system to)406.74 124.2 R .469(include the o)102 136.2 R .469(w\ +ner of a particular TCP connection in the audit trail it is in no sense perfec\ +t; a deter)-.25 F(-)-.2 E 1.293(mined for)102 148.2 R 1.294 +(ger can easily spoof the IDENT protocol.)-.18 F 1.294(The follo)6.294 F 1.294 +(wing description is e)-.25 F 1.294(xcerpted from)-.15 F(RFC 1413:)102 160.2 Q +2.5(6. Security)127 176.4 R(Considerations)2.5 E .006 +(The information returned by this protocol is at most as trustw)127 192.6 R +(orth)-.1 E 2.505(ya)-.05 G 2.505(st)400.505 192.6 S .005(he host pro)409.68 +192.6 R .005(viding it OR)-.15 F .273(the or)127 204.6 R -.05(ga)-.18 G .273 +(nization operating the host.).05 F -.15(Fo)5.273 G 2.773(re).15 G .274 +(xample, a PC in an open lab has fe)295.308 204.6 R 2.774(wi)-.25 G 2.774(fa) +448.612 204.6 S .574 -.15(ny c)459.156 204.6 T(ontrols).15 E .987(on it to pre) +127 216.6 R -.15(ve)-.25 G .986(nt a user from ha).15 F .986 +(ving this protocol return an)-.2 F 3.486(yi)-.15 G .986 +(denti\214er the user w)378.056 216.6 R 3.486(ants. Lik)-.1 F(e-)-.1 E 1.441(w\ +ise, if the host has been compromised the information returned may be complete\ +ly erro-)127 228.6 R(neous and misleading.)127 240.6 Q .521(The Identi\214cati\ +on Protocol is not intended as an authorization or access control protocol.)127 +256.8 R(At)5.52 E 1.036(best, it pro)127 268.8 R 1.037 +(vides some additional auditing information with respect to TCP connections.) +-.15 F(At)6.037 E -.1(wo)127 280.8 S(rst, it can pro).1 E +(vide misleading, incorrect, or maliciously incorrect information.)-.15 E 1.006 +(The use of the information returned by this protocol for other than auditing \ +is strongly dis-)127 297 R 2.697(couraged. Speci\214cally)127 309 R 2.697(,u) +-.65 G .197(sing Identi\214cation Protocol information to mak)228.114 309 R +2.697(ea)-.1 G .197(ccess control deci-)429.186 309 R .514(sions - either as t\ +he primary method \(i.e., no other checks\) or as an adjunct to other methods) +127 321 R(may result in a weak)127 333 Q(ening of normal host security)-.1 E(.) +-.65 E 1.778(An Identi\214cation serv)127 349.2 R 1.778(er may re)-.15 F -.15 +(ve)-.25 G 1.778(al information about users, entities, objects or processes).15 +F .337(which might normally be considered pri)127 361.2 R -.25(va)-.25 G 2.836 +(te. An).25 F .336(Identi\214cation serv)2.836 F .336(er pro)-.15 F .336 +(vides service which)-.15 F .806 +(is a rough analog of the CallerID services pro)127 373.2 R .806 +(vided by some phone companies and man)-.15 F 3.306(yo)-.15 G(f)500.67 373.2 Q +1.398(the same pri)127 385.2 R -.25(va)-.25 G 1.698 -.15(cy c).25 H 1.398 +(onsiderations and ar).15 F 1.398 +(guments that apply to the CallerID service apply to)-.18 F 3.545 +(Identi\214cation. If)127 397.2 R 1.045(you w)3.545 F(ouldn')-.1 E 3.545(tr) +-.18 G 1.045(un a "\214nger" serv)260.33 397.2 R 1.046(er due to pri)-.15 F +-.25(va)-.25 G 1.346 -.15(cy c).25 H 1.046(onsiderations you may).15 F(not w) +127 409.2 Q(ant to run this protocol.)-.1 E .377 +(In some cases your system may not w)102 425.4 R .377 +(ork properly with IDENT support due to a b)-.1 F .376(ug in the TCP/IP)-.2 F +3.675(implementation. The)102 437.4 R 1.175 +(symptoms will be that for some hosts the SMTP connection will be closed)3.675 +F .566(almost immediately)102 449.4 R 5.566(.I)-.65 G 3.066(ft)192.482 449.4 S +.565(his is true or if you do not w)201.658 449.4 R .565(ant to use IDENT)-.1 F +3.065(,y)-.74 G .565(ou should set the IDENT)401.75 449.4 R +(timeout to zero; this will disable the IDENT protocol.)102 461.4 Q F0 2.5 +(3. ARGUMENTS)72 485.4 R F2 .017(The complete list of ar)112 501.6 R .017 +(guments to)-.18 F F1(sendmail)2.517 E F2 .017 +(is described in detail in Appendix A.)2.517 F .018(Some important)5.018 F(ar) +87 513.6 Q(guments are described here.)-.18 E F0 2.5(3.1. Queue)87 537.6 R +(Inter)2.5 E -.1(va)-.1 G(l).1 E F2 .455(The amount of time between forking a \ +process to run through the queue is de\214ned by the)127 553.8 R F0<ad71>2.955 +E F2 2.675(\215ag. If)102 565.8 R .175(you run with deli)2.675 F -.15(ve)-.25 G +.175(ry mode set to).15 F F0(i)2.675 E F2(or)2.675 E F0(b)2.675 E F2 .176 +(this can be relati)2.675 F -.15(ve)-.25 G .176(ly lar).15 F .176 +(ge, since it will only be rel-)-.18 F -.25(eva)102 577.8 S .207 +(nt when a host that w).25 F .207(as do)-.1 F .207(wn comes back up.)-.25 F +.206(If you run in)5.207 F F0(q)2.706 E F2 .206(mode it should be relati)2.706 +F -.15(ve)-.25 G .206(ly short,).15 F 1.039(since it de\214nes the maximum amo\ +unt of time that a message may sit in the queue.)102 589.8 R 1.039 +(\(See also the)6.039 F(MinQueueAge option.\))102 601.8 Q 1.336 +(RFC 1123 section 5.3.1.1 says that this v)127 618 R 1.335 +(alue should be at least 30 minutes \(although that)-.25 F(probably doesn')102 +630 Q 2.5(tm)-.18 G(ak)179.59 630 Q 2.5(es)-.1 G(ense if you use `)199.76 630 Q +(`queue-only')-.74 E 2.5('m)-.74 G(ode\).)329.08 630 Q F0 2.5(3.2. Daemon)87 +654 R(Mode)2.5 E F2 .084(If you allo)127 670.2 R 2.584(wi)-.25 G .084 +(ncoming mail o)181.162 670.2 R -.15(ve)-.15 G 2.585(ra).15 G 2.585(nI)263.605 +670.2 S .085(PC connection, you should ha)274.52 670.2 R .385 -.15(ve a d)-.2 H +.085(aemon running.).15 F(This)5.085 E .07(should be set by your)102 682.2 R F1 +(/etc/r)2.57 E(c)-.37 E F2 .07(\214le using the)2.57 F F0(\255bd)2.57 E F2 +2.569(\215ag. The)2.57 F F0(\255bd)2.569 E F2 .069(\215ag and the)2.569 F F0 +<ad71>2.569 E F2 .069(\215ag may be combined)2.569 F(in one call:)102 694.2 Q +(/usr/sbin/sendmail \255bd \255q30m)142 710.4 Q EP +%%Page: 19 14 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-19)452.9 60 Q/F1 10/Times-Roman@0 SF .292(An alternati)127 96 R .592 +-.15(ve a)-.25 H .292(pproach is to in).15 F -.2(vo)-.4 G .493 -.1(ke s).2 H +.293(endmail from).1 F/F2 10/Times-Italic@0 SF(inetd)2.793 E F1 .293 +(\(8\) \(use the)B F0(\255bs)2.793 E F1 .293(\215ag to ask sendmail)2.793 F +.255(to speak SMTP on its standard input and output\).)102 108 R .255(This w) +5.255 F .255(orks and allo)-.1 F .255(ws you to wrap)-.25 F F2(sendmail)2.755 E +F1 .255(in a)2.755 F 1.39(TCP wrapper program, b)102 120 R 1.39 +(ut may be a bit slo)-.2 F 1.39 +(wer since the con\214guration \214le has to be re-read on)-.25 F -2.15 -.25 +(ev e)102 132 T .556(ry message that comes in.).25 F .556 +(If you do this, you still need to ha)5.556 F .856 -.15(ve a)-.2 H F2(sendmail) +3.206 E F1 .555(running to \215ush the)3.055 F(queue:)102 144 Q +(/usr/sbin/sendmail \255q30m)142 160.2 Q F0 2.5(3.3. F)87 188.4 R(or)-.25 E +(cing the Queue)-.18 E F1 .04(In some cases you may \214nd that the queue has \ +gotten clogged for some reason.)127 204.6 R -1.1(Yo)5.04 G 2.54(uc)1.1 G .04 +(an force)471.48 204.6 R 3.185(aq)102 216.6 S .685(ueue run using the)114.625 +216.6 R F0<ad71>3.184 E F1 .684(\215ag \(with no v)3.184 F 3.184(alue\). It) +-.25 F .684(is entertaining to use the)3.184 F F0<ad76>3.184 E F1 .684 +(\215ag \(v)3.184 F .684(erbose\) when)-.15 F(this is done to w)102 228.6 Q +(atch what happens:)-.1 E(/usr/sbin/sendmail \255q \255v)142 244.8 Q -1.1(Yo) +127 265.2 S 4.004(uc)1.1 G 1.504 +(an also limit the jobs to those with a particular queue identi\214er)151.564 +265.2 R 4.004(,s)-.4 G(ender)428.362 265.2 Q 4.004(,o)-.4 G 4.004(rr)461.676 +265.2 S(ecipient)472.34 265.2 Q .687(using one of the queue modi\214ers.)102 +277.2 R -.15(Fo)5.687 G 3.187(re).15 G .687(xample, \231\255qRberk)265.659 +277.2 R(ele)-.1 E .686(y\232 restricts the queue run to jobs that)-.15 F(ha)102 +289.2 Q .525 -.15(ve t)-.2 H .225(he string \231berk).15 F(ele)-.1 E .225 +(y\232 some)-.15 F .225(where in one of the recipient addresses.)-.25 F +(Similarly)5.226 E 2.726<2c99>-.65 G .226(\255qSstring\232 lim-)441.184 289.2 R +(its the run to particular senders and \231\255qIstring\232 limits it to parti\ +cular queue identi\214ers.)102 301.2 Q F0 2.5(3.4. Deb)87 325.2 R(ugging)-.2 E +F1 1.365(There are a f)127 341.4 R 1.365(airly lar)-.1 F 1.365 +(ge number of deb)-.18 F 1.365(ug \215ags b)-.2 F 1.365(uilt into)-.2 F F2 +(sendmail)3.865 E F1 6.365(.E)C 1.365(ach deb)417.65 341.4 R 1.365 +(ug \215ag has a)-.2 F 1.116(number and a le)102 353.4 R -.15(ve)-.25 G 1.116 +(l, where higher le).15 F -.15(ve)-.25 G 1.116 +(ls means to print out more information.).15 F 1.116(The con)6.116 F -.15(ve) +-.4 G 1.116(ntion is).15 F .294(that le)102 365.4 R -.15(ve)-.25 G .294 +(ls greater than nine are \231absurd,).15 F 2.794<9a69>-.7 G .294(.e., the) +274.018 365.4 R 2.794(yp)-.15 G .293(rint out so much information that you w) +313.616 365.4 R(ouldn')-.1 E(t)-.18 E .691(normally w)102 377.4 R .692 +(ant to see them e)-.1 F .692(xcept for deb)-.15 F .692 +(ugging that particular piece of code.)-.2 F(Deb)5.692 E .692 +(ug \215ags are set)-.2 F(using the)102 389.4 Q F0<ad64>2.5 E F1 +(option; the syntax is:)2.5 E(deb)142 405.6 Q(ug-\215ag:)-.2 E F0<ad64>200.13 +405.6 Q F1(deb)2.5 E(ug-list)-.2 E(deb)142 417.6 Q 13.05(ug-list: deb)-.2 F +(ug-option [ , deb)-.2 E(ug-option ]*)-.2 E(deb)142 429.6 Q -.28 +(ug-option: deb)-.2 F(ug-range [ . deb)-.2 E(ug-le)-.2 E -.15(ve)-.25 G 2.5(l]) +.15 G(deb)142 441.6 Q 3.07(ug-range: inte)-.2 F(ger | inte)-.15 E +(ger \255 inte)-.15 E(ger)-.15 E(deb)142 453.6 Q(ug-le)-.2 E -.15(ve)-.25 G +6.24(l: inte).15 F(ger)-.15 E(where spaces are for reading ease only)102 469.8 +Q 5(.F)-.65 G(or e)268.64 469.8 Q(xample,)-.15 E 34.99(\255d12 Set)142 486 R +(\215ag 12 to le)2.5 E -.15(ve)-.25 G 2.5(l1).15 G 27.49(\255d12.3 Set)142 498 +R(\215ag 12 to le)2.5 E -.15(ve)-.25 G 2.5(l3).15 G 24.35(\255d3\25517 Set)142 +510 R(\215ags 3 through 17 to le)2.5 E -.15(ve)-.25 G 2.5(l1).15 G 16.85 +(\255d3\25517.4 Set)142 522 R(\215ags 3 through 17 to le)2.5 E -.15(ve)-.25 G +2.5(l4).15 G -.15(Fo)102 538.2 S 4.066(rac).15 G 1.566(omplete list of the a) +132.752 538.2 R -.25(va)-.2 G 1.565(ilable deb).25 F 1.565 +(ug \215ags you will ha)-.2 F 1.865 -.15(ve t)-.2 H 4.065(ol).15 G 1.565 +(ook at the code \(the)380.9 538.2 R 4.065(ya)-.15 G 1.565(re too)479.385 538.2 +R(dynamic to k)102 550.2 Q(eep this documentation up to date\).)-.1 E F0 2.5 +(3.5. Changing)87 574.2 R(the V)2.5 E(alues of Options)-.92 E F1 +(Options can be o)127 590.4 Q -.15(ve)-.15 G(rridden using the).15 E F0<ad6f> +2.5 E F1(or)2.5 E F0<ad4f>2.5 E F1(command line \215ags.)2.5 E -.15(Fo)5 G 2.5 +(re).15 G(xample,)420.27 590.4 Q(/usr/sbin/sendmail \255oT2m)142 606.6 Q .02 +(sets the)102 622.8 R F0(T)2.52 E F1 .02(\(timeout\) option to tw)2.52 F 2.52 +(om)-.1 G .021(inutes for this run only; the equi)246.77 622.8 R -.25(va)-.25 G +.021(lent line using the long option).25 F(name is)102 634.8 Q +(/usr/sbin/sendmail -OQueueT)142 651 Q(imeout=2m)-.35 E .72(Some options ha)127 +671.4 R 1.02 -.15(ve s)-.2 H .72(ecurity implications.).15 F .72(Sendmail allo) +5.72 F .72(ws you to set these, b)-.25 F .72(ut relinquishes)-.2 F EP +%%Page: 20 15 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-20 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF +(its setuid root permissions thereafter)102 98 Q/F2 7/Times-Roman@0 SF(10) +247.54 94 Q F1(.)254.54 98 Q F0 2.5(3.6. T)87 122 R(rying a Differ)-.74 E +(ent Con\214guration File)-.18 E F1(An alternati)127 138.2 Q .3 -.15(ve c)-.25 +H(on\214guration \214le can be speci\214ed using the).15 E F0<ad43>2.5 E F1 +(\215ag; for e)2.5 E(xample,)-.15 E +(/usr/sbin/sendmail \255Ctest.cf \255oQ/tmp/mqueue)142 154.4 Q .429 +(uses the con\214guration \214le)102 170.6 R/F3 10/Times-Italic@0 SF(test.cf) +2.928 E F1 .428(instead of the def)2.928 F(ault)-.1 E F3(/etc/sendmail.cf)2.928 +E(.)-.15 E F1 .428(If the)5.428 F F0<ad43>2.928 E F1 .428(\215ag has no v)2.928 +F(alue)-.25 E(it def)102 182.6 Q(aults to)-.1 E F3(sendmail.cf)2.5 E F1 +(in the current directory)2.5 E(.)-.65 E F3(Sendmail)127 198.8 Q F1(gi)2.679 E +-.15(ve)-.25 G 2.679(su).15 G 2.679(pi)195.288 198.8 S .18 +(ts setuid root permissions when you use this \215ag, so it is common to use a) +205.747 198.8 R .069(publicly writable directory \(such as /tmp\) as the spool\ + directory \(QueueDirectory or Q option\) while)102 210.8 R(testing.)102 222.8 +Q F0 2.5(3.7. Logging)87 246.8 R -.74(Tr)2.5 G(af\214c).74 E F1(Man)127 263 Q +3.254(yS)-.15 G .754(MTP implementations do not fully implement the protocol.) +158.994 263 R -.15(Fo)5.754 G 3.254(re).15 G .755(xample, some per)428.54 263 R +(-)-.2 E 1.178(sonal computer based SMTPs do not understand continuation lines\ + in reply codes.)102 275 R 1.177(These can be)6.178 F -.15(ve)102 287 S .13 +(ry hard to trace.).15 F .13(If you suspect such a problem, you can set traf) +5.13 F .13(\214c logging using the)-.25 F F0<ad58>2.63 E F1 2.63(\215ag. F)2.63 +F(or)-.15 E -.15(ex)102 299 S(ample,).15 E(/usr/sbin/sendmail \255X /tmp/traf) +142 315.2 Q(\214c \255bd)-.25 E(will log all traf)102 331.4 Q +(\214c in the \214le)-.25 E F3(/tmp/tr)2.5 E(af)-.15 E<8c63>-.18 E F1(.)A .998 +(This logs a lot of data v)127 347.6 R .997(ery quickly and should)-.15 F F0 +(NEVER)3.497 E F1 .997(be used during normal operations.)3.497 F .962(After st\ +arting up such a daemon, force the errant implementation to send a message to \ +your host.)102 359.6 R .609(All message traf)102 371.6 R .609 +(\214c in and out of)-.25 F F3(sendmail)3.109 E F1 3.109(,i)C .609 +(ncluding the incoming SMTP traf)281.882 371.6 R .608(\214c, will be logged in) +-.25 F(this \214le.)102 383.6 Q F0 2.5(3.8. T)87 407.6 R +(esting Con\214guration Files)-.92 E F1 .643(When you b)127 423.8 R .644(uild \ +a con\214guration table, you can do a certain amount of testing using the \231\ +test)-.2 F(mode\232 of)102 435.8 Q F3(sendmail)2.5 E F1 5(.F)C(or e)191.01 +435.8 Q(xample, you could in)-.15 E -.2(vo)-.4 G -.1(ke).2 G F3(sendmail)2.6 E +F1(as:)2.5 E(sendmail \255bt \255Ctest.cf)142 452 Q .448(which w)102 468.2 R +.448(ould read the con\214guration \214le \231test.cf\232 and enter test mode.) +-.1 F .447(In this mode, you enter lines)5.447 F(of the form:)102 480.2 Q +(rwset address)142 496.4 Q(where)102 512.6 Q F3(rwset)3.006 E F1 .506 +(is the re)3.006 F .506(writing set you w)-.25 F .506(ant to use and)-.1 F F3 +(addr)3.007 E(ess)-.37 E F1 .507(is an address to apply the set to.)3.007 F -.7 +(Te)5.507 G(st).7 E .794(mode sho)102 524.6 R .794(ws you the steps it tak)-.25 +F .794(es as it proceeds, \214nally sho)-.1 F .794 +(wing you the address it ends up with.)-.25 F -1.1(Yo)102 536.6 S 3.331(um)1.1 +G .832(ay use a comma separated list of rwsets for sequential application of r\ +ules to an input.)129.231 536.6 R -.15(Fo)5.832 G(r).15 E -.15(ex)102 548.6 S +(ample:).15 E(3,1,21,4 monet:bollard)142 564.8 Q .622 +(\214rst applies ruleset three to the input \231monet:bollard.)102 581 R 5.622 +<9a52>-.7 G .622(uleset one is then applied to the output of)334.036 581 R +(ruleset three, follo)102 593 Q(wed similarly by rulesets twenty-one and four) +-.25 E(.)-.55 E 1.084(If you need more detail, you can also use the \231\255d2\ +1\232 \215ag to turn on more deb)127 609.2 R 3.585(ugging. F)-.2 F(or)-.15 E +-.15(ex)102 621.2 S(ample,).15 E(sendmail \255bt \255d21.99)142 637.4 Q .689 +(turns on an incredible amount of information; a single w)102 653.6 R .688 +(ord address is probably going to print out)-.1 F(se)102 665.6 Q -.15(ve)-.25 G +(ral pages w).15 E(orth of information.)-.1 E .32 LW 76 678.8 72 678.8 DL 80 +678.8 76 678.8 DL 84 678.8 80 678.8 DL 88 678.8 84 678.8 DL 92 678.8 88 678.8 +DL 96 678.8 92 678.8 DL 100 678.8 96 678.8 DL 104 678.8 100 678.8 DL 108 678.8 +104 678.8 DL 112 678.8 108 678.8 DL 116 678.8 112 678.8 DL 120 678.8 116 678.8 +DL 124 678.8 120 678.8 DL 128 678.8 124 678.8 DL 132 678.8 128 678.8 DL 136 +678.8 132 678.8 DL 140 678.8 136 678.8 DL 144 678.8 140 678.8 DL 148 678.8 144 +678.8 DL 152 678.8 148 678.8 DL 156 678.8 152 678.8 DL 160 678.8 156 678.8 DL +164 678.8 160 678.8 DL 168 678.8 164 678.8 DL 172 678.8 168 678.8 DL 176 678.8 +172 678.8 DL 180 678.8 176 678.8 DL 184 678.8 180 678.8 DL 188 678.8 184 678.8 +DL 192 678.8 188 678.8 DL 196 678.8 192 678.8 DL 200 678.8 196 678.8 DL 204 +678.8 200 678.8 DL 208 678.8 204 678.8 DL 212 678.8 208 678.8 DL 216 678.8 212 +678.8 DL/F4 5/Times-Roman@0 SF(10)93.6 689.2 Q/F5 8/Times-Roman@0 SF .497 +(That is, it sets its ef)3.2 J(fecti)-.2 E .737 -.12(ve u)-.2 H .497 +(id to the real uid; thus, if you are e).12 F -.12(xe)-.12 G .497 +(cuting as root, as from root').12 F 2.497(sc)-.44 G .497 +(rontab \214le or during system)413.572 692.4 R +(startup the root permissions will still be honored.)72 702 Q EP +%%Page: 21 16 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-21)452.9 60 Q/F1 10/Times-Roman@0 SF -1.1(Yo)127 96 S 2.574(us)1.1 G +.074(hould be w)149.584 96 R .074(arned that internally)-.1 F(,)-.65 E/F2 10 +/Times-Italic@0 SF(sendmail)2.575 E F1 .075 +(applies ruleset 3 to all addresses.)2.575 F .075(In test mode)5.075 F +(you will ha)102 108 Q .3 -.15(ve t)-.2 H 2.5(od).15 G 2.5(ot)173.87 108 S +(hat manually)184.15 108 Q 5(.F)-.65 G(or e)248.35 108 Q(xample, older v)-.15 E +(ersions allo)-.15 E(wed you to use)-.25 E 2.5(0b)142 124.2 S +(ruce@broadcast.son)154.5 124.2 Q -.65(y.)-.15 G(com).65 E(This v)102 140.4 Q +(ersion requires that you use:)-.15 E(3,0 bruce@broadcast.son)142 156.6 Q -.65 +(y.)-.15 G(com).65 E(As of v)127 177 Q(ersion 8.7, some other syntax)-.15 E +(es are a)-.15 E -.25(va)-.2 G(ilable in test mode:).25 E 5<832e>107 193.2 S +1.666(Dxv)118 193.2 S .328(alue de\214nes macro)-1.916 F F2(x)2.828 E F1 .328 +(to ha)2.828 F .628 -.15(ve t)-.2 H .328(he indicated).15 F F2(value)2.828 E F1 +5.328(.T)C .328(his is useful when deb)346.134 193.2 R .327(ugging rules that) +-.2 F(use the)115.5 205.2 Q F0($&)2.5 E F2(x)A F1(syntax.)2.5 E 5<832e>107 +217.2 S 1.666(Ccv)118 217.2 S(alue adds the indicated)-1.916 E F2(value)2.5 E +F1(to class)2.5 E F2(c)2.5 E F1(.)A 5<832e>107 229.2 S 1.666(Sr)118 229.2 S +(uleset dumps the contents of the indicated ruleset.)-1.666 E 5<83ad>107 241.2 +S 1.666(dd)121.14 241.2 S(eb)-1.666 E(ug-spec is equi)-.2 E -.25(va)-.25 G +(lent to the command-line \215ag.).25 E F0 2.5(4. TUNING)72 265.2 R F1 1.922 +(There are a number of con\214guration parameters you may w)112 281.4 R 1.922 +(ant to change, depending on the)-.1 F .367(requirements of your site.)87 293.4 +R .366(Most of these are set using an option in the con\214guration \214le.) +5.367 F -.15(Fo)5.366 G 2.866(re).15 G(xample,)472.06 293.4 Q(the line \231O T) +87 305.4 Q(imeout.queuereturn=5d\232 sets option \231T)-.35 E +(imeout.queuereturn\232 to the v)-.35 E(alue \2315d\232 \(\214v)-.25 E 2.5(ed) +-.15 G(ays\).)476.47 305.4 Q .735(Most of these options ha)112 321.6 R 1.035 +-.15(ve a)-.2 H .735(ppropriate def).15 F .735(aults for most sites.)-.1 F(Ho) +5.735 E(we)-.25 E -.15(ve)-.25 G 1.535 -.4(r, s).15 H .735(ites ha).4 F .735 +(ving v)-.2 F .735(ery high)-.15 F .046(mail loads may \214nd the)87 333.6 R +2.546(yn)-.15 G .046(eed to tune them as appropriate for their mail load.) +193.47 333.6 R .045(In particular)5.045 F 2.545(,s)-.4 G .045(ites e)459.395 +333.6 R(xperi-)-.15 E 1.087(encing a lar)87 345.6 R 1.087 +(ge number of small messages, man)-.18 F 3.587(yo)-.15 G 3.588(fw)294.496 345.6 +S 1.088(hich are deli)308.634 345.6 R -.15(ve)-.25 G 1.088(red to man).15 F +3.588(yr)-.15 G 1.088(ecipients, may \214nd)425.994 345.6 R(that the)87 357.6 Q +2.5(yn)-.15 G(eed to adjust the parameters dealing with queue priorities.) +129.07 357.6 Q .524(All v)112 373.8 R .524(ersions of)-.15 F F2(sendmail)3.024 +E F1 .524(prior to 8.7 had single character option names.)3.024 F .523 +(As of 8.7, options ha)5.524 F -.15(ve)-.2 G 1.215 +(long \(multi-character names\).)87 385.8 R 1.216 +(Although old short names are still accepted, most ne)6.215 F 3.716(wo)-.25 G +1.216(ptions do not)449.338 385.8 R(ha)87 397.8 Q .3 -.15(ve s)-.2 H(hort equi) +.15 E -.25(va)-.25 G(lents.).25 E .802 +(This section only describes the options you are most lik)112 414 R .802 +(ely to w)-.1 F .801(ant to tweak; read section 5 for)-.1 F(more details.)87 +426 Q F0 2.5(4.1. T)87 450 R(imeouts)-.18 E F1 .582(All time interv)127 466.2 R +.583(als are set using a scaled syntax.)-.25 F -.15(Fo)5.583 G 3.083(re).15 G +.583(xample, \23110m\232 represents ten minutes,)346.138 466.2 R +(whereas \2312h30m\232 represents tw)102 478.2 Q 2.5(oa)-.1 G(nd a half hours.) +241.3 478.2 Q(The full set of scales is:)5 E 16.11(ss)142 494.4 S(econds)165.89 +494.4 Q 12.22(mm)142 506.4 S(inutes)169.78 506.4 Q 15(hh)142 518.4 S(ours)167 +518.4 Q 15(dd)142 530.4 S(ays)167 530.4 Q 12.78(ww)142 542.4 S(eeks)169.22 +542.4 Q F0 2.5(4.1.1. Queue)102 570.6 R(inter)2.5 E -.1(va)-.1 G(l).1 E F1 .18 +(The ar)142 586.8 R .18(gument to the)-.18 F F0<ad71>2.68 E F1 .18 +(\215ag speci\214es ho)2.68 F 2.68(wo)-.25 G .18 +(ften a sub-daemon will run the queue.)319.25 586.8 R .18(This is)5.18 F .967 +(typically set to between \214fteen minutes and one hour)117 598.8 R 5.968(.R) +-.55 G .968(FC 1123 section 5.3.1.1 recommends)350.968 598.8 R +(that this be at least 30 minutes.)117 610.8 Q F0 2.5(4.1.2. Read)102 634.8 R +(timeouts)2.5 E F1 -.35(Ti)142 651 S 1.053(meouts all ha).35 F 1.352 -.15(ve o) +-.2 H 1.052(ption names \231T).15 F(imeout.)-.35 E F2(suboption)A F1 3.552 +(\232. The)B(recognized)3.552 E F2(suboption)3.552 E F1 1.052(s, their)B(def) +117 663 Q(ault v)-.1 E(alues, and the minimum v)-.25 E(alues allo)-.25 E +(wed by RFC 1123 section 5.3.2 are:)-.25 E 38.4(connect The)117 679.2 R .16 +(time to w)2.66 F .161(ait for an SMTP connection to open \(the)-.1 F F2 +(connect)2.661 E F1 .161(\(2\) system call\))B 1.154([0, unspeci\214ed].)189 +691.2 R 1.153(If zero, uses the k)6.153 F 1.153(ernel def)-.1 F 3.653(ault. In) +-.1 F 1.153(no case can this option)3.653 F -.15(ex)189 703.2 S .518 +(tend the timeout longer than the k).15 F .518(ernel pro)-.1 F .519(vides, b) +-.15 F .519(ut it can shorten it.)-.2 F(This)5.519 E .58(is to get around k)189 +715.2 R .579(ernels that pro)-.1 F .579 +(vide an absurdly long connection timeout \(90)-.15 F EP +%%Page: 22 17 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-22 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF +(minutes in one case\).)189 96 Q 46.16(initial The)117 112.2 R -.1(wa)2.5 G +(it for the initial 220 greeting message [5m, 5m].).1 E 52.28(helo The)117 +128.4 R -.1(wa)4.226 G 1.727 +(it for a reply from a HELO or EHLO command [5m, unspeci\214ed].).1 F .1 +(This may require a host name lookup, so \214v)189 140.4 R 2.6(em)-.15 G .1 +(inutes is probably a reasonable)380.29 140.4 R(minimum.)189 152.4 Q 46.72 +(mail\207 The)117 168.6 R -.1(wa)2.5 G +(it for a reply from a MAIL command [10m, 5m].).1 E 48.95(rcpt\207 The)117 +184.8 R -.1(wa)3.481 G .981(it for a reply from a RCPT command [1h, 5m].).1 F +.982(This should be long)5.982 F 1.556 +(because it could be pointing at a list that tak)189 196.8 R 1.556 +(es a long time to e)-.1 F 1.556(xpand \(see)-.15 F(belo)189 208.8 Q(w\).)-.25 +E 34.5(datainit\207 The)117 225 R -.1(wa)2.5 G(it for a reply from a D).1 E +-1.21 -1.11(AT A)-.4 H(command [5m, 2m].)3.61 E 25.62(datablock\207 The)117 +241.2 R -.1(wa)2.696 G .196 +(it for reading a data block \(that is, the body of the message\).).1 F .196 +([1h, 3m].)5.196 F .621 +(This should be long because it also applies to programs piping input to)189 +253.2 R/F2 10/Times-Italic@0 SF(send-)3.12 E(mail)189 265.2 Q F1(which ha)2.5 E +.3 -.15(ve n)-.2 H 2.5(og).15 G(uarantee of promptness.)274.75 265.2 Q 30.06 +(data\214nal\207 The)117 281.4 R -.1(wa)2.806 G .306 +(it for a reply from the dot terminating a message.).1 F .306([1h, 10m].)5.306 +F .306(If this is)5.306 F .884 +(shorter than the time actually needed for the recei)189 293.4 R -.15(ve)-.25 G +3.383(rt).15 G 3.383(od)412.881 293.4 S(eli)426.264 293.4 Q -.15(ve)-.25 G +3.383(rt).15 G .883(he message,)454.797 293.4 R(duplicates will be generated.) +189 305.4 Q(This is discussed in RFC 1047.)5 E 55.06(rset The)117 321.6 R -.1 +(wa)2.5 G(it for a reply from a RSET command [5m, unspeci\214ed].).1 E 53.94 +(quit The)117 337.8 R -.1(wa)2.5 G(it for a reply from a Q).1 E +(UIT command [2m, unspeci\214ed].)-.1 E 50.61(misc The)117 354 R -.1(wa)2.76 G +.261(it for a reply from miscellaneous \(b).1 F .261 +(ut short\) commands such as NOOP)-.2 F(\(no-operation\) and VERB \(go into v) +189 366 Q(erbose mode\).)-.15 E([2m, unspeci\214ed].)5 E 25.06(command\207 In) +117 382.2 R(serv)2.5 E(er SMTP)-.15 E 2.5(,t)-1.11 G(he time to w)259.4 382.2 Q +(ait for another command.)-.1 E([1h, 5m].)5 E 49.5(ident The)117 400.4 R +(timeout w)2.5 E(aiting for a reply to an IDENT query [30s)-.1 E/F3 7 +/Times-Roman@0 SF(11)413.86 396.4 Q F1 2.5(,u)420.86 400.4 S(nspeci\214ed].) +430.86 400.4 Q -.15(Fo)117 416.6 S 4.609(rc).15 G 2.109 +(ompatibility with old con\214guration \214les, if no)139.789 416.6 R F2 +(suboption)4.608 E F1 2.108(is speci\214ed, all the timeouts)4.608 F(mark)117 +428.6 Q(ed with \207 are set to the indicated v)-.1 E(alue.)-.25 E(Man)142 +444.8 Q 2.5(yo)-.15 G 2.5(ft)172.68 444.8 S(he RFC 1123 minimum v)181.29 444.8 +Q .001(alues may well be too short.)-.25 F F2(Sendmail)5.001 E F1 -.1(wa)2.501 +G 2.501(sd).1 G .001(esigned to)463.169 444.8 R .712 +(the RFC 822 protocols, which did not specify read timeouts; hence, v)117 456.8 +R .711(ersions of)-.15 F F2(sendmail)3.211 E F1(prior)3.211 E .864(to v)117 +468.8 R .865(ersion 8.1 did not guarantee to reply to messages promptly)-.15 F +5.865(.I)-.65 G 3.365(np)386.24 468.8 S(articular)399.605 468.8 Q 3.365(,a\231) +-.4 G .865(RCPT\232 com-)450.635 468.8 R .061 +(mand specifying a mailing list will e)117 480.8 R .061(xpand and v)-.15 F .06 +(erify the entire list; a lar)-.15 F .06(ge list on a slo)-.18 F 2.56(ws)-.25 G +(ystem)480.11 480.8 Q .436(may easily tak)117 494.8 R 2.936(em)-.1 G .436 +(ore than \214v)190.698 494.8 R 2.936(em)-.15 G(inutes)252.126 494.8 Q F3(12) +276.016 490.8 Q F1 5.436(.I)283.016 494.8 S .435 +(recommend a one hour timeout \212 since a commu-)297.218 494.8 R 1.365 +(nications f)117 506.8 R 1.366(ailure during the RCPT phase is rare, a long ti\ +meout is not onerous and may ulti-)-.1 F(mately help reduce netw)117 518.8 Q +(ork load and duplicated messages.)-.1 E -.15(Fo)142 535 S 2.5(re).15 G +(xample, the lines:)162.53 535 Q 2.5(OT)157 551.2 S(imeout.command=25m)172.48 +551.2 Q 2.5(OT)157 563.2 S(imeout.datablock=3h)172.48 563.2 Q .344 +(sets the serv)117 579.4 R .344(er SMTP command timeout to 25 minutes and the \ +input data block timeout to three)-.15 F(hours.)117 591.4 Q F0 2.5 +(4.1.3. Message)102 615.4 R(timeouts)2.5 E F1 .237 +(After sitting in the queue for a fe)142 631.6 R 2.737(wd)-.25 G .237 +(ays, a message will time out.)289.726 631.6 R .238(This is to insure that at) +5.238 F .568(least the sender is a)117 643.6 R -.1(wa)-.15 G .568 +(re of the inability to send a message.).1 F .567 +(The timeout is typically set to \214v)5.568 F(e)-.15 E 2.599(days. It)117 +655.6 R .099(is sometimes considered con)2.599 F -.15(ve)-.4 G .099 +(nient to also send a w).15 F .1(arning message if the message is in)-.1 F .32 +LW 76 665.2 72 665.2 DL 80 665.2 76 665.2 DL 84 665.2 80 665.2 DL 88 665.2 84 +665.2 DL 92 665.2 88 665.2 DL 96 665.2 92 665.2 DL 100 665.2 96 665.2 DL 104 +665.2 100 665.2 DL 108 665.2 104 665.2 DL 112 665.2 108 665.2 DL 116 665.2 112 +665.2 DL 120 665.2 116 665.2 DL 124 665.2 120 665.2 DL 128 665.2 124 665.2 DL +132 665.2 128 665.2 DL 136 665.2 132 665.2 DL 140 665.2 136 665.2 DL 144 665.2 +140 665.2 DL 148 665.2 144 665.2 DL 152 665.2 148 665.2 DL 156 665.2 152 665.2 +DL 160 665.2 156 665.2 DL 164 665.2 160 665.2 DL 168 665.2 164 665.2 DL 172 +665.2 168 665.2 DL 176 665.2 172 665.2 DL 180 665.2 176 665.2 DL 184 665.2 180 +665.2 DL 188 665.2 184 665.2 DL 192 665.2 188 665.2 DL 196 665.2 192 665.2 DL +200 665.2 196 665.2 DL 204 665.2 200 665.2 DL 208 665.2 204 665.2 DL 212 665.2 +208 665.2 DL 216 665.2 212 665.2 DL/F4 5/Times-Roman@0 SF(11)93.6 675.6 Q/F5 8 +/Times-Roman@0 SF(On some systems the def)3.2 I +(ault is zero to turn the protocol of)-.08 E 2(fe)-.2 G(ntirely)293.848 678.8 Q +(.)-.52 E F4(12)93.6 689.2 Q F5 .212(This v)3.2 J .212 +(eri\214cation includes looking up e)-.12 F -.12(ve)-.2 G .212 +(ry address with the name serv).12 F .212(er; this in)-.12 F -.16(vo)-.32 G(lv) +.16 E .212(es netw)-.12 F .213(ork delays, and can in some cases)-.08 F +(can be considerable.)72 702 Q EP +%%Page: 23 18 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-23)452.9 60 Q/F1 10/Times-Roman@0 SF .176(the queue longer than a fe) +117 96 R 2.675(wh)-.25 G .175(ours \(assuming you normally ha)236.105 96 R .475 +-.15(ve g)-.2 H .175(ood connecti).15 F .175(vity; if your mes-)-.25 F .645 +(sages normally took se)117 108 R -.15(ve)-.25 G .645(ral hours to send you w) +.15 F(ouldn')-.1 E 3.145(tw)-.18 G .645(ant to do this because it w)355.055 108 +R(ouldn')-.1 E 3.145(tb)-.18 G(e)499.56 108 Q 3.871(an unusual e)117 120 R -.15 +(ve)-.25 G 6.371(nt\). These).15 F 3.871(timeouts are set using the)6.371 F F0 +-.18(Ti)6.371 G(meout.queuer).18 E(etur)-.18 E(n)-.15 E F1(and)6.371 E F0 -.18 +(Ti)6.37 G(me-).18 E(out.queuewar)117 132 Q(n)-.15 E F1 +(options in the con\214guration \214le \(pre)2.5 E +(viously both were set using the)-.25 E F0(T)2.5 E F1(option\).)2.5 E .106 +(Since these options are global, and since you can not kno)142 148.2 R(w)-.25 E +/F2 10/Times-Italic@0 SF 2.606(ap)2.606 G(riori)393.822 148.2 Q F1(ho)2.607 E +2.607(wl)-.25 G .107(ong another host)437.126 148.2 R .476 +(outside your domain will be do)117 160.2 R .475(wn, a \214v)-.25 F 2.975(ed) +-.15 G .475(ay timeout is recommended.)291.785 160.2 R .475(This allo)5.475 F +.475(ws a recipient)-.25 F 1.579(to \214x the problem e)117 172.2 R -.15(ve) +-.25 G 4.079(ni).15 G 4.079(fi)222.545 172.2 S 4.079(to)232.734 172.2 S 1.579 +(ccurs at the be)244.593 172.2 R 1.58(ginning of a long week)-.15 F 4.08 +(end. RFC)-.1 F 1.58(1123 section)4.08 F +(5.3.1.1 says that this parameter should be `)117 184.2 Q +(`at least 4\2555 days')-.74 E('.)-.74 E(The)142 200.4 Q F0 -.18(Ti)2.923 G +(meout.queuewar).18 E(n)-.15 E F1 -.25(va)2.923 G .423(lue can be piggyback).25 +F .422(ed on the)-.1 F F0(T)2.922 E F1 .422(option by indicating a time)2.922 F +.845(after which a w)117 212.4 R .845(arning message should be sent; the tw)-.1 +F 3.346(ot)-.1 G .846(imeouts are separated by a slash.)349.104 212.4 R -.15 +(Fo)5.846 G(r).15 E -.15(ex)117 224.4 S(ample, the line).15 E -.4(OT)157 240.6 +S(5d/4h).4 E .972(causes email to f)117 256.8 R .971(ail after \214v)-.1 F +3.471(ed)-.15 G .971(ays, b)245.329 256.8 R .971(ut a w)-.2 F .971 +(arning message will be sent after four hours.)-.1 F(This)5.971 E +(should be lar)117 268.8 Q(ge enough that the message will ha)-.18 E .3 -.15 +(ve b)-.2 H(een tried se).15 E -.15(ve)-.25 G(ral times.).15 E F0 2.5(4.2. F)87 +292.8 R(orking During Queue Runs)-.25 E F1 .848(By setting the)127 309 R F0 +-.25(Fo)3.348 G(rkEachJ).25 E(ob)-.15 E F1(\()3.348 E F0(Y)A F1 3.348(\)o)C +(ption,)271.12 309 Q F2(sendmail)3.348 E F1 .849(will fork before each indi) +3.348 F .849(vidual message)-.25 F .293(while running the queue.)102 321 R .293 +(This will pre)5.293 F -.15(ve)-.25 G(nt).15 E F2(sendmail)2.793 E F1 .293 +(from consuming lar)2.793 F .293(ge amounts of memory)-.18 F 2.792(,s)-.65 G(o) +499 321 Q 1.11(it may be useful in memory-poor en)102 333 R 3.61 +(vironments. Ho)-.4 F(we)-.25 E -.15(ve)-.25 G 1.91 -.4(r, i).15 H 3.61(ft).4 G +(he)359.95 333 Q F0 -.25(Fo)3.61 G(rkEachJ).25 E(ob)-.15 E F1 1.11 +(option is not set,)3.61 F F2(sendmail)102 345 Q F1 .085(will k)2.585 F .085 +(eep track of hosts that are do)-.1 F .084 +(wn during a queue run, which can impro)-.25 F .384 -.15(ve p)-.15 H +(erformance).15 E(dramatically)102 357 Q(.)-.65 E(If the)127 373.2 Q F0 -.25 +(Fo)2.5 G(rkEachJ).25 E(ob)-.15 E F1(option is set,)2.5 E F2(sendmail)2.5 E F1 +(can not use connection caching.)2.5 E F0 2.5(4.3. Queue)87 397.2 R(Priorities) +2.5 E F1(Ev)127 413.4 Q 1.128(ery message is assigned a priority when it is \ +\214rst instantiated, consisting of the message)-.15 F .286 +(size \(in bytes\) of)102 425.4 R .286(fset by the message class \(which is de\ +termined from the Precedence: header\) times)-.25 F .342(the \231w)102 437.4 R +.342(ork class f)-.1 F .343 +(actor\232 and the number of recipients times the \231w)-.1 F .343 +(ork recipient f)-.1 F(actor)-.1 E 4.243 -.7(.\232 T)-.55 H .343(he priority).7 +F .073(is used to order the queue.)102 449.4 R .073 +(Higher numbers for the priority mean that the message will be processed)5.073 +F(later when running the queue.)102 461.4 Q .328 +(The message size is included so that lar)127 477.6 R .329 +(ge messages are penalized relati)-.18 F .629 -.15(ve t)-.25 H 2.829(os).15 G +.329(mall messages.)443.121 477.6 R .285(The message class allo)102 489.6 R +.285(ws users to send \231high priority\232 messages by including a \231Preced\ +ence:\232 \214eld)-.25 F .007(in their message; the v)102 501.6 R .007 +(alue of this \214eld is look)-.25 F .008(ed up in the)-.1 F F0(P)2.508 E F1 +.008(lines of the con\214guration \214le.)2.508 F .008(Since the)5.008 F 1.967 +(number of recipients af)102 513.6 R 1.967 +(fects the amount of load a message presents to the system, this is also)-.25 F +(included into the priority)102 525.6 Q(.)-.65 E .53(The recipient and class f) +127 541.8 R .53(actors can be set in the con\214guration \214le using the)-.1 F +F0(RecipientF)3.03 E(actor)-.25 E F1(\()102 553.8 Q F0(y)A F1 3.443(\)a)C(nd) +121.543 553.8 Q F0(ClassF)3.443 E(actor)-.25 E F1(\()3.442 E F0(z)A F1 3.442 +(\)o)C .942(ptions respecti)208.82 553.8 R -.15(ve)-.25 G(ly).15 E 5.942(.T) +-.65 G(he)298.534 553.8 Q 3.442(yd)-.15 G(ef)321.266 553.8 Q .942 +(ault to 30000 \(for the recipient f)-.1 F .942(actor\) and)-.1 F +(1800 \(for the class f)102 565.8 Q 2.5(actor\). The)-.1 F +(initial priority is:)2.5 E F2(pri)168.495 583.8 Q/F3 10/Symbol SF(=)3.16 E F2 +(msgsize)3.18 E F3(-)2.38 E F1(\()2.2 E F2(class).2 E F3<b4>2.47 E F0 +(ClassFactor\))2.2 E F3(+)2.2 E F1(\()2.2 E F2(nrcpt).36 E F3<b4>2.88 E F0 +(RecipientFactor\))2.2 E F1(\(Remember)102 601.8 Q 3.328(,h)-.4 G .828(igher v) +159.638 601.8 R .828 +(alues for this parameter actually mean that the job will be treated with lo) +-.25 F(wer)-.25 E(priority)102 613.8 Q(.\))-.65 E 1.519(The priority of a job \ +can also be adjusted each time it is processed \(that is, each time an)127 630 +R .235(attempt is made to deli)102 642 R -.15(ve)-.25 G 2.736(ri).15 G .236 +(t\) using the \231w)211.938 642 R .236(ork time f)-.1 F(actor)-.1 E 1.636 -.7 +(,\232 s)-.4 H .236(et by the).7 F F0(RetryF)2.736 E(actor)-.25 E F1(\()2.736 E +F0(Z)A F1 2.736(\)o)C 2.736(ption. This)457.924 642 R .367 +(is added to the priority)102 654 R 2.867(,s)-.65 G 2.867(oi)202.625 654 S +2.867(tn)213.272 654 S .366 +(ormally decreases the precedence of the job, on the grounds that jobs)223.919 +654 R .137(that ha)102 666 R .437 -.15(ve f)-.2 H .137(ailed man).05 F 2.637 +(yt)-.15 G .137(imes will tend to f)193.598 666 R .137(ail ag)-.1 F .137 +(ain in the future.)-.05 F(The)5.137 E F0(RetryF)2.637 E(actor)-.25 E F1 .137 +(option def)2.637 F .138(aults to)-.1 F(90000.)102 678 Q EP +%%Page: 24 19 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-24 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E 2.5(4.4. Load)87 96 R(Limiting)2.5 E/F1 +10/Times-Italic@0 SF(Sendmail)127 112.2 Q/F2 10/Times-Roman@0 SF .102 +(can be ask)2.602 F .101(ed to queue \(b)-.1 F .101(ut not deli)-.2 F -.15(ve) +-.25 G .101(r\) mail if the system load a).15 F -.15(ve)-.2 G .101 +(rage gets too high).15 F .483(using the)102 124.2 R F0(QueueLA)2.983 E F2(\() +2.983 E F0(x)A F2 2.983(\)o)C 2.983(ption. When)206.152 124.2 R .483 +(the load a)2.983 F -.15(ve)-.2 G .483(rage e).15 F .483(xceeds the v)-.15 F +.484(alue of the)-.25 F F0(QueueLA)2.984 E F2(option,)2.984 E .532(the deli)102 +136.2 R -.15(ve)-.25 G .532(ry mode is set to).15 F F0(q)3.032 E F2 .532 +(\(queue only\) if the)3.032 F F0(QueueF)3.032 E(actor)-.25 E F2(\()3.032 E F0 +(q)A F2 3.032(\)o)C .531(ption di)379.066 136.2 R .531(vided by the dif)-.25 F +(ference)-.25 E .004(in the current load a)102 148.2 R -.15(ve)-.2 G .004 +(rage and the).15 F F0(QueueLA)2.504 E F2 .004(option plus one e)2.504 F .004 +(xceeds the priority of the message \212)-.15 F +(that is, the message is queued if)102 160.2 Q(f:)-.25 E F1(pri)251.425 183.61 +Q F2(>)3.16 E F0(QueueFactor)287.21 176.61 Q F1(LA)276.475 190.61 Q/F3 10 +/Symbol SF(-)2.23 E F0(QueueLA)2.2 E F3(+)2.2 E .4 LW 354.625 181.01 275.895 +181.01 DL F2(1)349.625 190.61 Q(The)102 206.87 Q F0(QueueF)2.616 E(actor)-.25 E +F2 .116(option def)2.616 F .116(aults to 600000, so each point of load a)-.1 F +-.15(ve)-.2 G .116(rage is w).15 F .116(orth 600000 priority)-.1 F +(points \(as described abo)102 218.87 Q -.15(ve)-.15 G(\).).15 E -.15(Fo)127 +235.07 S 3.893(rd).15 G 1.393(rastic cases, the)149.633 235.07 R F0(RefuseLA) +3.893 E F2(\()3.893 E F0(X)A F2 3.893(\)o)C 1.394(ption de\214nes a load a) +288.228 235.07 R -.15(ve)-.2 G 1.394(rage at which).15 F F1(sendmail)3.894 E F2 +(will)3.894 E .69(refuse to accept netw)102 247.07 R .689(ork connections.)-.1 +F .689(Locally generated mail \(including incoming UUCP mail\) is)5.689 F +(still accepted.)102 259.07 Q F0 2.5(4.5. Deli)87 283.07 R -.1(ve)-.1 G +(ry Mode).1 E F2 .253(There are a number of deli)127 299.27 R -.15(ve)-.25 G +.253(ry modes that).15 F F1(sendmail)2.753 E F2 .254 +(can operate in, set by the)2.753 F F0(Deli)2.754 E -.1(ve)-.1 G(ryMode).1 E F2 +(\()102 311.27 Q F0(d)A F2 3.599(\)c)C 1.099(on\214guration option.)122.259 +311.27 R 1.099(These modes specify ho)6.099 F 3.598(wq)-.25 G 1.098 +(uickly mail will be deli)324.142 311.27 R -.15(ve)-.25 G 3.598(red. Le).15 F +-.05(ga)-.15 G 3.598(lm).05 G(odes)485.67 311.27 Q(are:)102 323.27 Q 17.22(id) +142 339.47 S(eli)167 339.47 Q -.15(ve)-.25 G 2.5(ri).15 G(nteracti)194.65 +339.47 Q -.15(ve)-.25 G(ly \(synchronously\)).15 E 15(bd)142 351.47 S(eli)167 +351.47 Q -.15(ve)-.25 G 2.5(ri).15 G 2.5(nb)194.65 351.47 S +(ackground \(asynchronously\))207.15 351.47 Q 15(qq)142 363.47 S +(ueue only \(don')167 363.47 Q 2.5(td)-.18 G(eli)240.42 363.47 Q -.15(ve)-.25 G +(r\)).15 E 15(dd)142 375.47 S(efer delv)167 375.47 Q(ery attempts \(don')-.15 E +2.5(td)-.18 G(eli)285.53 375.47 Q -.15(ve)-.25 G(r\)).15 E 1.273 +(There are tradeof)102 391.67 R 3.773(fs. Mode)-.25 F 1.273(\231i\232 gi)3.773 +F -.15(ve)-.25 G 3.773(st).15 G 1.273(he sender the quick)258.938 391.67 R +1.273(est feedback, b)-.1 F 1.274(ut may slo)-.2 F 3.774(wd)-.25 G -.25(ow) +462.146 391.67 S 3.774(ns).25 G(ome)486.78 391.67 Q .799 +(mailers and is hardly e)102 403.67 R -.15(ve)-.25 G 3.299(rn).15 G(ecessary) +216.405 403.67 Q 5.799(.M)-.65 G .799(ode \231b\232 deli)266.814 403.67 R -.15 +(ve)-.25 G .799(rs promptly b).15 F .798(ut can cause lar)-.2 F .798 +(ge numbers of)-.18 F .223(processes if you ha)102 415.67 R .524 -.15(ve a m) +-.2 H .224(ailer that tak).15 F .224(es a long time to deli)-.1 F -.15(ve)-.25 +G 2.724(ram).15 G 2.724(essage. Mode)370.904 415.67 R .224 +(\231q\232 minimizes the)2.724 F .597(load on your machine, b)102 427.67 R .597 +(ut means that deli)-.2 F -.15(ve)-.25 G .596 +(ry may be delayed for up to the queue interv).15 F 3.096(al. Mode)-.25 F .039 +(\231d\232 is identical to mode \231q\232 e)102 439.67 R .039 +(xcept that it also pre)-.15 F -.15(ve)-.25 G .04 +(nts all the early map lookups from w).15 F .04(orking; it is)-.1 F .086 +(intended for `)102 451.67 R .086(`dial on demand')-.74 F 2.586('s)-.74 G .085 +(ites where DNS lookups might cost real mone)233.42 451.67 R 3.885 -.65(y. S) +-.15 H .085(ome simple error).65 F .817(messages \(e.g., host unkno)102 463.67 +R .817(wn during the SMTP protocol\) will be delayed using this mode.)-.25 F +(Mode)5.818 E(\231b\232 is the usual def)102 475.67 Q(ault.)-.1 E .052(If you \ +run in mode \231q\232 \(queue only\), \231d\232 \(defer\), or \231b\232 \(deli) +127 491.87 R -.15(ve)-.25 G 2.552(ri).15 G 2.552(nb)389.136 491.87 S +(ackground\))401.688 491.87 Q F1(sendmail)2.551 E F2(will)2.551 E 1.391(not e) +102 503.87 R 1.392(xpand aliases and follo)-.15 F 3.892(w.)-.25 G(forw)232.428 +503.87 Q 1.392(ard \214les upon initial receipt of the mail.)-.1 F 1.392 +(This speeds up the)6.392 F(response to RCPT commands.)102 515.87 Q +(Mode \231i\232 cannot be used by the SMTP serv)5 E(er)-.15 E(.)-.55 E F0 2.5 +(4.6. Log)87 539.87 R(Le)2.5 E -.1(ve)-.15 G(l).1 E F2 .19(The le)127 556.07 R +-.15(ve)-.25 G 2.69(lo).15 G 2.69(fl)171.97 556.07 S .19(ogging can be set for) +180.77 556.07 R F1(sendmail)2.689 E F2 5.189(.T)C .189(he def)317.996 556.07 R +.189(ault using a standard con\214guration table)-.1 F(is le)102 568.07 Q -.15 +(ve)-.25 G 2.5(l9).15 G 5(.T)137.71 568.07 S(he le)151.32 568.07 Q -.15(ve)-.25 +G(ls are as follo).15 E(ws:)-.25 E 31(0N)102 584.27 S 2.5(ol)145.22 584.27 S +(ogging.)155.5 584.27 Q 31(1S)102 600.47 S(erious system f)143.56 600.47 Q +(ailures and potential security problems.)-.1 E 31(2L)102 616.67 S +(ost communications \(netw)144.11 616.67 Q(ork problems\) and protocol f)-.1 E +(ailures.)-.1 E 31(3O)102 632.87 S(ther serious f)145.22 632.87 Q(ailures.)-.1 +E 31(4M)102 649.07 S(inor f)146.89 649.07 Q(ailures.)-.1 E 31(5M)102 665.27 S +(essage collection statistics.)146.89 665.27 Q 31(6C)102 681.47 S +(reation of error messages, VRFY and EXPN commands.)144.67 681.47 Q 31(7D)102 +697.67 S(eli)145.22 697.67 Q -.15(ve)-.25 G(ry f).15 E +(ailures \(host or user unkno)-.1 E(wn, etc.\).)-.25 E 31(8S)102 713.87 S +(uccessful deli)143.56 713.87 Q -.15(ve)-.25 G(ries and alias database reb).15 +E(uilds.)-.2 E EP +%%Page: 25 20 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-25)452.9 60 Q/F1 10/Times-Roman@0 SF 31(9M)102 96 S +(essages being deferred \(due to a host being do)146.89 96 Q(wn, etc.\).)-.25 E +23.5(10 Database)102 112.2 R -.15(ex)2.5 G(pansion \(alias, forw).15 E +(ard, and userdb lookups\).)-.1 E 23.5(20 Logs)102 128.4 R .603 +(attempts to run lock)3.102 F .603(ed queue \214les.)-.1 F .603 +(These are not errors, b)5.603 F .603(ut can be useful to note if)-.2 F +(your queue appears to be clogged.)138 140.4 Q 23.5(30 Lost)102 156.6 R +(locks \(only if using lockf instead of \215ock\).)2.5 E(Additionally)102 172.8 +Q 2.717(,v)-.65 G .217(alues abo)161.877 172.8 R .516 -.15(ve 6)-.15 H 2.716 +(4a).15 G .216(re reserv)228.596 172.8 R .216(ed for e)-.15 F .216(xtremely v) +-.15 F .216(erbose deb)-.15 F .216(ugging output.)-.2 F .216(No normal site) +5.216 F -.1(wo)102 184.8 S(uld e).1 E -.15(ve)-.25 G 2.5(rs).15 G(et these.) +152.6 184.8 Q F0 2.5(4.7. File)87 208.8 R(Modes)2.5 E F1 .264 +(The modes used for \214les depend on what functionality you w)127 225 R .264 +(ant and the le)-.1 F -.15(ve)-.25 G 2.764(lo).15 G 2.764(fs)448.482 225 S .264 +(ecurity you)458.466 225 R(require.)102 237 Q F0 2.5(4.7.1. T)102 261 R 2.5(os) +-.92 G(uid or not to suid?)146.64 261 Q/F2 10/Times-Italic@0 SF(Sendmail)142 +277.2 Q F1 .934(can safely be made setuid to root.)3.434 F .934 +(At the point where it is about to)5.934 F F2 -.2(ex)3.433 G(ec).2 E F1 .933 +(\(2\) a)1.666 F(mailer)117 289.2 Q 2.582(,i)-.4 G 2.582(tc)150.012 289.2 S +.082(hecks to see if the userid is zero; if so, it resets the userid and group\ +id to a def)159.814 289.2 R .083(ault \(set)-.1 F .577(by the)117 301.2 R F0(u) +3.077 E F1(and)3.077 E F0(g)3.077 E F1 3.077(options\). \(This)3.077 F .576 +(can be o)3.076 F -.15(ve)-.15 G .576(rridden by setting the).15 F F0(S)3.076 E +F1 .576(\215ag to the mailer for mailers)3.076 F 1.531 +(that are trusted and must be called as root.\))117 313.2 R(Ho)6.531 E(we)-.25 +E -.15(ve)-.25 G 2.331 -.4(r, t).15 H 1.532 +(his will cause mail processing to be).4 F(accounted \(using)117 325.2 Q F2(sa) +2.5 E F1(\(8\)\) to root rather than to the user sending the mail.)1.666 E .339 +(If you don')142 341.4 R 2.839(tm)-.18 G(ak)200.887 341.4 Q(e)-.1 E F2 +(sendmail)2.839 E F1 .339(setuid to root, it will still run b)2.839 F .339 +(ut you lose a lot of functional-)-.2 F .007(ity and a lot of pri)117 353.4 R +-.25(va)-.25 G -.15(cy).25 G 2.507(,s)-.5 G .008(ince you')215.452 353.4 R .008 +(ll ha)-.1 F .308 -.15(ve t)-.2 H 2.508(om).15 G(ak)300.024 353.4 Q 2.508(et) +-.1 G .008(he queue directory w)319.092 353.4 R .008(orld readable.)-.1 F -1.1 +(Yo)5.008 G 2.508(uc)1.1 G(ould)486.22 353.4 Q .501(also mak)117 365.4 R(e)-.1 +E F2(sendmail)3.001 E F1 .501(setuid to some pseudo-user \(e.g., create a user\ + called \231sendmail\232 and mak)3.001 F(e)-.1 E F2(sendmail)117 377.4 Q F1 +1.533(setuid to that\) which will \214x the pri)4.033 F -.25(va)-.25 G 1.834 +-.15(cy p).25 H 1.534(roblems b).15 F 1.534(ut not the functionality issues.) +-.2 F .642(Also, this isn')117 389.4 R 3.142(tag)-.18 G .641 +(uarantee of security: for e)192.448 389.4 R .641 +(xample, root occasionally sends mail, and the dae-)-.15 F +(mon often runs as root.)117 401.4 Q F0 2.5(4.7.2. Should)102 425.4 R +(my alias database be writable?)2.5 E F1 .058(At Berk)142 441.6 R(ele)-.1 E +2.558(yw)-.15 G 2.558(eh)200.186 441.6 S -2.25 -.2(av e)212.184 441.6 T .058 +(the alias database \(/etc/aliases*\) mode 644.)2.758 F .058 +(While this is not as \215e)5.058 F(x-)-.15 E 1.719 +(ible as if the database were more 666, it a)117 453.6 R -.2(vo)-.2 G 1.718 +(ids potential security problems with a globally).2 F(writable database.)117 +465.6 Q 1.19(The database that)142 481.8 R F2(sendmail)3.69 E F1 1.191 +(actually used is represented by the tw)3.691 F 3.691<6f8c>-.1 G(les)429.118 +481.8 Q F2(aliases.dir)3.691 E F1(and)3.691 E F2(aliases.pa)117 493.8 Q(g)-.1 E +F1 .159(\(both in /etc\) \(or)2.659 F F2(aliases.db)2.659 E F1 .159 +(if you are running with the ne)2.659 F 2.658(wB)-.25 G(erk)412.854 493.8 Q +(ele)-.1 E 2.658(yd)-.15 G .158(atabase prim-)449.692 493.8 R(iti)117 505.8 Q +-.15(ve)-.25 G 3.606(s\). The).15 F 1.107 +(mode on these \214les should match the mode on /etc/aliases.)3.606 F(If)6.107 +E F2(aliases)3.607 E F1 1.107(is writable)3.607 F 1.624(and the DBM \214les \() +117 517.8 R F2(aliases.dir)A F1(and)4.124 E F2(aliases.pa)4.124 E(g)-.1 E F1 +4.124(\)a)C 1.624(re not, users will be unable to re\215ect their)324.648 517.8 +R .719(desired changes through to the actual database.)117 529.8 R(Ho)5.719 E +(we)-.25 E -.15(ve)-.25 G 1.519 -.4(r, i).15 H(f).4 E F2(aliases)3.219 E F1 .72 +(is read-only and the DBM)3.219 F(\214les are writable, a slightly sophisticat\ +ed user can arrange to steal mail an)117 541.8 Q(yw)-.15 E(ay)-.1 E(.)-.65 E +.621(If your DBM \214les are not writable by the w)142 558 R .62 +(orld or you do not ha)-.1 F .92 -.15(ve a)-.2 H(uto-reb).15 E .62 +(uild enabled)-.2 F 3.028(\(with the)117 570 R F0 -.5(Au)5.528 G(toReb).5 E +(uildAliases)-.2 E F1 3.028 +(option\), then you must be careful to reconstruct the alias)5.528 F +(database each time you change the te)117 582 Q(xt v)-.15 E(ersion:)-.15 E(ne) +157 598.2 Q -.1(wa)-.25 G(liases).1 E(If this step is ignored or for)117 614.4 +Q(gotten an)-.18 E 2.5(yi)-.15 G(ntended changes will also be ignored or for) +273.32 614.4 Q(gotten.)-.18 E F0 2.5(4.8. Connection)87 638.4 R(Caching)2.5 E +F1 .642(When processing the queue,)127 654.6 R F2(sendmail)3.142 E F1 .642 +(will try to k)3.142 F .642(eep the last fe)-.1 F 3.142(wo)-.25 G .642 +(pen connections open to)405.144 654.6 R -.2(avo)102 666.6 S +(id startup and shutdo).2 E(wn costs.)-.25 E +(This only applies to IPC connections.)5 E .286 +(When trying to open a connection the cache is \214rst searched.)127 682.8 R +.287(If an open connection is found,)5.286 F .92 +(it is probed to see if it is still acti)102 694.8 R 1.22 -.15(ve b)-.25 H 3.42 +(ys).15 G .92(ending a)270.892 694.8 R/F3 9/Times-Roman@0 SF(NOOP)3.42 E F1 +3.42(command. It)3.42 F .92(is not an error if this f)3.42 F(ails;)-.1 E +(instead, the connection is closed and reopened.)102 706.8 Q EP +%%Page: 26 21 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-26 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF -1 -.8(Tw o)127 +96 T .408(parameters control the connection cache.)3.708 F(The)5.408 E F0 +(ConnectionCacheSize)2.908 E F1(\()2.908 E F0(k)A F1 2.908(\)o)C .408 +(ption de\214nes)452.202 96 R .145 +(the number of simultaneous open connections that will be permitted.)102 108 R +.145(If it is set to zero, connections)5.145 F .212 +(will be closed as quickly as possible.)102 120 R .212(The def)5.212 F .212 +(ault is one.)-.1 F .213(This should be set as appropriate for your)5.212 F .63 +(system size; it will limit the amount of system resources that)102 132 R/F2 10 +/Times-Italic@0 SF(sendmail)3.129 E F1 .629(will use during queue runs.)3.129 F +(Ne)102 144 Q -.15(ve)-.25 G 2.5(rs).15 G(et this higher than 4.)132.42 144 Q +(The)127 160.2 Q F0(ConnectionCacheT)2.74 E(imeout)-.18 E F1(\()2.741 E F0(K)A +F1 2.741(\)o)C .241(ption speci\214es the maximum time that an)281.692 160.2 R +2.741(yc)-.15 G .241(ached con-)460.169 160.2 R .9 +(nection will be permitted to idle.)102 172.2 R .899(When the idle time e)5.9 F +.899(xceeds this v)-.15 F .899(alue the connection is closed.)-.25 F .34 +(This number should be small \(under ten minutes\) to pre)102 184.2 R -.15(ve) +-.25 G .34(nt you from grabbing too man).15 F 2.84(yr)-.15 G(esources)469.57 +184.2 Q(from other hosts.)102 196.2 Q(The def)5 E(ault is \214v)-.1 E 2.5(em) +-.15 G(inutes.)257.57 196.2 Q F0 2.5(4.9. Name)87 220.2 R(Ser)2.5 E -.1(ve)-.1 +G 2.5(rA).1 G(ccess)172.33 220.2 Q F1 .104 +(Control of host address lookups is set by the)127 236.4 R F0(hosts)2.604 E F1 +.103(service entry in your service switch \214le.)2.603 F(If)5.103 E .99 +(you are on a system that has b)102 248.4 R .99 +(uilt-in service switch support \(e.g., Ultrix, Solaris, or DEC OSF/1\))-.2 F +.336(then your system is probably con\214gured properly already)102 260.4 R +5.335(.O)-.65 G(therwise,)347.885 260.4 Q F2(sendmail)2.835 E F1 .335 +(will consult the \214le)2.835 F F0(/etc/ser)102 272.4 Q(vice.switch)-.1 E F1 +2.5(,w)C(hich should be created.)191.04 272.4 Q F2(Sendmail)5 E F1 +(only uses tw)2.5 E 2.5(oe)-.1 G(ntries:)389.8 272.4 Q F0(hosts)2.5 E F1(and) +2.5 E F0(aliases)2.5 E F1(.)A(Ho)127 288.6 Q(we)-.25 E -.15(ve)-.25 G .908 -.4 +(r, s).15 H .108(ome systems \(such as SunOS\) will do DNS lookups re).4 F -.05 +(ga)-.15 G .108(rdless of the setting of the).05 F 1.558(service switch entry) +102 300.6 R 6.558(.I)-.65 G 4.058(np)196.834 300.6 S(articular)210.892 300.6 Q +4.058(,t)-.4 G 1.558(he system routine)253.15 300.6 R F2 -.1(ge)4.058 G +(thostbyname).1 E F1 1.558(\(3\) is used to look up host)B .461(names, and man) +102 312.6 R 2.961(yv)-.15 G .461(endor v)180.293 312.6 R .461 +(ersions try some combination of DNS, NIS, and \214le lookup in /etc/hosts)-.15 +F .537(without consulting a service switch.)102 324.6 R F2(Sendmail)5.537 E F1 +(mak)3.037 E .536(es no attempt to w)-.1 F .536(ork around this problem, and) +-.1 F .27(the DNS lookup will be done an)102 336.6 R(yw)-.15 E(ay)-.1 E 5.27 +(.I)-.65 G 2.77(fy)264.36 336.6 S .271(ou do not ha)275.46 336.6 R .571 -.15 +(ve a n)-.2 H(ameserv).15 E .271(er con\214gured at all, such as at)-.15 F +2.855(aU)102 348.6 S .355(UCP-only site,)116.515 348.6 R F2(sendmail)2.855 E F1 +.354 +(will get a \231connection refused\232 message when it tries to connect to the) +2.855 F .622(name serv)102 360.6 R(er)-.15 E 5.622(.I)-.55 G 3.122(ft)161.964 +360.6 S(he)171.196 360.6 Q F0(hosts)3.122 E F1 .623 +(switch entry has the service \231dns\232 listed some)3.122 F .623 +(where in the list,)-.25 F F2(sendmail)3.123 E F1 .912 +(will interpret this to mean a temporary f)102 372.6 R .912 +(ailure and will queue the mail for later processing; other)-.1 F(-)-.2 E +(wise, it ignores the name serv)102 384.6 Q(er data.)-.15 E .672 +(The same technique is used to decide whether to do MX lookups.)127 400.8 R +.673(If you w)5.673 F .673(ant MX support,)-.1 F(you)102 412.8 Q F2(must)2.5 E +F1(ha)2.5 E .3 -.15(ve \231)-.2 H(dns\232 listed as a service in the).15 E F0 +(hosts)2.5 E F1(switch entry)2.5 E(.)-.65 E(The)127 429 Q F0(Resolv)3.87 E +(erOptions)-.1 E F1(\()3.87 E F0(I)A F1 3.869(\)o)C 1.369(ption allo)240.719 +429 R 1.369(ws you to tweak name serv)-.25 F 1.369(er options.)-.15 F 1.369 +(The command)6.369 F .892(line tak)102 441 R .892 +(es a series of \215ags as documented in)-.1 F F2 -.37(re)3.392 G(solver).37 E +F1 .892(\(3\) \(with the leading \231RES_\232 deleted\).)B(Each)5.892 E +(can be preceded by an optional `+' or `)102 453 Q/F3 10/Symbol SF(-)A F1 2.5 +('. F)B(or e)-.15 E(xample, the line)-.15 E 2.5(OR)142 469.2 S(esolv)158.39 +469.2 Q(erOptions=+AA)-.15 E(ONL)-.55 E(Y)-1 E F3(-)2.5 E F1(DNSRCH)A .862 +(turns on the AA)102 485.4 R(ONL)-.55 E 3.362(Y\()-1 G .862(accept authoritati) +201.658 485.4 R 1.162 -.15(ve a)-.25 H .861(nswers only\) and turns of).15 F +3.361(ft)-.25 G .861(he DNSRCH \(search the)402.827 485.4 R 2.039 +(domain path\) options.)102 497.4 R 2.039(Most resolv)7.039 F 2.039 +(er libraries def)-.15 F 2.039(ault DNSRCH, DEFN)-.1 F 2.039(AMES, and RECURSE) +-.35 F .503(\215ags on and all others of)102 509.4 R 3.003(f. Y)-.25 F .503 +(ou can also include \231HasW)-1.1 F .503 +(ildcardMX\232 to specify that there is a wild-)-.4 F 1.972 +(card MX record matching your domain; this turns of)102 521.4 R 4.472(fM)-.25 G +4.473(Xm)344.188 521.4 S 1.973(atching when canonifying names,)363.661 521.4 R +(which can lead to inappropriate canoni\214cations.)102 533.4 Q -1.11(Ve)127 +549.6 S 2.257(rsion le)1.11 F -.15(ve)-.25 G 4.757(l1c).15 G 2.256 +(on\214gurations turn DNSRCH and DEFN)200.301 549.6 R 2.256(AMES of)-.35 F +4.756(fw)-.25 G 2.256(hen doing deli)424.898 549.6 R -.15(ve)-.25 G(ry).15 E +2.06(lookups, b)102 561.6 R 2.06(ut lea)-.2 F 2.36 -.15(ve t)-.2 H 2.06 +(hem on e).15 F -.15(ve)-.25 G 2.06(rywhere else.).15 F -1.11(Ve)7.06 G 2.06 +(rsion 8 of)1.11 F F2(sendmail)4.56 E F1 2.06(ignores them when doing)4.56 F +.313(canoni\214cation lookups \(that is, when using $[ ... $]\), and al)102 +573.6 R -.1(wa)-.1 G .313(ys does the search.).1 F .313(If you don')5.313 F +2.812(tw)-.18 G(ant)491.78 573.6 Q(to do automatic name e)102 585.6 Q +(xtension, don')-.15 E 2.5(tc)-.18 G(all $[ ... $].)261.93 585.6 Q .485 +(The search rules for $[ ... $] are some)127 601.8 R .485(what dif)-.25 F .485 +(ferent than usual.)-.25 F .486(If the name being look)5.485 F .486(ed up)-.1 F +.11(has at least one dot, it al)102 613.8 R -.1(wa)-.1 G .11 +(ys tries the unmodi\214ed name \214rst.).1 F .109(If that f)5.109 F .109 +(ails, it tries the reduced search)-.1 F .124 +(path, and lastly tries the unmodi\214ed name \(b)102 625.8 R .124 +(ut only for names without a dot, since names with a dot)-.2 F(ha)102 637.8 Q +.789 -.15(ve a)-.2 H .489(lready been tried\).).15 F .489(This allo)5.489 F +.489(ws names such as `)-.25 F(`utc.CS')-.74 E 2.989('t)-.74 G 2.988(om)362.81 +637.8 S .488(atch the site in Czechoslo)378.578 637.8 R -.25(va)-.15 G(kia).25 +E 1.587(rather than the site in your local Computer Science department.)102 +649.8 R 1.588(It also prefers A and CN)6.587 F(AME)-.35 E .513(records o)102 +661.8 R -.15(ve)-.15 G 3.013(rM).15 G 3.013(Xr)163.816 661.8 S .513 +(ecords \212 that is, if it \214nds an MX record it mak)177.379 661.8 R .512 +(es note of it, b)-.1 F .512(ut k)-.2 F .512(eeps looking.)-.1 F 1.541(This w) +102 673.8 R(ay)-.1 E 4.041(,i)-.65 G 4.041(fy)149.052 673.8 S 1.541(ou ha) +161.423 673.8 R 1.841 -.15(ve a w)-.2 H 1.541 +(ildcard MX record matching your domain, it will not assume that all).15 F +(names match.)102 685.8 Q 3.454 -.8(To c)127 702 T 1.853(ompletely turn of).8 F +4.353(fa)-.25 G 1.853(ll name serv)231.123 702 R 1.853 +(er access on systems without service switch support)-.15 F .578 +(\(such as SunOS\) you will ha)102 714 R .878 -.15(ve t)-.2 H 3.078(or).15 G +.579(ecompile with \255DN)245.406 714 R .579(AMED_BIND=0 and remo)-.35 F .879 +-.15(ve \255)-.15 H .579(lresolv from).15 F EP +%%Page: 27 22 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-27)452.9 60 Q/F1 10/Times-Roman@0 SF +(the list of libraries to be searched when linking.)102 96 Q F0 2.5(4.10. Mo)87 +120 R(ving the P)-.1 E(er)-.2 E(-User F)-.37 E(orward Files)-.25 E F1 .772 +(Some sites mount each user')127 136.2 R 3.272(sh)-.55 G .772 +(ome directory from a local disk on their w)256.13 136.2 R .772 +(orkstation, so that)-.1 F .575(local access is f)102 148.2 R 3.075(ast. Ho)-.1 +F(we)-.25 E -.15(ve)-.25 G 1.375 -.4(r, t).15 H .575(he result is that .forw).4 +F .575(ard \214le lookups are slo)-.1 F 4.376 -.65(w. I)-.25 H 3.076(ns).65 G +.576(ome cases, mail)439.248 148.2 R .216(can e)102 160.2 R -.15(ve)-.25 G +2.716(nb).15 G 2.716(ed)144.792 160.2 S(eli)156.948 160.2 Q -.15(ve)-.25 G .216 +(red on machines inappropriately because of a \214le serv).15 F .216 +(er being do)-.15 F 2.716(wn. The)-.25 F(perfor)2.716 E(-)-.2 E +(mance can be especially bad if you run the automounter)102 172.2 Q(.)-.55 E +(The)127 188.4 Q F0 -.25(Fo)2.743 G(rwardP).25 E(ath)-.1 E F1(\()2.743 E F0(J)A +F1 2.743(\)o)C .243(ption allo)224.859 188.4 R .243 +(ws you to set a path of forw)-.25 F .243(ard \214les.)-.1 F -.15(Fo)5.243 G +2.743(re).15 G .244(xample, the con-)436.582 188.4 R(\214g \214le line)102 +200.4 Q 2.5(OF)142 216.6 S(orw)157.13 216.6 Q(ardP)-.1 E(ath=/v)-.15 E(ar/forw) +-.25 E(ard/$u:$z/.forw)-.1 E(ard.$w)-.1 E -.1(wo)102 232.8 S .208 +(uld \214rst look for a \214le with the same name as the user').1 F 2.707(sl) +-.55 G .207(ogin in /v)343.191 232.8 R(ar/forw)-.25 E .207 +(ard; if that is not found)-.1 F 1.17(\(or is inaccessible\) the \214le `)102 +244.8 R(`.forw)-.74 E(ard.)-.1 E/F2 10/Times-Italic@0 SF(mac)A(hinename)-.15 E +F1 2.651 -.74('' i)D 3.671(nt).74 G 1.171(he user')337.014 244.8 R 3.671(sh) +-.55 G 1.171(ome directory is searched.)382.126 244.8 R(A)6.171 E(truly perv) +102 256.8 Q(erse site could also search by sender by using $r)-.15 E 2.5(,$)-.4 +G(s, or $f.)343.07 256.8 Q .69(If you create a directory such as /v)127 273 R +(ar/forw)-.25 E .69(ard, it should be mode 1777 \(that is, the stick)-.1 F 3.19 +(yb)-.15 G(it)498.44 273 Q(should be set\).)102 285 Q +(Users should create the \214les mode 644.)5 E F0 2.5(4.11. Fr)87 309 R +(ee Space)-.18 E F1 1.405(On systems that ha)127 325.2 R 1.705 -.15(ve o)-.2 H +1.405(ne of the system calls in the).15 F F2(statfs)3.906 E F1 1.406(\(2\) f)B +1.406(amily \(including)-.1 F F2(statvfs)3.906 E F1(and)3.906 E F2(ustat)102 +337.2 Q F1 .839(\), you can specify a minimum number of free blocks on the que\ +ue \214lesystem using the)B F0(Min-)3.339 E(Fr)102 349.2 Q(eeBlocks)-.18 E F1 +(\()2.553 E F0(b)A F1 2.553(\)o)C 2.553(ption. If)171.916 349.2 R .053 +(there are fe)2.553 F .053 +(wer than the indicated number of blocks free on the \214lesystem)-.25 F 1.355 +(on which the queue is mounted the SMTP serv)102 361.2 R 1.355 +(er will reject mail with the 452 error code.)-.15 F(This)6.354 E(in)102 373.2 +Q(vites the SMTP client to try ag)-.4 E(ain later)-.05 E(.)-.55 E(Be)127 389.4 +Q -.1(wa)-.25 G .746(re of setting this option too high; it can cause rejectio\ +n of email when that mail w).1 F(ould)-.1 E(be processed without dif)102 401.4 +Q(\214culty)-.25 E(.)-.65 E F0 2.5(4.12. Maximum)87 425.4 R(Message Size)2.5 E +F1 2.078 -.8(To a)127 441.6 T -.2(vo).6 G .478(id o).2 F -.15(ve)-.15 G(r\215o) +.15 E .478(wing your system with a lar)-.25 F .478(ge message, the)-.18 F F0 +(MaxMessageSize)2.977 E F1 .477(option can be)2.977 F .692 +(set to set an absolute limit on the size of an)102 453.6 R 3.193(yo)-.15 G +.693(ne message.)294.176 453.6 R .693(This will be adv)5.693 F .693 +(ertised in the ESMTP)-.15 F(dialogue and check)102 465.6 Q +(ed during message collection.)-.1 E F0 2.5(4.13. Pri)87 489.6 R -.1(va)-.1 G +(cy Flags).1 E F1(The)127 505.8 Q F0(Pri)2.96 E -.1(va)-.1 G(cyOptions).1 E F1 +(\()2.96 E F0(p)A F1 2.96(\)o)C .46(ption allo)235.12 505.8 R .46 +(ws you to set certain `)-.25 F(`pri)-.74 E -.25(va)-.25 G -.15(cy).25 G 1.94 +-.74('' \215).15 H 2.96(ags. Actually).74 F 2.96(,m)-.65 G(an)478.42 505.8 Q +2.96(yo)-.15 G(f)500.67 505.8 Q .533(them don')102 517.8 R 3.033(tg)-.18 G +-2.15 -.25(iv e)153.996 517.8 T .533(you an)3.283 F 3.034(ye)-.15 G .534 +(xtra pri)208.496 517.8 R -.25(va)-.25 G -.15(cy).25 G 3.034(,r)-.5 G .534 +(ather just insisting that client SMTP serv)264.634 517.8 R .534 +(ers use the HELO)-.15 F 2.87 +(command before using certain commands or adding e)102 529.8 R 2.87 +(xtra headers to indicate possible spoof)-.15 F(attempts.)102 541.8 Q .123 +(The option tak)127 558 R .124(es a series of \215ag names; the \214nal pri)-.1 +F -.25(va)-.25 G .424 -.15(cy i).25 H 2.624(st).15 G .124(he inclusi)367.706 +558 R .424 -.15(ve o)-.25 H 2.624(ro).15 G 2.624(ft)434.058 558 S .124 +(hose \215ags.)442.792 558 R -.15(Fo)5.124 G(r).15 E -.15(ex)102 570 S(ample:) +.15 E 2.5(OP)142 586.2 S(ri)157.28 586.2 Q -.25(va)-.25 G -.15(cy).25 G +(Options=needmailhelo, noe).15 E(xpn)-.15 E .928(insists that the HELO or EHLO\ + command be used before a MAIL command is accepted and dis-)102 602.4 R +(ables the EXPN command.)102 614.4 Q +(The \215ags are detailed in section 5.1.6.)127 630.6 Q F0 2.5(4.14. Send)87 +654.6 R(to Me T)2.5 E(oo)-.92 E F1(Normally)127 670.8 Q(,)-.65 E F2(sendmail) +3.423 E F1 .923(deletes the \(en)3.423 F -.15(ve)-.4 G .923 +(lope\) sender from an).15 F 3.423(yl)-.15 G .924(ist e)375.484 670.8 R 3.424 +(xpansions. F)-.15 F .924(or e)-.15 F .924(xample, if)-.15 F .761(\231matt\232\ + sends to a list that contains \231matt\232 as one of the members he w)102 +682.8 R(on')-.1 E 3.261(tg)-.18 G .761(et a cop)416.705 682.8 R 3.261(yo)-.1 G +3.261(ft)462.488 682.8 S .761(he mes-)471.859 682.8 R 2.882(sage. If)102 694.8 +R(the)2.882 E F0<ad6d>2.882 E F1 .383 +(\(me too\) command line \215ag, or if the)2.882 F F0(MeT)2.883 E(oo)-.92 E F1 +(\()2.883 E F0(m)A F1 2.883(\)o)C .383(ption is set in the con\214guration) +377.915 694.8 R(\214le, this beha)102 706.8 Q(viour is suppressed.)-.2 E +(Some sites lik)5 E 2.5(et)-.1 G 2.5(or)305.31 706.8 S(un the)316.14 706.8 Q/F3 +9/Times-Roman@0 SF(SMTP)2.5 E F1(daemon with)2.5 E F0<ad6d>2.5 E F1(.)A EP +%%Page: 28 23 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-28 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E 2.5(5. THE)72 96 R +(WHOLE SCOOP ON THE CONFIGURA)2.5 E(TION FILE)-.95 E/F1 10/Times-Roman@0 SF +(This section describes the con\214guration \214le in detail.)112 112.2 Q .648 +(There is one point that should be made clear immediately: the syntax of the c\ +on\214guration \214le is)112 128.4 R 1.076 +(designed to be reasonably easy to parse, since this is done e)87 140.4 R -.15 +(ve)-.25 G 1.077(ry time).15 F/F2 10/Times-Italic@0 SF(sendmail)3.577 E F1 +1.077(starts up, rather than)3.577 F(easy for a human to read or write.)87 +152.4 Q +(On the \231future project\232 list is a con\214guration-\214le compiler)5 E(.) +-.55 E .243(The con\214guration \214le is or)112 168.6 R -.05(ga)-.18 G .243 +(nized as a series of lines, each of which be).05 F .243 +(gins with a single charac-)-.15 F .102 +(ter de\214ning the semantics for the rest of the line.)87 180.6 R .102 +(Lines be)5.102 F .102(ginning with a space or a tab are continuation)-.15 F +1.323(lines \(although the semantics are not well de\214ned in man)87 192.6 R +3.823(yp)-.15 G 3.822(laces\). Blank)340.61 192.6 R 1.322(lines and lines be) +3.822 F(ginning)-.15 E(with a sharp symbol \(`#'\) are comments.)87 204.6 Q F0 +2.5(5.1. R)87 228.6 R(and S \212 Rewriting Rules)2.5 E F1 .465 +(The core of address parsing are the re)127 244.8 R .466(writing rules.)-.25 F +.466(These are an ordered production system.)5.466 F F2(Sendmail)102 256.8 Q F1 +.19(scans through the set of re)2.69 F .19 +(writing rules looking for a match on the left hand side \(LHS\) of)-.25 F +(the rule.)102 268.8 Q(When a rule matches, the address is replaced by the rig\ +ht hand side \(RHS\) of the rule.)5 E .921(There are se)127 285 R -.15(ve)-.25 +G .921(ral sets of re).15 F .921(writing rules.)-.25 F .921(Some of the re) +5.921 F .922(writing sets are used internally and)-.25 F .36(must ha)102 297 R +.66 -.15(ve s)-.2 H .36(peci\214c semantics.).15 F .359(Other re)5.359 F .359 +(writing sets do not ha)-.25 F .659 -.15(ve s)-.2 H .359 +(peci\214cally assigned semantics, and).15 F +(may be referenced by the mailer de\214nitions or by other re)102 309 Q +(writing sets.)-.25 E(The syntax of these tw)127 325.2 Q 2.5(oc)-.1 G +(ommands are:)229.38 325.2 Q F0(S)142 341.4 Q F2(n)A F1 .248 +(Sets the current ruleset being collected to)102 357.6 R F2(n)2.748 E F1 5.248 +(.I)C 2.748(fy)287.284 357.6 S .248(ou be)298.362 357.6 R .249 +(gin a ruleset more than once it deletes the old)-.15 F(de\214nition.)102 369.6 +Q F0(R)142 385.8 Q F2(lhs rhs comments)A F1 1.185(The \214elds must be separat\ +ed by at least one tab character; there may be embedded spaces in the)102 402 R +2.594(\214elds. The)102 414 R F2(lhs)2.594 E F1 .095 +(is a pattern that is applied to the input.)2.594 F .095 +(If it matches, the input is re)5.095 F .095(written to the)-.25 F F2(rhs)2.595 +E F1(.)A(The)102 426 Q F2(comments)2.5 E F1(are ignored.)2.5 E .755(Macro e)127 +442.2 R .755(xpansions of the form)-.15 F F0($)3.255 E F2(x)A F1 .755 +(are performed when the con\214guration \214le is read.)3.255 F(Expan-)5.755 E +.283(sions of the form)102 454.2 R F0($&)2.783 E F2(x)A F1 .284 +(are performed at run time using a some)2.783 F .284 +(what less general algorithm.)-.25 F .284(This for)5.284 F +(is intended only for referencing internally de\214ned macros such as)102 466.2 +Q F0($h)2.5 E F1(that are changed at runtime.)2.5 E F0 2.5(5.1.1. The)102 490.2 +R(left hand side)2.5 E F1 2.771(The left hand side of re)142 506.4 R 2.771 +(writing rules contains a pattern.)-.25 F 2.77(Normal w)7.771 F 2.77 +(ords are simply)-.1 F(matched directly)117 518.4 Q 5(.M)-.65 G +(etasyntax is introduced using a dollar sign.)199.67 518.4 Q +(The metasymbols are:)5 E F0($*)157 534.6 Q F1(Match zero or more tok)177.14 +534.6 Q(ens)-.1 E F0($+)157 546.6 Q F1(Match one or more tok)9.44 E(ens)-.1 E +F0<24ad>157 558.6 Q F1(Match e)9.44 E(xactly one tok)-.15 E(en)-.1 E F0($=)157 +570.6 Q F2(x)A F1(Match an)5 E 2.5(yp)-.15 G(hrase in class)226.98 570.6 Q F2 +(x)2.5 E F0($~)157 582.6 Q F2(x)A F1(Match an)7.37 E 2.5(yw)-.15 G +(ord not in class)229.1 582.6 Q F2(x)2.5 E F1 .131(If an)117 598.8 R 2.631(yo) +-.15 G 2.631(ft)148.212 598.8 S .131(hese match, the)156.953 598.8 R 2.631(ya) +-.15 G .132(re assigned to the symbol)231.066 598.8 R F0($)2.632 E F2(n)A F1 +.132(for replacement on the right hand side,)2.632 F(where)117 610.8 Q F2(n)2.5 +E F1(is the inde)2.5 E 2.5(xi)-.15 G 2.5(nt)202.67 610.8 S(he LHS.)212.95 610.8 +Q -.15(Fo)5 G 2.5(re).15 G(xample, if the LHS:)271.81 610.8 Q($\255:$+)157 627 +Q(is applied to the input:)117 643.2 Q(UCB)157 659.4 Q(ARP)-.35 E(A:eric)-.92 E +(the rule will match, and the v)117 675.6 Q(alues passed to the RHS will be:) +-.25 E 7.5($1 UCB)157 691.8 R(ARP)-.35 E(A)-.92 E 7.5($2 eric)157 703.8 R EP +%%Page: 29 24 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-29)452.9 60 Q/F1 10/Times-Roman@0 SF(Additionally)142 96 Q 2.705(,t) +-.65 G .204(he LHS can include)199.895 96 R F0($@)2.704 E F1 .204 +(to match zero tok)2.704 F 2.704(ens. This)-.1 F(is)2.704 E/F2 10 +/Times-Italic@0 SF(not)2.704 E F1 .204(bound to a)2.704 F F0($)2.704 E F2(n)A +F1(on)2.704 E(the RHS, and is normally only used when it stands alone in order\ + to match the null input.)117 108 Q F0 2.5(5.1.2. The)102 132 R +(right hand side)2.5 E F1 .648(When the left hand side of a re)142 148.2 R .649 +(writing rule matches, the input is deleted and replaced by)-.25 F 1.037 +(the right hand side.)117 160.2 R -.8(To)6.037 G -.1(ke).8 G 1.036 +(ns are copied directly from the RHS unless the).1 F 3.536(yb)-.15 G -.15(eg) +430.772 160.2 S 1.036(in with a dollar).15 F 2.5(sign. Metasymbols)117 172.2 R +(are:)2.5 E F0($)157 188.4 Q F2(n)A F1(Substitute inde\214nite tok)207.55 188.4 +Q(en)-.1 E F2(n)2.5 E F1(from LHS)2.5 E F0($[)157 200.4 Q F2(name)A F0($])A F1 +(Canonicalize)207.55 200.4 Q F2(name)2.5 E F0($\()157 212.4 Q F2(map k)A -.3 +(ey)-.1 G F0($@)2.8 E F2(ar)A(guments)-.37 E F0($:)2.5 E F2(default)A F0($\)) +2.5 E F1(Generalized k)207.55 224.4 Q -.15(ey)-.1 G(ed mapping function).15 E +F0($>)157 236.4 Q F2(n)A F1(\231Call\232 ruleset)207.55 236.4 Q F2(n)2.5 E F0 +($#)157 248.4 Q F2(mailer)A F1(Resolv)207.55 248.4 Q 2.5(et)-.15 G(o)244.9 +248.4 Q F2(mailer)2.5 E F0($@)157 260.4 Q F2(host)A F1(Specify)207.55 260.4 Q +F2(host)2.5 E F0($:)157 272.4 Q F2(user)A F1(Specify)207.55 272.4 Q F2(user)2.5 +E F1(The)142 292.8 Q F0($)3.136 E F2(n)A F1 .637 +(syntax substitutes the corresponding v)3.136 F .637(alue from a)-.25 F F0($+) +3.137 E F1(,)A F0<24ad>3.137 E F1(,)A F0($*)3.137 E F1(,)A F0($=)3.137 E F1 +3.137(,o)C(r)448.489 292.8 Q F0($~)3.137 E F1 .637(match on)3.137 F(the LHS.) +117 304.8 Q(It may be used an)5 E(ywhere.)-.15 E 2.706(Ah)142 321 S .206 +(ost name enclosed between)156.926 321 R F0($[)2.706 E F1(and)2.706 E F0($]) +2.706 E F1 .206(is look)2.706 F .205 +(ed up in the host database\(s\) and replaced)-.1 F 1.683 +(by the canonical name)117 335 R/F3 7/Times-Roman@0 SF(13)211.749 331 Q F1 +6.683(.F)218.749 335 S 1.683(or e)233.342 335 R 1.683 +(xample, \231$[ftp$]\232 might become \231ftp.CS.Berk)-.15 F(ele)-.1 E -.65(y.) +-.15 G 1.683(EDU\232 and).65 F 2.707(\231$[[128.32.130.2]$]\232 w)117 347 R +2.707(ould become \231v)-.1 F(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G +(EDU.).65 E<9a>-.7 E F2(Sendmail)7.707 E F1 2.706(recognizes it')5.206 F(s)-.55 +E(numeric IP address without calling the name serv)117 359 Q +(er and replaces it with it')-.15 E 2.5(sc)-.55 G(anonical name.)424.3 359 Q +(The)142 375.2 Q F0($\()3.003 E F1(...)3.003 E F0($\))5.503 E F1 .503 +(syntax is a more general form of lookup; it uses a named map instead of an) +3.003 F .81(implicit map.)117 387.2 R .81(If no lookup is found, the indicated) +5.81 F F2(default)3.309 E F1 .809(is inserted; if no def)3.309 F .809 +(ault is speci\214ed)-.1 F .775(and no lookup matches, the v)117 399.2 R .776 +(alue is left unchanged.)-.25 F(The)5.776 E F2(ar)3.276 E(guments)-.37 E F1 +.776(are passed to the map for)3.276 F(possible use.)117 411.2 Q(The)142 427.4 +Q F0($>)2.62 E F2(n)A F1 .119(syntax causes the remainder of the line to be su\ +bstituted as usual and then passed)2.62 F .586(as the ar)117 439.4 R .586 +(gument to ruleset)-.18 F F2(n)3.086 E F1 5.586(.T)C .586(he \214nal v)244.206 +439.4 R .586(alue of ruleset)-.25 F F2(n)3.087 E F1 .587 +(then becomes the substitution for this)3.087 F 3.075(rule. The)117 451.4 R F0 +($>)3.075 E F1 .575(syntax can only be used at the be)3.075 F .575 +(ginning of the right hand side; it can be only be)-.15 F(preceded by)117 463.4 +Q F0($@)2.5 E F1(or)2.5 E F0($:)2.5 E F1(.)A(The)142 479.6 Q F0($#)2.507 E F1 +.007(syntax should)2.507 F F2(only)2.507 E F1 .008 +(be used in ruleset zero or a subroutine of ruleset zero.)2.507 F .008 +(It causes)5.008 F -.25(eva)117 491.6 S .685 +(luation of the ruleset to terminate immediately).25 F 3.184(,a)-.65 G .684 +(nd signals to)329.502 491.6 R F2(sendmail)3.184 E F1 .684 +(that the address has)3.184 F(completely resolv)117 503.6 Q 2.5(ed. The)-.15 F +(complete syntax is:)2.5 E F0($#)157 519.8 Q F2(mailer)A F0($@)2.5 E F2(host)A +F0($:)2.5 E F2(user)A F1 1.394(This speci\214es the {mailer)117 536 R 3.894(,h) +-.4 G 1.394(ost, user} 3-tuple necessary to direct the mailer)234.466 536 R +6.394(.I)-.55 G 3.894(ft)444.548 536 S 1.394(he mailer is)454.552 536 R .774 +(local the host part may be omitted)117 550 R F3(14)257.744 546 Q F1 5.774(.T) +264.744 550 S(he)279.128 550 Q F2(mailer)3.274 E F1 .775(must be a single w) +3.274 F .775(ord, b)-.1 F .775(ut the)-.2 F F2(host)3.275 E F1(and)3.275 E F2 +(user)3.275 E F1 .253(may be multi-part.)117 562 R .253(If the)5.253 F F2 +(mailer)2.753 E F1 .253(is the b)2.753 F .253(uiltin IPC mailer)-.2 F 2.753(,t) +-.4 G(he)354.733 562 Q F2(host)2.753 E F1 .253(may be a colon-separated list) +2.753 F .5(of hosts that are searched in order for the \214rst w)117 574 R .5 +(orking address \(e)-.1 F .5(xactly lik)-.15 F 3(eM)-.1 G 3(Xr)437.47 574 S 3 +(ecords\). The)451.02 574 R F2(user)117 586 Q F1 .036(is later re)2.536 F .036 +(written by the mailer)-.25 F .036(-speci\214c en)-.2 F -.15(ve)-.4 G .036 +(lope re).15 F .036(writing set and assigned to the)-.25 F F0($u)2.536 E F1 +(macro.)2.536 E .492(As a special case, if the v)117 598 R .492(alue to)-.25 F +F0($#)2.992 E F1 .492(is \231local\232 and the \214rst character of the)2.992 F +F0($:)2.992 E F1 -.25(va)2.992 G .492(lue is \231@\232, the).25 F .017 +(\231@\232 is stripped of)117 610 R .017(f, and a \215ag is set in the address\ + descriptor that causes sendmail to not do rule-)-.25 F(set 5 processing.)117 +622 Q(Normally)142 638.2 Q 3.251(,ar)-.65 G .751 +(ule that matches is retried, that is, the rule loops until it f)196.452 638.2 +R 3.252(ails. A)-.1 F .752(RHS may)3.252 F 1.086(also be preceded by a)117 +650.2 R F0($@)3.586 E F1 1.085(or a)3.585 F F0($:)3.585 E F1 1.085 +(to change this beha)3.585 F(vior)-.2 E 6.085(.A)-.55 G F0($@)375.685 650.2 Q +F1 1.085(pre\214x causes the ruleset to)3.585 F .32 LW 76 659.8 72 659.8 DL 80 +659.8 76 659.8 DL 84 659.8 80 659.8 DL 88 659.8 84 659.8 DL 92 659.8 88 659.8 +DL 96 659.8 92 659.8 DL 100 659.8 96 659.8 DL 104 659.8 100 659.8 DL 108 659.8 +104 659.8 DL 112 659.8 108 659.8 DL 116 659.8 112 659.8 DL 120 659.8 116 659.8 +DL 124 659.8 120 659.8 DL 128 659.8 124 659.8 DL 132 659.8 128 659.8 DL 136 +659.8 132 659.8 DL 140 659.8 136 659.8 DL 144 659.8 140 659.8 DL 148 659.8 144 +659.8 DL 152 659.8 148 659.8 DL 156 659.8 152 659.8 DL 160 659.8 156 659.8 DL +164 659.8 160 659.8 DL 168 659.8 164 659.8 DL 172 659.8 168 659.8 DL 176 659.8 +172 659.8 DL 180 659.8 176 659.8 DL 184 659.8 180 659.8 DL 188 659.8 184 659.8 +DL 192 659.8 188 659.8 DL 196 659.8 192 659.8 DL 200 659.8 196 659.8 DL 204 +659.8 200 659.8 DL 208 659.8 204 659.8 DL 212 659.8 208 659.8 DL 216 659.8 212 +659.8 DL/F4 5/Times-Roman@0 SF(13)93.6 670.2 Q/F5 8/Times-Roman@0 SF +(This is actually completely equi)3.2 I -.2(va)-.2 G(lent to $\(host).2 E/F6 8 +/Times-Italic@0 SF(hostname)2 E F5 2($\). In)B(particular)2 E 2(,a)-.32 G/F7 8 +/Times-Bold@0 SF($:)A F5(def)2 E(ault can be used.)-.08 E F4(14)93.6 683.8 Q F5 +-.88(Yo)3.2 K 2.726(um).88 G .726(ay w)120.446 687 R .726 +(ant to use it for special \231per user\232 e)-.08 F 2.726(xtensions. F)-.12 F +.726(or e)-.12 F .725 +(xample, in the address \231jgm+foo@CMU.EDU\232; the \231+foo\232)-.12 F(part \ +is not part of the user name, and is passed to the local mailer for local use.) +72 696.6 Q EP +%%Page: 30 25 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-30 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 1.46 +(return with the remainder of the RHS as the v)117 96 R 3.96(alue. A)-.25 F F0 +($:)3.96 E F1 1.46(pre\214x causes the rule to terminate)3.96 F(immediately)117 +108 Q 3.756(,b)-.65 G 1.256(ut the ruleset to continue; this can be used to a) +177.406 108 R -.2(vo)-.2 G 1.256(id continued application of a).2 F 2.5 +(rule. The)117 120 R(pre\214x is stripped before continuing.)2.5 E(The)142 +136.2 Q F0($@)2.5 E F1(and)2.5 E F0($:)2.5 E F1(pre\214x)2.5 E +(es may precede a)-.15 E F0($>)2.5 E F1(spec; for e)2.5 E(xample:)-.15 E 20.19 +(R$+ $:)157 152.4 R($>7 $1)2.5 E 1.256(matches an)117 168.6 R 1.256 +(ything, passes that to ruleset se)-.15 F -.15(ve)-.25 G 1.256 +(n, and continues; the).15 F F0($:)3.756 E F1 1.256(is necessary to a)3.756 F +-.2(vo)-.2 G 1.256(id an).2 F(in\214nite loop.)117 180.6 Q 1.205(Substitution \ +occurs in the order described, that is, parameters from the LHS are substi-)142 +196.8 R .219(tuted, hostnames are canonicalized, \231subroutines\232 are calle\ +d, and \214nally)117 208.8 R F0($#)2.719 E F1(,)A F0($@)2.719 E F1 2.72(,a)C +(nd)448.64 208.8 Q F0($:)2.72 E F1 .22(are pro-)2.72 F(cessed.)117 220.8 Q F0 +2.5(5.1.3. Semantics)102 244.8 R(of r)2.5 E(ewriting rule sets)-.18 E F1 1.523 +(There are \214v)142 261 R 4.023(er)-.15 G -.25(ew)207.779 261 S 1.523 +(riting sets that ha).25 F 1.823 -.15(ve s)-.2 H 1.523(peci\214c semantics.).15 +F -.15(Fo)6.523 G 1.523(ur of these are related as).15 F +(depicted by \214gure 1.)117 273 Q 1.029 +(Ruleset three should turn the address into \231canonical form.)142 289.2 R +6.029<9a54>-.7 G 1.03(his form should ha)401.351 289.2 R 1.33 -.15(ve t)-.2 H +(he).15 E(basic syntax:)117 301.2 Q(local-part@host-domain-spec)157 317.4 Q +(Ruleset three is applied by)117 333.6 Q/F2 10/Times-Italic@0 SF(sendmail)2.5 E +F1(before doing an)2.5 E(ything with an)-.15 E 2.5(ya)-.15 G(ddress.)396.39 +333.6 Q .302(If no \231@\232 sign is speci\214ed, then the host-domain-spec)142 +349.8 R F2(may)2.801 E F1 .301(be appended \(box \231D\232 in Fig-)2.801 F .577 +(ure 1\) from the sender address \(if the)117 361.8 R F0(C)3.077 E F1 .577 +(\215ag is set in the mailer de\214nition corresponding to the)3.077 F F2 +(sending)117 373.8 Q F1(mailer\).)2.5 E 1.021(Ruleset zero is applied after ru\ +leset three to addresses that are going to actually specify)142 390 R 3.663 +(recipients. It)117 402 R 1.163(must resolv)3.663 F 3.663(et)-.15 G 3.664(oa) +232.602 402 S F2({mailer)A 3.664(,h)-1.11 G 1.164(ost, user})289.534 402 R F1 +3.664(triple. The)3.664 F F2(mailer)3.664 E F1 1.164(must be de\214ned in the) +3.664 F .752(mailer de\214nitions from the con\214guration \214le.)117 414 R +(The)5.751 E F2(host)3.251 E F1 .751(is de\214ned into the)3.251 F F0($h)3.251 +E F1 .751(macro for use in)3.251 F(the ar)117 426 Q(gv e)-.18 E +(xpansion of the speci\214ed mailer)-.15 E(.)-.55 E .452(Rulesets one and tw) +142 442.2 R 2.952(oa)-.1 G .452 +(re applied to all sender and recipient addresses respecti)235.918 442.2 R -.15 +(ve)-.25 G(ly).15 E 5.453(.T)-.65 G(he)489.71 442.2 Q(y)-.15 E +(are applied before an)117 454.2 Q 2.5(ys)-.15 G +(peci\214cation in the mailer de\214nition.)212.37 454.2 Q(The)5 E 2.5(ym)-.15 +G(ust ne)391.1 454.2 Q -.15(ve)-.25 G 2.5(rr).15 G(esolv)432.91 454.2 Q(e.)-.15 +E .4 LW 77 483.6 72 483.6 DL 79 483.6 74 483.6 DL 84 483.6 79 483.6 DL 89 483.6 +84 483.6 DL 94 483.6 89 483.6 DL 99 483.6 94 483.6 DL 104 483.6 99 483.6 DL 109 +483.6 104 483.6 DL 114 483.6 109 483.6 DL 119 483.6 114 483.6 DL 124 483.6 119 +483.6 DL 129 483.6 124 483.6 DL 134 483.6 129 483.6 DL 139 483.6 134 483.6 DL +144 483.6 139 483.6 DL 149 483.6 144 483.6 DL 154 483.6 149 483.6 DL 159 483.6 +154 483.6 DL 164 483.6 159 483.6 DL 169 483.6 164 483.6 DL 174 483.6 169 483.6 +DL 179 483.6 174 483.6 DL 184 483.6 179 483.6 DL 189 483.6 184 483.6 DL 194 +483.6 189 483.6 DL 199 483.6 194 483.6 DL 204 483.6 199 483.6 DL 209 483.6 204 +483.6 DL 214 483.6 209 483.6 DL 219 483.6 214 483.6 DL 224 483.6 219 483.6 DL +229 483.6 224 483.6 DL 234 483.6 229 483.6 DL 239 483.6 234 483.6 DL 244 483.6 +239 483.6 DL 249 483.6 244 483.6 DL 254 483.6 249 483.6 DL 259 483.6 254 483.6 +DL 264 483.6 259 483.6 DL 269 483.6 264 483.6 DL 274 483.6 269 483.6 DL 279 +483.6 274 483.6 DL 284 483.6 279 483.6 DL 289 483.6 284 483.6 DL 294 483.6 289 +483.6 DL 299 483.6 294 483.6 DL 304 483.6 299 483.6 DL 309 483.6 304 483.6 DL +314 483.6 309 483.6 DL 319 483.6 314 483.6 DL 324 483.6 319 483.6 DL 329 483.6 +324 483.6 DL 334 483.6 329 483.6 DL 339 483.6 334 483.6 DL 344 483.6 339 483.6 +DL 349 483.6 344 483.6 DL 354 483.6 349 483.6 DL 359 483.6 354 483.6 DL 364 +483.6 359 483.6 DL 369 483.6 364 483.6 DL 374 483.6 369 483.6 DL 379 483.6 374 +483.6 DL 384 483.6 379 483.6 DL 389 483.6 384 483.6 DL 394 483.6 389 483.6 DL +399 483.6 394 483.6 DL 404 483.6 399 483.6 DL 409 483.6 404 483.6 DL 414 483.6 +409 483.6 DL 419 483.6 414 483.6 DL 424 483.6 419 483.6 DL 429 483.6 424 483.6 +DL 434 483.6 429 483.6 DL 439 483.6 434 483.6 DL 444 483.6 439 483.6 DL 449 +483.6 444 483.6 DL 454 483.6 449 483.6 DL 459 483.6 454 483.6 DL 464 483.6 459 +483.6 DL 469 483.6 464 483.6 DL 474 483.6 469 483.6 DL 479 483.6 474 483.6 DL +484 483.6 479 483.6 DL 489 483.6 484 483.6 DL 494 483.6 489 483.6 DL 499 483.6 +494 483.6 DL 504 483.6 499 483.6 DL(addr)91.915 578 Q 133.2 576 111.6 576 DL +133.2 576 126 577.8 DL 133.2 576 126 574.2 DL(3)141.5 578 Q 133.2 565.2 133.2 +586.8 DL 154.8 565.2 133.2 565.2 DL 154.8 586.8 154.8 565.2 DL 133.2 586.8 +154.8 586.8 DL 176.4 576 154.8 576 DL 176.4 576 169.2 577.8 DL 176.4 576 169.2 +574.2 DL(D)183.59 578 Q 176.4 565.2 176.4 586.8 DL 198 565.2 176.4 565.2 DL 198 +586.8 198 565.2 DL 176.4 586.8 198 586.8 DL 219.6 576 198 576 DL 277.2 558 +255.6 558 DL 277.2 558 270 559.8 DL 277.2 558 270 556.2 DL(1)285.5 560 Q 277.2 +547.2 277.2 568.8 DL 298.8 547.2 277.2 547.2 DL 298.8 568.8 298.8 547.2 DL +277.2 568.8 298.8 568.8 DL 320.4 558 298.8 558 DL 320.4 558 313.2 559.8 DL +320.4 558 313.2 556.2 DL(S)328.42 560 Q 320.4 547.2 320.4 568.8 DL 342 547.2 +320.4 547.2 DL 342 568.8 342 547.2 DL 320.4 568.8 342 568.8 DL 363.6 558 342 +558 DL 277.2 594 255.6 594 DL 277.2 594 270 595.8 DL 277.2 594 270 592.2 DL(2) +285.5 596 Q 277.2 583.2 277.2 604.8 DL 298.8 583.2 277.2 583.2 DL 298.8 604.8 +298.8 583.2 DL 277.2 604.8 298.8 604.8 DL 320.4 594 298.8 594 DL 320.4 594 +313.2 595.8 DL 320.4 594 313.2 592.2 DL(R)327.865 596 Q 320.4 583.2 320.4 604.8 +DL 342 583.2 320.4 583.2 DL 342 604.8 342 583.2 DL 320.4 604.8 342 604.8 DL +363.6 594 342 594 DL 421.2 576 399.6 576 DL 421.2 576 414 577.8 DL 421.2 576 +414 574.2 DL(4)429.5 578 Q 421.2 565.2 421.2 586.8 DL 442.8 565.2 421.2 565.2 +DL 442.8 586.8 442.8 565.2 DL 421.2 586.8 442.8 586.8 DL 464.4 576 442.8 576 DL +464.4 576 457.2 577.8 DL 464.4 576 457.2 574.2 DL(msg)466.865 578 Q 255.6 558 +219.6 576 DL 255.6 594 219.6 576 DL 399.6 576 363.6 558 DL 399.6 576 363.6 594 +DL 208.8 522 187.2 522 DL 208.8 522 201.6 523.8 DL 208.8 522 201.6 520.2 DL(0) +217.1 524 Q 208.8 511.2 208.8 532.8 DL 230.4 511.2 208.8 511.2 DL 230.4 532.8 +230.4 511.2 DL 208.8 532.8 230.4 532.8 DL 252 522 230.4 522 DL 252 522 244.8 +523.8 DL 252 522 244.8 520.2 DL(resolv)265.69 524 Q(ed address)-.15 E 187.2 522 +162 576 DL(Figure 1 \212 Re)216.045 624 Q(writing set semantics)-.25 E 2.5 +(D\212s)209.35 636 S(ender domain addition)235.46 636 Q 2.5(S\212m)209.35 648 S +(ailer)237.69 648 Q(-speci\214c sender re)-.2 E(writing)-.25 E 2.5(R\212m) +209.35 660 S(ailer)238.8 660 Q(-speci\214c recipient re)-.2 E(writing)-.25 E 77 +672 72 672 DL 79 672 74 672 DL 84 672 79 672 DL 89 672 84 672 DL 94 672 89 672 +DL 99 672 94 672 DL 104 672 99 672 DL 109 672 104 672 DL 114 672 109 672 DL 119 +672 114 672 DL 124 672 119 672 DL 129 672 124 672 DL 134 672 129 672 DL 139 672 +134 672 DL 144 672 139 672 DL 149 672 144 672 DL 154 672 149 672 DL 159 672 154 +672 DL 164 672 159 672 DL 169 672 164 672 DL 174 672 169 672 DL 179 672 174 672 +DL 184 672 179 672 DL 189 672 184 672 DL 194 672 189 672 DL 199 672 194 672 DL +204 672 199 672 DL 209 672 204 672 DL 214 672 209 672 DL 219 672 214 672 DL 224 +672 219 672 DL 229 672 224 672 DL 234 672 229 672 DL 239 672 234 672 DL 244 672 +239 672 DL 249 672 244 672 DL 254 672 249 672 DL 259 672 254 672 DL 264 672 259 +672 DL 269 672 264 672 DL 274 672 269 672 DL 279 672 274 672 DL 284 672 279 672 +DL 289 672 284 672 DL 294 672 289 672 DL 299 672 294 672 DL 304 672 299 672 DL +309 672 304 672 DL 314 672 309 672 DL 319 672 314 672 DL 324 672 319 672 DL 329 +672 324 672 DL 334 672 329 672 DL 339 672 334 672 DL 344 672 339 672 DL 349 672 +344 672 DL 354 672 349 672 DL 359 672 354 672 DL 364 672 359 672 DL 369 672 364 +672 DL 374 672 369 672 DL 379 672 374 672 DL 384 672 379 672 DL 389 672 384 672 +DL 394 672 389 672 DL 399 672 394 672 DL 404 672 399 672 DL 409 672 404 672 DL +414 672 409 672 DL 419 672 414 672 DL 424 672 419 672 DL 429 672 424 672 DL 434 +672 429 672 DL 439 672 434 672 DL 444 672 439 672 DL 449 672 444 672 DL 454 672 +449 672 DL 459 672 454 672 DL 464 672 459 672 DL 469 672 464 672 DL 474 672 469 +672 DL 479 672 474 672 DL 484 672 479 672 DL 489 672 484 672 DL 494 672 489 672 +DL 499 672 494 672 DL 504 672 499 672 DL EP +%%Page: 31 26 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-31)452.9 60 Q/F1 10/Times-Roman@0 SF 1.266 +(Ruleset four is applied to all addresses in the message.)142 96 R 1.265 +(It is typically used to translate)6.265 F(internal to e)117 108 Q +(xternal form.)-.15 E F0 2.5(5.1.4. IPC)102 132 R(mailers)2.5 E F1 1.332 +(Some special processing occurs if the ruleset zero resolv)142 148.2 R 1.333 +(es to an IPC mailer \(that is, a)-.15 F 1.179 +(mailer that has \231[IPC]\232 listed as the P)117 160.2 R 1.179(ath in the) +-.15 F F0(M)3.679 E F1 1.179(con\214guration line.)3.679 F 1.178 +(The host name passed)6.178 F .168(after \231$@\232 has MX e)117 172.2 R .168 +(xpansion performed; this looks the name up in DNS to \214nd alternate deli) +-.15 F(v-)-.25 E(ery sites.)117 184.2 Q(The host name can also be pro)142 200.4 +Q(vided as a dotted quad in square brack)-.15 E(ets; for e)-.1 E(xample:)-.15 E +([128.32.149.78])157 216.6 Q(This causes direct con)117 232.8 Q -.15(ve)-.4 G +(rsion of the numeric v).15 E(alue to a TCP/IP host address.)-.25 E .214(The h\ +ost name passed in after the \231$@\232 may also be a colon-separated list of \ +hosts.)142 249 R(Each)5.213 E .484(is separately MX e)117 261 R .484 +(xpanded and the results are concatenated to mak)-.15 F 2.985(e\()-.1 G .485 +(essentially\) one long MX)401.165 261 R 3.465(list. The)117 273 R .964 +(intent here is to create \231f)3.465 F(ak)-.1 E .964 +(e\232 MX records that are not published in DNS for pri)-.1 F -.25(va)-.25 G +(te).25 E(internal netw)117 285 Q(orks.)-.1 E +(As a \214nal special case, the host name can be passed in as a te)142 301.2 Q +(xt string in square brack)-.15 E(ets:)-.1 E([ucb)157 317.4 Q -.25(va)-.15 G +(x.berk).25 E(ele)-.1 E -.65(y.)-.15 G(edu]).65 E .312(This form a)117 333.6 R +-.2(vo)-.2 G .312(ids the MX mapping.).2 F F0(N.B.:)5.312 E/F2 10 +/Times-Italic@0 SF .313(This is intended only for situations wher)2.812 F 2.813 +(ey)-.37 G .313(ou have a)464.494 333.6 R .338(network \214r)117 345.6 R -.15 +(ew)-.37 G .337(all or other host that will do special pr).15 F .337 +(ocessing for all your mail, so that your MX)-.45 F -.37(re)117 357.6 S(cor).37 +E 3.958(dp)-.37 G 1.458(oints to a gate)151.878 357.6 R 1.458(way mac)-.15 F +1.458(hine; this mac)-.15 F 1.459(hine could then do dir)-.15 F 1.459 +(ect delivery to mac)-.37 F(hines)-.15 E .09(within your local domain.)117 +369.6 R .09(Use of this featur)5.09 F 2.59(ed)-.37 G(ir)306.8 369.6 Q .09 +(ectly violates RFC 1123 section 5.3.5: it should)-.37 F(not be used lightly) +117 381.6 Q(.)-.55 E F0 2.5(5.2. D)87 405.6 R 2.5<8a44>2.5 G(e\214ne Macr) +136.44 405.6 Q(o)-.18 E F1 .081 +(Macros are named with a single character or with a w)127 421.8 R .082 +(ord in {braces}.)-.1 F .082(Single character names)5.082 F .45 +(may be selected from the entire ASCII set, b)102 433.8 R .45(ut user)-.2 F .45 +(-de\214ned macros should be selected from the set)-.2 F .446 +(of upper case letters only)102 445.8 R 5.446(.L)-.65 G -.25(ow)217.72 445.8 S +.446(er case letters and special symbols are used internally).25 F 5.446(.L) +-.65 G .446(ong names)460.504 445.8 R(be)102 457.8 Q .913(ginning with a lo) +-.15 F .913(wer case letter or a punctuation character are reserv)-.25 F .912 +(ed for use by sendmail, so)-.15 F(user)102 469.8 Q +(-de\214ned long macro names should be)-.2 E(gin with an upper case letter)-.15 +E(.)-.55 E(The syntax for macro de\214nitions is:)127 486 Q F0(D)142 502.2 Q F2 +1.666(xv)C(al)-1.666 E F1(where)102 518.4 Q F2(x)3.068 E F1 .568 +(is the name of the macro \(which may be a single character or a w)3.068 F .569 +(ord in braces\) and)-.1 F F2(val)3.069 E F1(is)3.069 E .479(the v)102 530.4 R +.479(alue it should ha)-.25 F -.15(ve)-.2 G 5.479(.T).15 G .478 +(here should be no spaces gi)212.395 530.4 R -.15(ve)-.25 G 2.978(nt).15 G .478 +(hat do not actually belong in the macro)344.284 530.4 R -.25(va)102 542.4 S +(lue.).25 E .494(Macros are interpolated using the construct)127 558.6 R F0($) +2.994 E F2(x)A F1 2.994(,w)C(here)327.638 558.6 Q F2(x)2.994 E F1 .494 +(is the name of the macro to be inter)2.994 F(-)-.2 E 2.933(polated. This)102 +570.6 R .433(interpolation is done when the con\214guration \214le is read, e) +2.933 F .432(xcept in)-.15 F F0(M)2.932 E F1 2.932(lines. The)2.932 F(spe-) +2.932 E(cial construct)102 582.6 Q F0($&)2.5 E F2(x)A F1(can be used in)2.5 E +F0(R)2.5 E F1(lines to get deferred interpolation.)2.5 E +(Conditionals can be speci\214ed using the syntax:)127 598.8 Q($?x te)142 615 Q +(xt1 $| te)-.15 E(xt2 $.)-.15 E 1.127(This interpolates)102 631.2 R F2(te)3.627 +E(xt1)-.2 E F1 1.127(if the macro)3.627 F F0($x)3.627 E F1 1.128(is set, and) +3.628 F F2(te)3.628 E(xt2)-.2 E F1 3.628(otherwise. The)3.628 F 1.128 +(\231else\232 \()3.628 F F0($|)A F1 3.628(\)c)C 1.128(lause may be)449.534 +631.2 R(omitted.)102 643.2 Q(Lo)127 659.4 Q .58 +(wer case macro names are reserv)-.25 F .58(ed to ha)-.15 F .88 -.15(ve s)-.2 H +.58(pecial semantics, used to pass information in).15 F 1.56(or out of)102 +671.4 R F2(sendmail)4.06 E F1 4.06(,a)C 1.561(nd special characters are reserv) +190.73 671.4 R 1.561(ed to pro)-.15 F 1.561(vide conditionals, etc.)-.15 F +1.561(Upper case)6.561 F(names \(that is,)102 683.4 Q F0($A)2.5 E F1(through) +2.5 E F0($Z)2.5 E F1 2.5(\)a)C(re speci\214cally reserv)232.82 683.4 Q +(ed for con\214guration \214le authors.)-.15 E 1.303(The follo)127 699.6 R +1.303(wing macros are de\214ned and/or used internally by)-.25 F F2(sendmail) +3.802 E F1 1.302(for interpolation into)3.802 F EP +%%Page: 32 27 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-32 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(ar)102 98 Q(gv') +-.18 E 2.792(sf)-.55 G .292(or mailers or for other conte)132.382 98 R 2.793 +(xts. The)-.15 F .293(ones mark)2.793 F .293 +(ed \207 are information passed into sendmail)-.1 F/F2 7/Times-Roman@0 SF(15) +494.5 94 Q F1(,)501.5 98 Q .036(the ones mark)102 110 R .036 +(ed \210 are information passed both in and out of sendmail, and the unmark)-.1 +F .035(ed macros are)-.1 F(passed out of sendmail b)102 122 Q +(ut are not otherwise used internally)-.2 E 5(.T)-.65 G(hese macros are:)354.45 +122 Q 13.06($a The)102 138.2 R(origination date in RFC 822 format.)2.5 E +(This is e)5 E(xtracted from the Date: line.)-.15 E 12.5($b The)102 154.4 R +(current date in RFC 822 format.)2.5 E 13.06($c The)102 170.6 R .002 +(hop count.)2.502 F .002(This is a count of the number of Recei)5.002 F -.15 +(ve)-.25 G .003(d: lines plus the v).15 F .003(alue of the)-.25 F F0<ad68>2.503 +E F1(com-)2.503 E(mand line \215ag.)127 182.6 Q 12.5($d The)102 198.8 R +(current date in UNIX \(ctime\) format.)2.5 E 8.06($e\207 \(Obsolete;)102 215 R +1.814(use SmtpGreetingMessage option instead.\))4.314 F 1.814 +(The SMTP entry message.)6.814 F 1.814(This is)6.814 F 2.008 +(printed out when SMTP starts up.)127 227 R 2.008(The \214rst w)7.008 F 2.008 +(ord must be the)-.1 F F0($j)4.508 E F1 2.009(macro as speci\214ed by)4.508 F +2.732(RFC821. Def)127 239 R .232(aults to \231$j Sendmail $v ready at $b\232.) +-.1 F .231(Commonly rede\214ned to include the con-)5.231 F(\214guration v)127 +251 Q(ersion number)-.15 E 2.5(,e)-.4 G +(.g., \231$j Sendmail $v/$Z ready at $b\232)239.77 251 Q 14.17($f The)102 267.2 +R(en)2.5 E -.15(ve)-.4 G(lope sender \(from\) address.).15 E 12.5($g The)102 +283.4 R .017(sender address relati)2.517 F .317 -.15(ve t)-.25 H 2.517(ot).15 G +.017(he recipient.)251.375 283.4 R -.15(Fo)5.017 G 2.517(re).15 G .018 +(xample, if)326.386 283.4 R F0($f)2.518 E F1 .018(is \231foo\232,)2.518 F F0 +($g)2.518 E F1 .018(will be \231host!foo\232,)2.518 F +(\231foo@host.domain\232, or whate)127 295.4 Q -.15(ve)-.25 G 2.5(ri).15 G 2.5 +(sa)264.95 295.4 S(ppropriate for the recei)275.78 295.4 Q(ving mailer)-.25 E +(.)-.55 E 12.5($h The)102 311.6 R(recipient host.)2.5 E +(This is set in ruleset 0 from the $# \214eld of a parsed address.)5 E 14.72 +($i The)102 327.8 R(queue id, e.g., \231HAA12345\232.)2.5 E 9.72($j\210 The)102 +344 R(\231of)2.747 E .247(\214cial\232 domain name for this site.)-.25 F .247 +(This is fully quali\214ed if the full quali\214cation can be)5.247 F 3.093 +(found. It)127 356 R/F3 10/Times-Italic@0 SF(must)3.093 E F1 .594(be rede\214n\ +ed to be the fully quali\214ed domain name if your system is not con-)3.093 F +(\214gured so that information can \214nd it automatically)127 368 Q(.)-.65 E +12.5($k The)102 384.2 R(UUCP node name \(from the uname system call\).)2.5 E +9.72($l\207 \(Obsolete;)102 400.4 R 1.282(use UnixFromLine option instead.\)) +3.782 F 1.282(The format of the UNIX from line.)6.282 F(Unless)6.281 E 1.409 +(you ha)127 412.4 R 1.709 -.15(ve c)-.2 H 1.409 +(hanged the UNIX mailbox format, you should not change the def).15 F 1.41 +(ault, which is)-.1 F(\231From $g)127 424.4 Q($d\232.)5 E 9.72($m The)102 440.6 +R .719(domain part of the)3.219 F F3 -.1(ge)3.219 G(thostname).1 E F1 .718 +(return v)3.219 F 3.218(alue. Under)-.25 F .718(normal circumstances,)3.218 F +F0($j)3.218 E F1 .718(is equi)3.218 F(v-)-.25 E(alent to)127 452.6 Q F0($w)2.5 +E(.$m)-.7 E F1(.)A 7.5($n\207 The)102 468.8 R +(name of the daemon \(for error messages\).)2.5 E(Def)5 E +(aults to \231MAILER-D)-.1 E(AEMON\232.)-.4 E 7.5($o\207 \(Obsolete:)102 485 R +.65(use OperatorChars option instead.\))3.15 F .651 +(The set of \231operators\232 in addresses.)5.651 F 3.151(Al)5.651 G .651 +(ist of)483.069 485 R .582(characters which will be considered tok)127 497 R +.581(ens and which will separate tok)-.1 F .581(ens when doing pars-)-.1 F +3.277(ing. F)127 509 R .777(or e)-.15 F .777(xample, if \231@\232 were in the) +-.15 F F0($o)3.278 E F1 .778(macro, then the input \231a@b\232 w)3.278 F .778 +(ould be scanned as)-.1 F .628(three tok)127 521 R .628(ens: \231a,)-.1 F 3.128 +<9a99>-.7 G(@,)204.724 521 Q 3.128<9a61>-.7 G .628(nd \231b)227.742 521 R 4.527 +-.7(.\232 D)-.4 H(ef).7 E .627 +(aults to \231.:@[]\232, which is the minimum set necessary to)-.1 F .856(do R\ +FC 822 parsing; a richer set of operators is \231.:%@!/[]\232, which adds supp\ +ort for UUCP)127 533 R(,)-1.11 E(the %-hack, and X.400 addresses.)127 545 Q +12.5($p Sendmail')102 561.2 R 2.5(sp)-.55 G(rocess id.)178.95 561.2 Q 7.5 +($q\207 Def)102 577.4 R .404(ault format of sender address.)-.1 F(The)5.404 E +F0($q)2.903 E F1 .403(macro speci\214es ho)2.903 F 2.903(wa)-.25 G 2.903(na) +388.955 577.4 S .403(ddress should appear in a)401.298 577.4 R 1.18 +(message when it is def)127 589.4 R 3.681(aulted. Def)-.1 F 1.181 +(aults to \231<$g>\232.)-.1 F 1.181(It is commonly rede\214ned to be \231$?x$x) +6.181 F(<$g>$|$g$.)127 601.4 Q 5<9a6f>-.7 G 2.5<7299>186.52 601.4 S +($g$?x \($x\)$.)196.79 601.4 Q(\232, corresponding to the follo)-.7 E(wing tw) +-.25 E 2.5(of)-.1 G(ormats:)403.21 601.4 Q(Eric Allman <eric@CS.Berk)167 617.6 +Q(ele)-.1 E -.65(y.)-.15 G(EDU>).65 E(eric@CS.Berk)167 629.6 Q(ele)-.1 E -.65 +(y.)-.15 G(EDU \(Eric Allman\)).65 E F3(Sendmail)127 645.8 Q F1 +(properly quotes names that ha)2.5 E .3 -.15(ve s)-.2 H +(pecial characters if the \214rst form is used.).15 E 14.17($r Protocol)102 662 +R .977(used to recei)3.477 F 1.277 -.15(ve t)-.25 H .976(he message.).15 F .976 +(Set from the)5.976 F F0<ad70>3.476 E F1 .976 +(command line \215ag or by the SMTP)3.476 F(serv)127 674 Q(er code.)-.15 E .32 +LW 76 688.4 72 688.4 DL 80 688.4 76 688.4 DL 84 688.4 80 688.4 DL 88 688.4 84 +688.4 DL 92 688.4 88 688.4 DL 96 688.4 92 688.4 DL 100 688.4 96 688.4 DL 104 +688.4 100 688.4 DL 108 688.4 104 688.4 DL 112 688.4 108 688.4 DL 116 688.4 112 +688.4 DL 120 688.4 116 688.4 DL 124 688.4 120 688.4 DL 128 688.4 124 688.4 DL +132 688.4 128 688.4 DL 136 688.4 132 688.4 DL 140 688.4 136 688.4 DL 144 688.4 +140 688.4 DL 148 688.4 144 688.4 DL 152 688.4 148 688.4 DL 156 688.4 152 688.4 +DL 160 688.4 156 688.4 DL 164 688.4 160 688.4 DL 168 688.4 164 688.4 DL 172 +688.4 168 688.4 DL 176 688.4 172 688.4 DL 180 688.4 176 688.4 DL 184 688.4 180 +688.4 DL 188 688.4 184 688.4 DL 192 688.4 188 688.4 DL 196 688.4 192 688.4 DL +200 688.4 196 688.4 DL 204 688.4 200 688.4 DL 208 688.4 204 688.4 DL 212 688.4 +208 688.4 DL 216 688.4 212 688.4 DL/F4 5/Times-Roman@0 SF(15)93.6 698.8 Q/F5 8 +/Times-Roman@0 SF(As of v)3.2 I(ersion 8.6, all of these macros ha)-.12 E .24 +-.12(ve r)-.16 H(easonable def).12 E 2(aults. Pre)-.08 F(vious v)-.2 E +(ersions required that the)-.12 E 2(yb)-.12 G 2(ed)424.728 702 S(e\214ned.) +434.28 702 Q EP +%%Page: 33 28 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-33)452.9 60 Q/F1 10/Times-Roman@0 SF 13.61($s Sender')102 96 R 2.5(sh) +-.55 G(ost name.)168.94 96 Q(Set from the)5 E F0<ad70>2.5 E F1 +(command line \215ag or by the SMTP serv)2.5 E(er code.)-.15 E 14.72($t A)102 +112.2 R(numeric representation of the current time.)2.5 E 12.5($u The)102 128.4 +R(recipient user)2.5 E(.)-.55 E 12.5($v The)102 144.6 R -.15(ve)2.5 G +(rsion number of the).15 E/F2 10/Times-Italic@0 SF(sendmail)2.5 E F1(binary)2.5 +E(.)-.65 E 5.28($w\210 The)102 160.8 R(hostname of this site.)2.5 E +(This is the root name of this host \(b)5 E(ut see belo)-.2 E 2.5(wf)-.25 G +(or ca)432.64 160.8 Q -.15(ve)-.2 G(ats\).).15 E 12.5($x The)102 177 R +(full name of the sender)2.5 E(.)-.55 E 13.06($z The)102 193.2 R +(home directory of the recipient.)2.5 E 12.5($_ The)102 209.4 R -.25(va)2.5 G +(lidated sender address.).25 E .749 +(There are three types of dates that can be used.)127 225.6 R(The)5.749 E F0 +($a)3.249 E F1(and)3.249 E F0($b)3.249 E F1 .749(macros are in RFC 822 for) +3.249 F(-)-.2 E(mat;)102 237.6 Q F0($a)3.214 E F1 .714(is the time as e)3.214 F +.713(xtracted from the \231Date:\232 line of the message \(if there w)-.15 F +.713(as one\), and)-.1 F F0($b)3.213 E F1(is)3.213 E .056 +(the current date and time \(used for postmarks\).)102 249.6 R .057 +(If no \231Date:\232 line is found in the incoming message,)5.056 F F0($a)102 +261.6 Q F1 .305(is set to the current time also.)2.805 F(The)5.305 E F0($d) +2.805 E F1 .304(macro is equi)2.805 F -.25(va)-.25 G .304(lent to the).25 F F0 +($b)2.804 E F1 .304(macro in UNIX \(ctime\) for)2.804 F(-)-.2 E(mat.)102 273.6 +Q .238(The macros)127 289.8 R F0($w)2.738 E F1(,)A F0($j)2.738 E F1 2.738(,a)C +(nd)212.372 289.8 Q F0($m)2.738 E F1 .238 +(are set to the identity of this host.)2.738 F F2(Sendmail)5.239 E F1 .239 +(tries to \214nd the fully)2.739 F .335 +(quali\214ed name of the host if at all possible; it does this by calling)102 +301.8 R F2 -.1(ge)2.834 G(thostname).1 E F1 .334(\(2\) to get the current)B +.457(hostname and then passing that to)102 313.8 R F2 -.1(ge)2.957 G +(thostbyname).1 E F1 .457(\(3\) which is supposed to return the canonical v)B +(er)-.15 E(-)-.2 E .279(sion of that host name.)102 327.8 R/F3 7/Times-Roman@0 +SF(16)193.946 323.8 Q F1 .279(Assuming this is successful,)203.725 327.8 R F0 +($j)2.778 E F1 .278(is set to the fully quali\214ed name and)2.778 F F0($m) +2.778 E F1(is)2.778 E .706(set to the domain part of the name \(e)102 339.8 R +-.15(ve)-.25 G .706(rything after the \214rst dot\).).15 F(The)5.706 E F0($w) +3.206 E F1 .706(macro is set to the \214rst)3.206 F -.1(wo)102 351.8 S .359 +(rd \(e).1 F -.15(ve)-.25 G .358(rything before the \214rst dot\) if you ha).15 +F .658 -.15(ve a l)-.2 H -2.15 -.25(ev e).15 H 2.858(l5o).25 G 2.858(rh)345 +351.8 S .358(igher con\214guration \214le; otherwise, it)356.188 351.8 R .404 +(is set to the same v)102 363.8 R .405(alue as)-.25 F F0($j)2.905 E F1 5.405 +(.I)C 2.905(ft)229.965 363.8 S .405 +(he canoni\214cation is not successful, it is imperati)238.98 363.8 R .705 -.15 +(ve t)-.25 H .405(hat the con\214g).15 F(\214le set)102 377.8 Q F0($j)2.5 E F1 +(to the fully quali\214ed domain name)2.5 E F3(17)279.77 373.8 Q F1(.)286.77 +377.8 Q(The)127 394 Q F0($f)2.833 E F1 .333(macro is the id of the sender as o\ +riginally determined; when mailing to a speci\214c host)2.833 F(the)102 406 Q +F0($g)3.224 E F1 .724(macro is set to the address of the sender)3.224 F F2 -.37 +(re)3.225 G .725(lative to the r).37 F(ecipient.)-.37 E F1 -.15(Fo)5.725 G +3.225(re).15 G .725(xample, if I send to)423.61 406 R +(\231bollard@matisse.CS.Berk)102 418 Q(ele)-.1 E -.65(y.)-.15 G .425 +(EDU\232 from the machine \231v).65 F(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.) +-.15 G .424(EDU\232 the).65 F F0($f)2.924 E F1(macro)2.924 E +(will be \231eric\232 and the)102 430 Q F0($g)2.5 E F1 +(macro will be \231eric@v)2.5 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G +(EDU.).65 E<9a>-.7 E(The)127 446.2 Q F0($x)2.562 E F1 .062 +(macro is set to the full name of the sender)2.562 F 5.062(.T)-.55 G .062 +(his can be determined in se)338.824 446.2 R -.15(ve)-.25 G .063(ral w).15 F +2.563(ays. It)-.1 F .63(can be passed as \215ag to)102 458.2 R F2(sendmail)3.13 +E F1 5.629(.I)C 3.129(tc)249.439 458.2 S .629(an be de\214ned in the)259.788 +458.2 R/F4 9/Times-Roman@0 SF -.315(NA)3.129 G(ME).315 E F1(en)3.129 E .629 +(vironment v)-.4 F 3.129(ariable. The)-.25 F(third)3.129 E .948 +(choice is the v)102 470.2 R .948 +(alue of the \231Full-Name:\232 line in the header if it e)-.25 F .949 +(xists, and the fourth choice is the)-.15 F .526 +(comment \214eld of a \231From:\232 line.)102 482.2 R .526(If all of these f) +5.526 F .526(ail, and if the message is being originated locally)-.1 F(,)-.65 E +(the full name is look)102 494.2 Q(ed up in the)-.1 E F2(/etc/passwd)2.5 E F1 +(\214le.)2.5 E 1.32(When sending, the)127 510.4 R F0($h)3.82 E F1(,)A F0($u) +3.82 E F1 3.82(,a)C(nd)246.37 510.4 Q F0($z)3.82 E F1 1.321 +(macros get set to the host, user)3.82 F 3.821(,a)-.4 G 1.321 +(nd home directory \(if)414.777 510.4 R .517(local\) of the recipient.)102 +522.4 R .517(The \214rst tw)5.517 F 3.016(oa)-.1 G .516(re set from the)256.878 +522.4 R F0($@)3.016 E F1(and)3.016 E F0($:)3.016 E F1 .516(part of the re)3.016 +F .516(writing rules, respec-)-.25 F(ti)102 534.4 Q -.15(ve)-.25 G(ly).15 E(.) +-.65 E(The)127 550.6 Q F0($p)3.806 E F1(and)3.806 E F0($t)3.806 E F1 1.306(mac\ +ros are used to create unique strings \(e.g., for the \231Message-Id:\232 \214\ +eld\).)3.806 F(The)102 562.6 Q F0($i)3.252 E F1 .751(macro is set to the queue\ + id on this host; if put into the timestamp line it can be e)3.252 F(xtremely) +-.15 E .164(useful for tracking messages.)102 574.6 R(The)5.164 E F0($v)2.664 E +F1 .164(macro is set to be the v)2.664 F .165(ersion number of)-.15 F F2 +(sendmail)2.665 E F1 2.665(;t)C .165(his is nor)463.87 574.6 R(-)-.2 E +(mally put in timestamps and has been pro)102 586.6 Q -.15(ve)-.15 G 2.5(ne).15 +G(xtremely useful for deb)289.31 586.6 Q(ugging.)-.2 E(The)127 602.8 Q F0($c) +3.548 E F1 1.048(\214eld is set to the \231hop count,)3.548 F 3.548<9a69>-.7 G +1.048(.e., the number of times this message has been pro-)290.162 602.8 R 2.856 +(cessed. This)102 614.8 R .356(can be determined by the)2.856 F F0<ad68>2.856 E +F1 .357(\215ag on the command line or by counting the timestamps)2.856 F +(in the message.)102 626.8 Q(The)127 643 Q F0($r)2.833 E F1(and)2.833 E F0($s) +2.833 E F1 .333(\214elds are set to the protocol used to communicate with)2.833 +F F2(sendmail)2.833 E F1 .333(and the send-)2.833 F .194(ing hostname.)102 655 +R(The)5.194 E 2.694(yc)-.15 G .194(an be set together using the)191.032 655 R +F0<ad70>2.694 E F1 .194(command line \215ag or separately using the)2.694 F F0 +<ad4d>2.695 E F1(or)102 667 Q F0(\255oM)2.5 E F1(\215ags.)2.5 E .32 LW 76 676.6 +72 676.6 DL 80 676.6 76 676.6 DL 84 676.6 80 676.6 DL 88 676.6 84 676.6 DL 92 +676.6 88 676.6 DL 96 676.6 92 676.6 DL 100 676.6 96 676.6 DL 104 676.6 100 +676.6 DL 108 676.6 104 676.6 DL 112 676.6 108 676.6 DL 116 676.6 112 676.6 DL +120 676.6 116 676.6 DL 124 676.6 120 676.6 DL 128 676.6 124 676.6 DL 132 676.6 +128 676.6 DL 136 676.6 132 676.6 DL 140 676.6 136 676.6 DL 144 676.6 140 676.6 +DL 148 676.6 144 676.6 DL 152 676.6 148 676.6 DL 156 676.6 152 676.6 DL 160 +676.6 156 676.6 DL 164 676.6 160 676.6 DL 168 676.6 164 676.6 DL 172 676.6 168 +676.6 DL 176 676.6 172 676.6 DL 180 676.6 176 676.6 DL 184 676.6 180 676.6 DL +188 676.6 184 676.6 DL 192 676.6 188 676.6 DL 196 676.6 192 676.6 DL 200 676.6 +196 676.6 DL 204 676.6 200 676.6 DL 208 676.6 204 676.6 DL 212 676.6 208 676.6 +DL 216 676.6 212 676.6 DL/F5 5/Times-Roman@0 SF(16)93.6 687 Q/F6 8 +/Times-Roman@0 SF -.12(Fo)3.2 K 2(re).12 G(xample, on some systems)115.024 +690.2 Q/F7 8/Times-Italic@0 SF -.08(ge)2 G(thostname).08 E F6 +(might return \231foo\232 which w)2 E(ould be mapped to \231foo.bar)-.08 E +(.com\232 by)-.44 E F7 -.08(ge)2 G(thostbyname).08 E F6(.)A F5(17)93.6 700.6 Q +F6(Older v)3.2 I(ersions of sendmail didn')-.12 E 2(tp)-.144 G(re-de\214ne) +211.88 703.8 Q/F8 8/Times-Bold@0 SF($j)2 E F6 +(at all, so up until 8.6, con\214g \214les)2 E F7(always)2 E F6 +(had to de\214ne)2 E F8($j)2 E F6(.)A EP +%%Page: 34 29 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-34 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(The)127 96 Q F0 +($_)2.967 E F1 .467(is set to a v)2.967 F .467(alidated sender host name.)-.25 +F .466(If the sender is running an RFC 1413 compli-)5.467 F .384 +(ant IDENT serv)102 108 R .384(er and the recei)-.15 F -.15(ve)-.25 G 2.884(rh) +.15 G .384(as the IDENT protocol turned on, it will include the user name) +249.254 108 R(on that host.)102 120 Q F0 2.5(5.3. C)87 144 R +(and F \212 De\214ne Classes)2.5 E F1 .66 +(Classes of phrases may be de\214ned to match on the left hand side of re)127 +160.2 R .659(writing rules, where a)-.25 F .192(\231phrase\232 is a sequence o\ +f characters that do not contain space characters.)102 172.2 R -.15(Fo)5.192 G +2.692(re).15 G .192(xample a class of all)421.582 172.2 R 1.428(local names fo\ +r this site might be created so that attempts to send to oneself can be elimin\ +ated.)102 184.2 R .041(These can either be de\214ned directly in the con\214gu\ +ration \214le or read in from another \214le.)102 196.2 R .041(Classes are) +5.041 F .649(named as a single letter or a w)102 208.2 R .649(ord in {braces}.) +-.1 F .649(Class names be)5.649 F .649(ginning with lo)-.15 F .648 +(wer case letters and)-.25 F .638(special characters are reserv)102 220.2 R +.638(ed for system use.)-.15 F .639 +(Classes de\214ned in con\214g \214les may be gi)5.639 F -.15(ve)-.25 G 3.139 +(nn).15 G(ames)483.45 220.2 Q 1.05 +(from the set of upper case letters for short names or be)102 232.2 R 1.05 +(ginning with an upper case letter for long)-.15 F(names.)102 244.2 Q +(The syntax is:)127 260.4 Q F0(C)142 276.6 Q/F2 10/Times-Italic@0 SF 1.666(cp)C +(hr)-1.666 E(ase1 phr)-.15 E(ase2...)-.15 E F0(F)142 288.6 Q F2 1.666<638c>C +(le)-1.666 E F1 .661(The \214rst form de\214nes the class)102 304.8 R F2(c) +3.161 E F1 .661(to match an)3.161 F 3.161(yo)-.15 G 3.161(ft)300.1 304.8 S .661 +(he named w)309.371 304.8 R 3.161(ords. It)-.1 F .661 +(is permissible to split them)3.161 F(among multiple lines; for e)102 316.8 Q +(xample, the tw)-.15 E 2.5(of)-.1 G(orms:)280.07 316.8 Q(CHmonet ucbmonet)142 +333 Q(and)102 349.2 Q(CHmonet)142 365.4 Q(CHucbmonet)142 377.4 Q(are equi)102 +393.6 Q -.25(va)-.25 G 2.5(lent. The).25 F -.74(``)2.5 G(F').74 E 2.5('f)-.74 G +(orm reads the elements of the class)206.65 393.6 Q F2(c)2.5 E F1 +(from the named)2.5 E F2(\214le)2.5 E F1(.)A 1.339 +(Elements of classes can be accessed in rules using)127 409.8 R F0($=)3.839 E +F1(or)3.839 E F0($~)3.839 E F1 6.339(.T)C(he)392.048 409.8 Q F0($~)3.839 E F1 +1.338(\(match entries not in)3.839 F(class\) only matches a single w)102 421.8 +Q(ord; multi-w)-.1 E(ord entries in the class are ignored in this conte)-.1 E +(xt.)-.15 E 1.098(The class)127 438 R F0($=w)3.598 E F1 1.098 +(is set to be the set of all names this host is kno)3.598 F 1.098(wn by)-.25 F +6.098(.T)-.65 G 1.098(his can be used to)428.506 438 R(match local hostnames.) +102 450 Q(The class)127 466.2 Q F0($=k)2.5 E F1(is set to be the same as)2.5 E +F0($k)2.5 E F1 2.5(,t)C(hat is, the UUCP node name.)297.69 466.2 Q(The class) +127 482.4 Q F0($=m)2.5 E F1 +(is set to the set of domains by which this host is kno)2.5 E +(wn, initially just)-.25 E F0($m)2.5 E F1(.)A .239(The class)127 498.6 R F0 +($=t)2.739 E F1 .239(is set to the set of trusted users by the)2.739 F F0(T) +2.739 E F1 .239(con\214guration line.)2.739 F .239(If you w)5.239 F .239 +(ant to read)-.1 F(trusted users from a \214le use)102 510.6 Q F0(Ft)2.5 E F2 +(/\214le/name)A F1(.)A .635(The class)127 526.8 R F0($=n)3.135 E F1 .635 +(can be set to the set of MIME body types that can ne)3.135 F -.15(ve)-.25 G +3.136(rb).15 G 3.136(ee)426.306 526.8 S .636(ight to se)438.322 526.8 R -.15 +(ve)-.25 G 3.136(nb).15 G(it)498.44 526.8 Q 2.76(encoded. It)102 538.8 R(def) +2.76 E .26(aults to \231multipart/signed\232.)-.1 F .26 +(Message types \231message/*\232 and \231multipart/*\232 are ne)5.26 F -.15(ve) +-.25 G(r).15 E .942(encoded directly)102 550.8 R 5.942(.M)-.65 G .943 +(ultipart messages are al)185.994 550.8 R -.1(wa)-.1 G .943(ys handled recursi) +.1 F -.15(ve)-.25 G(ly).15 E 5.943(.T)-.65 G .943(he handling of message/*) +399.241 550.8 R .658(messages are controlled by class)102 562.8 R F0($=s)3.158 +E F1 5.658(.T)C .657(he class)266.618 562.8 R F0($=e)3.157 E F1 .657 +(contains the Content-T)3.157 F(ransfer)-.35 E .657(-Encodings that)-.2 F .007 +(can be 8)102 574.8 R/F3 10/Symbol SF<ae>A F1 2.507(7b)C .007(it encoded.) +157.711 574.8 R .007 +(It is prede\214ned to contain \2317bit\232, \2318bit\232, and \231binary\232.) +5.007 F .007(The class)5.007 F F0($=s)2.507 E F1(con-)2.508 E 1.52 +(tains the set of subtypes of message that can be treated recursi)102 586.8 R +-.15(ve)-.25 G(ly).15 E 6.52(.B)-.65 G 4.02(yd)398.58 586.8 S(ef)412.6 586.8 Q +1.52(ault it contains only)-.1 F 3.213(\231rfc822\232. Other)102 598.8 R .713 +(\231message/*\232 types cannot be 8)3.213 F F3<ae>A F1 3.214(7b)C .714 +(it encoded.)319.862 598.8 R .714(If a message containing eight bit)5.714 F +1.714(data is sent to a se)102 610.8 R -.15(ve)-.25 G 4.214(nb).15 G 1.714 +(it host, and that message cannot be encoded into se)206.314 610.8 R -.15(ve) +-.25 G 4.213(nb).15 G 1.713(its, it will be)448.851 610.8 R +(stripped to 7 bits.)102 622.8 Q F2(Sendmail)127 639 Q F1 .182 +(can be compiled to allo)2.682 F 2.682(wa)-.25 G F2(scanf)A F1 .182 +(\(3\) string on the)B F0(F)2.682 E F1 2.683(line. This)2.683 F .183 +(lets you do simplistic)2.683 F .555(parsing of te)102 651 R .555(xt \214les.) +-.15 F -.15(Fo)5.555 G 3.055(re).15 G .554 +(xample, to read all the user names in your system)209.595 651 R F2 +(/etc/passwd)3.054 E F1 .554(\214le into a)3.054 F(class, use)102 663 Q +(FL/etc/passwd %[^:])142 679.2 Q(which reads e)102 695.4 Q -.15(ve)-.25 G +(ry line up to the \214rst colon.).15 E EP +%%Page: 35 30 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-35)452.9 60 Q 2.5(5.4. M)87 96 R 2.5<8a44>2.5 G(e\214ne Mailer)138.66 +96 Q/F1 10/Times-Roman@0 SF(Programs and interf)127 112.2 Q +(aces to mailers are de\214ned in this line.)-.1 E(The format is:)5 E F0(M)142 +128.4 Q/F2 10/Times-Italic@0 SF(name)A F1 2.5(,{)C F2(\214eld)182.9 128.4 Q F1 +(=)A F2(value)A F1(}*)1.666 E(where)102 144.6 Q F2(name)4.244 E F1 1.744(is th\ +e name of the mailer \(used internally only\) and the \231\214eld=name\232 pai\ +rs de\214ne)4.244 F(attrib)102 156.6 Q(utes of the mailer)-.2 E 5(.F)-.55 G +(ields are:)205.13 156.6 Q -.15(Pa)142 172.8 S 51.87(th The).15 F +(pathname of the mailer)2.5 E 47.83(Flags Special)142 184.8 R +(\215ags for this mailer)2.5 E 41.73(Sender Re)142 196.8 R +(writing set\(s\) for sender addresses)-.25 E 31.17(Recipient Re)142 208.8 R +(writing set\(s\) for recipient addresses)-.25 E(Ar)142 220.8 Q 49.13(gv An) +-.18 F(ar)2.5 E(gument v)-.18 E(ector to pass to this mailer)-.15 E 55.61 +(Eol The)142 232.8 R(end-of-line string for this mailer)2.5 E 35.62 +(Maxsize The)142 244.8 R(maximum message length to this mailer)2.5 E 32.27 +(Linelimit The)142 256.8 R(maximum line length in the message body)2.5 E 31.18 +(Directory The)142 268.8 R -.1(wo)2.5 G(rking directory for the mailer).1 E +42.84(Userid The)142 280.8 R(def)2.5 E(ault user and group id to run as)-.1 E +50.62(Nice The)142 292.8 R(nice\(2\) increment for the mailer)2.5 E 38.95 +(Charset The)142 304.8 R(def)2.5 E(ault character set for 8-bit characters)-.1 +E -.8(Ty)142 316.8 S 49.75(pe The).8 F +(MTS type information \(used for error messages\))2.5 E +(Only the \214rst character of the \214eld name is check)102 333 Q(ed.)-.1 E +.397(The follo)127 349.2 R .396 +(wing \215ags may be set in the mailer description.)-.25 F(An)5.396 E 2.896(yo) +-.15 G .396(ther \215ags may be used freely)386.77 349.2 R .075 +(to conditionally assign headers to messages destined for particular mailers.) +102 361.2 R .075(Flags mark)5.075 F .075(ed with \207 are)-.1 F 1.193 +(not interpreted by the)102 373.2 R F2(sendmail)3.693 E F1 1.193 +(binary; these are the con)3.693 F -.15(ve)-.4 G 1.192 +(ntionally used to correlate to the \215ags).15 F .737(portion of the)102 385.2 +R F0(H)3.237 E F1 3.237(line. Flags)3.237 F(mark)3.237 E .737 +(ed with \210 apply to the mailers for the sender address rather than)-.1 F +(the usual recipient mailers.)102 397.2 Q 15.56(aR)102 413.4 S .987(un Extende\ +d SMTP \(ESMTP\) protocol \(de\214ned in RFCs 1651, 1652, and 1653\).)128.67 +413.4 R .986(This \215ag)5.987 F(def)122 425.4 Q +(aults on if the SMTP greeting message includes the w)-.1 E(ord \231ESMTP\232.) +-.1 E 12.78(AL)102 441.6 S .762 +(ook up the user part of the address in the alias database.)128.11 441.6 R .763 +(Normally this is only set for local)5.762 F(mailers.)122 453.6 Q 15(bF)102 +469.8 S .456(orce a blank line on the end of a message.)127.41 469.8 R .456 +(This is intended to w)5.456 F .456(ork around some stupid v)-.1 F(er)-.15 E(-) +-.2 E .361(sions of /bin/mail that require a blank line, b)122 481.8 R .362 +(ut do not pro)-.2 F .362(vide it themselv)-.15 F 2.862(es. It)-.15 F -.1(wo) +2.862 G .362(uld not nor).1 F(-)-.2 E(mally be used on netw)122 493.8 Q +(ork mail.)-.1 E 15.56(cD)102 510 S 2.663(on)129.22 510 S .163 +(ot include comments in addresses.)141.883 510 R .163 +(This should only be used if you ha)5.163 F .463 -.15(ve t)-.2 H 2.663(ow).15 G +.163(ork around a)453.135 510 R 1.846 +(remote mailer that gets confused by comments.)122 522 R 1.846 +(This strips addresses of the form \231Phrase)6.846 F +(<address>\232 or \231address \(Comment\)\232 do)122 534 Q +(wn to just \231address\232.)-.25 E 5.83(C\210 If)102 550.2 R .214(mail is) +2.714 F F2 -.37(re)2.714 G(ceived).37 E F1 .213 +(from a mailer with this \215ag set, an)2.713 F 2.713(ya)-.15 G .213 +(ddresses in the header that do not ha)348.169 550.2 R -.15(ve)-.2 G .97 +(an at sign \(\231@\232\) after being re)122 562.2 R .97 +(written by ruleset three will ha)-.25 F 1.27 -.15(ve t)-.2 H .97 +(he \231@domain\232 clause from).15 F(the sender en)122 574.2 Q -.15(ve)-.4 G +(lope address tack).15 E(ed on.)-.1 E(This allo)5 E +(ws mail with headers of the form:)-.25 E(From: usera@hosta)162 590.4 Q -.8(To) +162 602.4 S 2.5(:u).8 G(serb@hostb, userc)182.59 602.4 Q(to be re)122 618.6 Q +(written as:)-.25 E(From: usera@hosta)162 634.8 Q -.8(To)162 646.8 S 2.5(:u).8 +G(serb@hostb, userc@hosta)182.59 646.8 Q(automatically)122 663 Q 5(.H)-.65 G +-.25(ow)190.51 663 S -2.15 -.25(ev e).25 H .8 -.4(r, i).25 H 2.5(td).4 G(oesn') +236.95 663 Q 2.5(tr)-.18 G(eally w)267.04 663 Q(ork reliably)-.1 E(.)-.65 E +5.28(D\207 This)102 679.2 R(mailer w)2.5 E(ants a \231Date:\232 header line.) +-.1 E 15.56(eT)102 695.4 S .174(his mailer is e)128.11 695.4 R(xpensi)-.15 E +.474 -.15(ve t)-.25 H 2.674(oc).15 G .173(onnect to, so try to a)237.03 695.4 R +-.2(vo)-.2 G .173(id connecting normally; an).2 F 2.673(yn)-.15 G .173 +(ecessary con-)449.687 695.4 R(nection will occur during a queue run.)122 707.4 +Q EP +%%Page: 36 31 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-36 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 13.89(EE)102 96 +S(scape lines be)128.11 96 Q +(ginning with \231From\232 in the message with a `>' sign.)-.15 E 16.67(fT)102 +112.2 S .19(he mailer w)128.11 112.2 R .19(ants a)-.1 F F0<ad66>2.69 E/F2 10 +/Times-Italic@0 SF(fr)2.69 E(om)-.45 E F1 .19(\215ag, b)2.69 F .19 +(ut only if this is a netw)-.2 F .19(ork forw)-.1 F .19 +(ard operation \(i.e., the mailer)-.1 F(will gi)122 124.2 Q .3 -.15(ve a)-.25 H +2.5(ne).15 G(rror if the e)175.76 124.2 Q -.15(xe)-.15 G +(cuting user does not ha).15 E .3 -.15(ve s)-.2 H(pecial permissions\).).15 E +6.94(F\207 This)102 140.4 R(mailer w)2.5 E(ants a \231From:\232 header line.) +-.1 E 15(gN)102 156.6 S(ormally)129.22 156.6 Q(,)-.65 E F2(sendmail)4.893 E F1 +2.393(sends internally generated email \(e.g., error messages\) using the null) +4.893 F 1.327(return address as required by RFC 1123.)122 168.6 R(Ho)6.327 E +(we)-.25 E -.15(ve)-.25 G 2.127 -.4(r, s).15 H 1.327(ome mailers don').4 F +3.827(ta)-.18 G 1.328(ccept a null return)427.537 168.6 R 3.311(address. If)122 +180.6 R(necessary)3.311 E 3.311(,y)-.65 G .811(ou can set the)219.303 180.6 R +F0(g)3.311 E F1 .811(\215ag to pre)3.311 F -.15(ve)-.25 G(nt).15 E F2(sendmail) +3.31 E F1 .81(from obe)3.31 F .81(ying the standards;)-.15 F 1.57 +(error messages will be sent as from the MAILER-D)122 192.6 R 1.57 +(AEMON \(actually)-.4 F 4.07(,t)-.65 G 1.57(he v)425.76 192.6 R 1.57 +(alue of the)-.25 F F0($n)4.07 E F1(macro\).)122 204.6 Q 15(hU)102 220.8 S +(pper case should be preserv)129.22 220.8 Q(ed in host names for this mailer) +-.15 E(.)-.55 E 16.67(IT)102 237 S .475 +(his mailer will be speaking SMTP to another)128.11 237 R F2(sendmail)2.974 E +F1 2.974<8a61>2.974 G 2.974(ss)370.066 237 S .474 +(uch it can use special protocol)380.82 237 R 3.632(features. This)122 249 R +1.133(option is not required \(i.e., if this option is omitted the transmissio\ +n will still)3.632 F(operate successfully)122 261 Q 2.5(,a)-.65 G +(lthough perhaps not as ef)211.6 261 Q(\214ciently as possible\).)-.25 E 15(kN) +102 277.2 S 1.03(ormally when)129.22 277.2 R F2(sendmail)3.53 E F1 1.03 +(connects to a host via SMTP)3.53 F 3.529(,i)-1.11 G 3.529(tc)356.257 277.2 S +1.029(hecks to mak)367.006 277.2 R 3.529(es)-.1 G 1.029(ure that this isn') +433.593 277.2 R(t)-.18 E .562(accidently the same host name as might happen if) +122 289.2 R F2(sendmail)3.062 E F1 .562(is miscon\214gured or if a long-haul) +3.062 F(netw)122 301.2 Q 1.074(ork interf)-.1 F 1.074 +(ace is set in loopback mode.)-.1 F 1.073 +(This \215ag disables the loopback check.)6.074 F 1.073(It should)6.073 F +(only be used under v)122 313.2 Q(ery unusual circumstances.)-.15 E 12.78(KC) +102 329.4 S(urrently unimplemented.)128.67 329.4 Q(Reserv)5 E(ed for chunking.) +-.15 E 17.22(lT)102 345.6 S(his mailer is local \(i.e., \214nal deli)128.11 +345.6 Q -.15(ve)-.25 G(ry will be performed\).).15 E 13.89(LL)102 361.8 S .819 +(imit the line lengths as speci\214ed in RFC821.)128.11 361.8 R .82 +(This deprecated option should be replaced by)5.819 F(the)122 373.8 Q F0(L=)2.5 +E F1(mail declaration.)2.5 E -.15(Fo)5 G 2.5(rh).15 G(istoric reasons, the) +245.04 373.8 Q F0(L)2.5 E F1(\215ag also sets the)2.5 E F0(7)2.5 E F1(\215ag.) +2.5 E 12.22(mT)102 390 S .464 +(his mailer can send to multiple users on the same host in one transaction.) +128.11 390 R .463(When a)5.463 F F0($u)2.963 E F1(macro)2.963 E .731 +(occurs in the)122 402 R F2(ar)3.231 E(gv)-.37 E F1 .732(part of the mailer de\ +\214nition, that \214eld will be repeated as necessary for all)3.231 F +(qualifying users.)122 414 Q 3.61(M\207 This)102 430.2 R(mailer w)2.5 E +(ants a \231Message-Id:\232 header line.)-.1 E 15(nD)102 446.4 S 2.5(on)129.22 +446.4 S(ot insert a UNIX-style \231From\232 line on the front of the message.) +141.72 446.4 Q 15(oA)102 462.6 S -.1(lwa)129.22 462.6 S .816(ys run as the o).1 +F .816(wner of the recipient mailbox.)-.25 F(Normally)5.816 E F2(sendmail)3.316 +E F1 .816(runs as the sender for)3.316 F .198 +(locally generated mail or as \231daemon\232 \(actually)122 474.6 R 2.698(,t) +-.65 G .198(he user speci\214ed in the)321.576 474.6 R F0(u)2.698 E F1 .198 +(option\) when deli)2.698 F(v-)-.25 E .981(ering netw)122 486.6 R .981 +(ork mail.)-.1 F .981(The normal beha)5.981 F .981 +(viour is required by most local mailers, which will not)-.2 F(allo)122 498.6 Q +2.52(wt)-.25 G .02(he en)149.27 498.6 R -.15(ve)-.4 G .021 +(lope sender address to be set unless the mailer is running as daemon.).15 F +.021(This \215ag is)5.021 F(ignored if the)122 510.6 Q F0(S)2.5 E F1 +(\215ag is set.)2.5 E 15(pU)102 526.8 S .498(se the route-addr style re)129.22 +526.8 R -.15(ve)-.25 G .498(rse-path in the SMTP \231MAIL FR).15 F .497 +(OM:\232 command rather than just)-.4 F .385 +(the return address; although this is required in RFC821 section 3.1, man)122 +538.8 R 2.886(yh)-.15 G .386(osts do not process)427.012 538.8 R(re)122 550.8 Q +-.15(ve)-.25 G(rse-paths properly).15 E 5(.R)-.65 G -2.15 -.25(ev e)224.81 +550.8 T(rse-paths are of).25 E(\214cially discouraged by RFC 1123.)-.25 E 6.94 +(P\207 This)102 567 R(mailer w)2.5 E(ants a \231Return-P)-.1 E(ath:\232 line.) +-.15 E 16.67(rS)102 583.2 S(ame as)127.56 583.2 Q F0(f)2.5 E F1 2.5(,b)C +(ut sends a)170.68 583.2 Q F0<ad72>2.5 E F1(\215ag.)2.5 E 16.11(sS)102 599.4 S +(trip quote characters \(" and \\\) of)127.56 599.4 Q 2.5(fo)-.25 G 2.5(ft) +266.07 599.4 S(he address before calling the mailer)274.68 599.4 Q(.)-.55 E +14.44(SD)102 615.6 S(on')129.22 615.6 Q 3.332(tr)-.18 G .832 +(eset the userid before calling the mailer)151.812 615.6 R 5.831(.T)-.55 G .831 +(his w)328.433 615.6 R .831(ould be used in a secure en)-.1 F(vironment)-.4 E +(where)122 627.6 Q F2(sendmail)3.317 E F1 .817(ran as root.)3.317 F .817 +(This could be used to a)5.817 F -.2(vo)-.2 G .817(id for).2 F .817 +(ged addresses.)-.18 F .817(If the)5.817 F F0(U=)3.317 E F1 .818(\214eld is) +3.317 F .974(also speci\214ed, this \215ag causes the user id to al)122 639.6 R +-.1(wa)-.1 G .974(ys be set to that user and group \(instead of).1 F(lea)122 +651.6 Q(ving it as root\).)-.2 E 15(uU)102 667.8 S(pper case should be preserv) +129.22 667.8 Q(ed in user names for this mailer)-.15 E(.)-.55 E 12.78(UT)102 +684 S(his mailer w)128.11 684 Q(ants UUCP-style \231From\232 lines with the ug\ +ly \231remote from <host>\232 on the end.)-.1 E 12.78(wT)102 700.2 S .565 +(he user must ha)128.11 700.2 R .865 -.15(ve a v)-.2 H .566 +(alid account on this machine, i.e., getpwnam must succeed.)-.1 F .566 +(If not, the)5.566 F(mail is bounced.)122 712.2 Q +(This is required to get \231.forw)5 E(ard\232 capability)-.1 E(.)-.65 E EP +%%Page: 37 32 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-37)452.9 60 Q/F1 10/Times-Roman@0 SF 7.5(x\207 This)102 96 R(mailer w) +2.5 E(ants a \231Full-Name:\232 header line.)-.1 E 12.78(XT)102 112.2 S .972 +(his mailer w)128.11 112.2 R .972 +(ant to use the hidden dot algorithm as speci\214ed in RFC821; basically)-.1 F +3.472(,a)-.65 G 1.272 -.15(ny l)475.678 112.2 T(ine).15 E(be)122 124.2 Q .796 +(ginning with a dot will ha)-.15 F 1.096 -.15(ve a)-.2 H 3.296(ne).15 G .797 +(xtra dot prepended \(to be stripped at the other end\).)267.742 124.2 R(This) +5.797 E(insures that lines in the message containing a dot will not terminate \ +the message prematurely)122 136.2 Q(.)-.65 E 15(5I)102 152.4 S 2.717(fn)125.33 +152.4 S 2.717(oa)136.377 152.4 S .217(liases are found for this address, pass \ +the address through ruleset 5 for possible alternate)148.534 152.4 R 2.5 +(resolution. This)122 164.4 R(is intended to forw)2.5 E +(ard the mail to an alternate deli)-.1 E -.15(ve)-.25 G(ry spot.).15 E 15(7S) +102 180.6 S 1.14(trip all output to se)127.56 180.6 R -.15(ve)-.25 G 3.64(nb) +.15 G 3.64(its. This)230.36 180.6 R 1.14(is the def)3.64 F 1.141(ault if the) +-.1 F F0(L)3.641 E F1 1.141(\215ag is set.)3.641 F 1.141 +(Note that clearing this)6.141 F .295(option is not suf)122 192.6 R .295 +(\214cient to get full eight bit data passed through)-.25 F/F2 10 +/Times-Italic@0 SF(sendmail)2.795 E F1 5.295(.I)C 2.795(ft)423.635 192.6 S(he) +432.54 192.6 Q F0(7)2.795 E F1 .295(option is set,)2.795 F .716 +(this is essentially al)122 204.6 R -.1(wa)-.1 G .717 +(ys set, since the eighth bit w).1 F .717(as stripped on input.)-.1 F .717 +(Note that this option)5.717 F(will only impact messages that didn')122 216.6 Q +2.5(th)-.18 G -2.25 -.2(av e)279.04 216.6 T(8)2.7 E/F3 10/Symbol SF<ae>A F1 2.5 +(7b)C(it MIME con)322.44 216.6 Q -.15(ve)-.4 G(rsions performed.).15 E 15(8I) +102 232.8 S 3.783(fs)125.33 232.8 S 1.283(et, it is acceptable to send eight b\ +it data to this mailer; the usual attempt to do 8)136.333 232.8 R F3<ae>A F1 +3.782(7b)C(it)498.44 232.8 Q(MIME con)122 244.8 Q -.15(ve)-.4 G +(rsions will be bypassed.).15 E 17.22(:C)102 261 S .982 +(heck addresses to see if the)128.67 261 R 3.482(yb)-.15 G -.15(eg)255.492 261 +S .982(in \231:include:\232; if the).15 F 3.482(yd)-.15 G .982(o, con)361.33 +261 R -.15(ve)-.4 G .982(rt them to the \231*include*\232).15 F(mailer)122 273 +Q(.)-.55 E 18(|C)102 289.2 S(heck addresses to see if the)128.67 289.2 Q 2.5 +(yb)-.15 G -.15(eg)249.6 289.2 S(in with a `|'; if the).15 E 2.5(yd)-.15 G +(o, con)343.51 289.2 Q -.15(ve)-.4 G(rt them to the \231prog\232 mailer).15 E +(.)-.55 E 17.22(/C)102 305.4 S(heck addresses to see if the)128.67 305.4 Q 2.5 +(yb)-.15 G -.15(eg)249.6 305.4 S(in with a `/'; if the).15 E 2.5(yd)-.15 G +(o, con)344.29 305.4 Q -.15(ve)-.4 G(rt them to the \231*\214le*\232 mailer).15 +E(.)-.55 E 10.79(@L)102 321.6 S(ook up addresses in the user database.)128.11 +321.6 Q .268(Con\214guration \214les prior to le)127 337.8 R -.15(ve)-.25 G +2.768(l6a).15 G .268(ssume the `)271.538 337.8 R -1.11(A')-.8 G 2.768(,`)1.11 G +.268(w', `5', `:', `|', `/', and `@' options on the)334.862 337.8 R +(mailer named \231local\232.)102 349.8 Q .306(The mailer with the special name\ + \231error\232 can be used to generate a user error)127 366 R 5.306(.T)-.55 G +.306(he \(optional\))452.314 366 R .324(host \214eld is an e)102 378 R .323 +(xit status to be returned, and the user \214eld is a message to be printed.) +-.15 F .323(The e)5.323 F .323(xit sta-)-.15 F .891 +(tus may be numeric or one of the v)102 390 R .891(alues USA)-.25 F .891 +(GE, NOUSER, NOHOST)-.4 F 3.391(,U)-.74 G -.35(NA)409.869 390 S -1.35(VA)-1 G +.891(ILABLE, SOFT)1.35 F(-)-.92 E -1.2(WA)102 402 S 1.573(RE, TEMPF)1.2 F 1.573 +(AIL, PR)-.74 F -1.88 -.4(OT O)-.4 H 1.573 +(COL, or CONFIG to return the corresponding EX_ e).4 F 1.572(xit code.)-.15 F +-.15(Fo)6.572 G(r).15 E -.15(ex)102 414 S(ample, the entry:).15 E +($#error $@ NOHOST $: Host unkno)142 430.2 Q(wn in this domain)-.25 E .145(on \ +the RHS of a rule will cause the speci\214ed error to be generated and the \ +\231Host unkno)102 446.4 R .146(wn\232 e)-.25 F .146(xit sta-)-.15 F +(tus to be returned if the LHS matches.)102 458.4 Q +(This mailer is only functional in rulesets zero or \214v)5 E(e.)-.15 E .468 +(The mailer named \231local\232)127 474.6 R F2(must)2.968 E F1 .468 +(be de\214ned in e)2.968 F -.15(ve)-.25 G .468(ry con\214guration \214le.).15 F +.468(This is used to deli)5.468 F -.15(ve)-.25 G(r).15 E .25 +(local mail, and is treated specially in se)102 486.6 R -.15(ve)-.25 G .25 +(ral w).15 F 2.75(ays. Additionally)-.1 F 2.75(,t)-.65 G .25 +(hree other mailers named \231prog\232,)369.43 486.6 R .942 +(\231*\214le*\232, and \231*include*\232 may be de\214ned to tune the deli)102 +498.6 R -.15(ve)-.25 G .942(ry of messages to programs, \214les, and).15 F +(:include: lists respecti)102 510.6 Q -.15(ve)-.25 G(ly).15 E 5(.T)-.65 G(he) +219 510.6 Q 2.5(yd)-.15 G(ef)240.79 510.6 Q(ault to:)-.1 E +(Mprog, P=/bin/sh, F=lsD, A=sh \255c $u)142 526.8 Q(M*\214le*, P=/de)142 538.8 +Q(v/null, F=lsDFMPEu, A=FILE)-.25 E(M*include*, P=/de)142 550.8 Q +(v/null, F=su, A=INCLUDE)-.25 E .615(The Sender and Recipient re)127 571.2 R +.615(writing sets may either be a simple ruleset id or may be tw)-.25 F 3.116 +(oi)-.1 G(ds)495.11 571.2 Q .576(separated by a slash; if so, the \214rst re) +102 583.2 R .575(writing set is applied to en)-.25 F -.15(ve)-.4 G .575 +(lope addresses and the second is).15 F(applied to headers.)102 595.2 Q .196 +(The Directory is actually a colon-separated path of directories to try)127 +611.4 R 5.197(.F)-.65 G .197(or e)413.019 611.4 R .197(xample, the de\214ni-) +-.15 F .104(tion \231D=$z:/\232 \214rst tries to e)102 623.4 R -.15(xe)-.15 G +.104(cute in the recipient').15 F 2.604(sh)-.55 G .104 +(ome directory; if that is not a)315.196 623.4 R -.25(va)-.2 G .103 +(ilable, it tries to).25 F -.15(exe)102 635.4 S .816 +(cute in the root of the \214lesystem.).15 F .816 +(This is intended to be used only on the \231prog\232 mailer)5.816 F 3.317(,s) +-.4 G(ince)487.34 635.4 Q .368(some shells \(such as)102 647.4 R F2(csh)2.868 E +F1 2.868(\)r)C .368(efuse to e)210.21 647.4 R -.15(xe)-.15 G .368(cute if the) +.15 F 2.868(yc)-.15 G .367(annot read the home directory)311.29 647.4 R 5.367 +(.S)-.65 G .367(ince the queue)445.506 647.4 R +(directory is not normally readable by unpri)102 659.4 Q(vile)-.25 E(ged users) +-.15 E F2(csh)2.5 E F1(scripts as recipients can f)2.5 E(ail.)-.1 E 1.862 +(The Userid speci\214es the def)127 675.6 R 1.863 +(ault user and group id to run as, o)-.1 F -.15(ve)-.15 G 1.863(rriding the).15 +F F0(DefaultUser)4.363 E F1 .287(option \(q.v)102 687.6 R 2.787(.\). If)-.65 F +(the)2.787 E F0(S)2.787 E F1 .287(mailer \215ag is also speci\214ed, this is t\ +he user and group to run as in all circum-)2.787 F 2.587(stances. This)102 +699.6 R .088(may be gi)2.587 F -.15(ve)-.25 G 2.588(na).15 G(s)219.518 699.6 Q +F2(user:gr)2.588 E(oup)-.45 E F1 .088 +(to set both the user and group id; either may be an inte)2.588 F(ger)-.15 E +.541(or a symbolic name to be look)102 711.6 R .541(ed up in the)-.1 F F2 +(passwd)3.041 E F1(and)3.041 E F2(gr)3.041 E(oup)-.45 E F1 .541 +(\214les respecti)3.041 F -.15(ve)-.25 G(ly).15 E 5.541(.I)-.65 G 3.041(fo) +432.657 711.6 S .541(nly a symbolic)444.028 711.6 R +(user name is speci\214ed, the group id in the)102 723.6 Q F2(passwd)2.5 E F1 +(\214le for that user is used as the group id.)2.5 E EP +%%Page: 38 33 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-38 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF .545 +(The Charset \214eld is used when con)127 96 R -.15(ve)-.4 G .545 +(rting a message to MIME; this is the character set used).15 F .466 +(in the Content-T)102 108 R .466(ype: header)-.8 F 5.466(.I)-.55 G 2.966(ft) +225.824 108 S .466(his is not set, the)234.9 108 R F0(DefaultCharset)2.966 E F1 +.465(option is used, and if that is not)2.965 F .257(set, the v)102 120 R .257 +(alue \231unkno)-.25 F .257(wn-8bit\232 is used.)-.25 F F0 -1.2(WA)5.257 G +(RNING:)1.2 E F1 .257(this \214eld applies to the sender')2.757 F 2.758(sm)-.55 +G(ailer)453.614 120 Q 2.758(,n)-.4 G .258(ot the)481.242 120 R(recipient')102 +132 Q 2.702(sm)-.55 G(ailer)154.142 132 Q 5.202(.F)-.55 G .202(or e)184.474 132 +R .202(xample, if the en)-.15 F -.15(ve)-.4 G .201 +(lope sender address lists an address on the local netw).15 F(ork)-.1 E .48 +(and the recipient is on an e)102 144 R .48(xternal netw)-.15 F .48 +(ork, the character set will be set from the Charset= \214eld for)-.1 F +(the local netw)102 156 Q(ork mailer)-.1 E 2.5(,n)-.4 G(ot that of the e)208.98 +156 Q(xternal netw)-.15 E(ork mailer)-.1 E(.)-.55 E .795(The T)127 172.2 R .795 +(ype= \214eld sets the type information used in MIME error messages as de\214n\ +ed by RFC)-.8 F .15(XXX \(not yet published\).)102 184.2 R .15 +(It is actually three v)5.15 F .151(alues separated by slashes: the MT)-.25 F +.151(A-type \(that is, the)-.93 F .36(description of ho)102 196.2 R 2.86(wh) +-.25 G .359(osts are named\), the address type \(the description of e-mail add\ +resses\), and the)185.32 196.2 R .221 +(diagnostic type \(the description of error diagnostic codes\).)102 208.2 R +.222(Each of these must be a re)5.221 F .222(gistered v)-.15 F(alue)-.25 E +(or be)102 220.2 Q(gin with \231X\255\232.)-.15 E(The def)5 E +(ault is \231dns/rfc822/smtp\232.)-.1 E F0 2.5(5.5. H)87 244.2 R 2.5<8a44>2.5 G +(e\214ne Header)137 244.2 Q F1 1.136(The format of the header lines that)127 +260.4 R/F2 10/Times-Italic@0 SF(sendmail)3.636 E F1 1.135 +(inserts into the message are de\214ned by the)3.636 F F0(H)3.635 E F1 2.5 +(line. The)102 272.4 R(syntax of this line is:)2.5 E F0(H)142 288.6 Q F1([)A F0 +(?)A F2(m\215a)A(gs)-.1 E F0(?)A F1(])A F2(hname)A F0(:)A F2(htemplate)2.5 E F1 +1.058(Continuation lines in this spec are re\215ected directly into the outgoi\ +ng message.)102 304.8 R(The)6.058 E F2(htemplate)3.558 E F1(is)3.558 E 1.098 +(macro e)102 316.8 R 1.098(xpanded before insertion into the message.)-.15 F +1.098(If the)6.098 F F2(m\215a)3.598 E(gs)-.1 E F1 1.097 +(\(surrounded by question marks\))3.597 F .161(are speci\214ed, at least one o\ +f the speci\214ed \215ags must be stated in the mailer de\214nition for this h\ +eader)102 328.8 R .192(to be automatically output.)102 340.8 R .191 +(If one of these headers is in the input it is re\215ected to the output re) +5.192 F -.05(ga)-.15 G(rd-).05 E(less of these \215ags.)102 352.8 Q +(Some headers ha)127 369 Q .3 -.15(ve s)-.2 H +(pecial semantics that will be described later).15 E(.)-.55 E F0 2.5(5.6. O)87 +393 R 2.5<8a53>2.5 G(et Option)135.34 393 Q F1 .962(There are a number of glob\ +al options that can be set from a con\214guration \214le.)127 409.2 R .963 +(Options are)5.963 F .86(represented by full w)102 421.2 R .86 +(ords; some are also representable as single characters for back compatibility) +-.1 F(.)-.65 E(The syntax of this line is:)102 433.2 Q F0(O)142 449.4 Q F2 +(option)7.5 E F0(=)A F2(value)A F1 .562(This sets option)102 465.6 R F2(option) +3.062 E F1 .562(to be)3.062 F F2(value)3.062 E F1 5.562(.N)C .562 +(ote that there)258.434 465.6 R F2(must)3.062 E F1 .562 +(be a space between the letter `O' and the)3.062 F(name of the option.)102 +477.6 Q(An older v)5 E(ersion is:)-.15 E F0(O)142 493.8 Q F2 1.666(ov)C(alue) +-1.666 E F1 .13(where the option)102 510 R F2(o)2.63 E F1 .13 +(is a single character)2.63 F 5.13(.D)-.55 G .13(epending on the option,)273.56 +510 R F2(value)2.63 E F1 .13(may be a string, an inte)2.63 F(ger)-.15 E(,)-.4 E +2.5(ab)102 522 S(oolean \(with le)113.94 522 Q -.05(ga)-.15 G 2.5(lv).05 G +(alues \231t\232, \231T\232, \231f\232, or \231F\232; the def)193.2 522 Q +(ault is TR)-.1 E(UE\), or a time interv)-.4 E(al.)-.25 E +(The options supported \(with the old, one character names in brack)127 538.2 Q +(ets\) are:)-.1 E(AliasFile=)102 554.4 Q F2(spec, spec, ...)A F1 .439 +([A] Specify possible alias \214le\(s\).)174 566.4 R(Each)5.439 E F2(spec)2.939 +E F1 .439(should be in the format `)2.939 F(`)-.74 E F2(class)A F0(:)A F2 +(\214le)2.94 E F1 -.74('')C(where)174 578.4 Q F2(class)3.1 E F0(:)A F1 .599 +(is optional and def)3.099 F .599(aults to `)-.1 F(`implicit')-.74 E 3.099 +('. Depending)-.74 F .599(on ho)3.099 F(w)-.25 E F2(sendmail)3.099 E F1 .186 +(is compiled, v)174 590.4 R .187(alid classes are \231implicit\232 \(search th\ +rough a compiled-in list of alias)-.25 F 2.055 +(\214le types, for back compatibility\), \231hash\232 \(if)174 602.4 R/F3 9 +/Times-Roman@0 SF(NEWDB)4.555 E F1 2.055(is speci\214ed\), \231dbm\232 \(if) +4.555 F F3(NDBM)174 614.4 Q F1 1.588(is speci\214ed\), \231stab\232 \(internal\ + symbol table \212 not normally used unless)4.088 F .075(you ha)174 626.4 R +.375 -.15(ve n)-.2 H 2.575(oo).15 G .075 +(ther database lookup\), or \231nis\232 \(if)230.255 626.4 R F3(NIS)2.574 E F1 +.074(is speci\214ed\).)2.574 F .074(If a list of)5.074 F F2(spec)2.574 E F1(s)A +(are pro)174 638.4 Q(vided,)-.15 E F2(sendmail)2.5 E F1(searches them in order) +2.5 E(.)-.55 E(AliasW)102 654.6 Q(ait=)-.8 E F2(timeout)A F1 .14([a] If set, w) +174 666.6 R .14(ait up to)-.1 F F2(timeout)2.64 E F1 .141(\(units def)2.641 F +.141(ault to minutes\) for an \231@:@\232 entry to e)-.1 F(xist)-.15 E .518 +(in the alias database before starting up.)174 678.6 R .517 +(If it does not appear in the)5.517 F F2(timeout)3.017 E F1(inter)3.017 E(-)-.2 +E -.25(va)174 690.6 S 3.21(lr).25 G(eb)192.51 690.6 Q .71 +(uild the database \(if the)-.2 F F0 -.5(Au)3.21 G(toReb).5 E(uildAliases)-.2 E +F1 .71(option is also set\) or issue a)3.21 F -.1(wa)174 702.6 S(rning.).1 E EP +%%Page: 39 34 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-39)452.9 60 Q/F1 10/Times-Roman@0 SF(AutoReb)102 96 Q(uildAliases)-.2 E +.128([D] If set, reb)174 108 R .128 +(uild the alias database if necessary and possible.)-.2 F .128 +(If this option is not)5.128 F(set,)174 120 Q/F2 10/Times-Italic@0 SF(sendmail) +4.885 E F1 2.385(will ne)4.885 F -.15(ve)-.25 G 4.885(rr).15 G(eb)283.96 120 Q +2.385(uild the alias database unless e)-.2 F 2.385(xplicitly requested)-.15 F +(using)174 132 Q F0(\255bi)2.5 E F1 5(.N)C +(ot recommended \212 can cause thrashing.)226.93 132 Q(BlankSub=)102 148.2 Q F2 +(c)A F1 1.255([B] Set the blank substitution character to)174 148.2 R F2(c) +3.755 E F1 6.255(.U)C 1.255(nquoted spaces in addresses are)372.35 148.2 R +(replaced by this character)174 160.2 Q 5(.D)-.55 G(ef)290.63 160.2 Q +(aults to space \(i.e., no change is made\).)-.1 E 14.51(CheckAliases [n])102 +176.4 R -1.11(Va)2.5 G(lidate the RHS of aliases when reb)1.11 E +(uilding the alias database.)-.2 E(CheckpointInterv)102 192.6 Q(al=)-.25 E F2 +(N)A F1 1.296([C] Checkpoints the queue e)174 204.6 R -.15(ve)-.25 G(ry).15 E +F2(N)3.797 E F1(\(def)3.797 E 1.297(ault 10\) addresses sent.)-.1 F 1.297 +(If your system)6.297 F .747(crashes during deli)174 216.6 R -.15(ve)-.25 G +.746(ry to a lar).15 F .746(ge list, this pre)-.18 F -.15(ve)-.25 G .746 +(nts retransmission to an).15 F 3.246(yb)-.15 G .746(ut the)480.754 216.6 R +(last recipients.)174 228.6 Q(ClassF)102 244.8 Q(actor=)-.15 E F2(fact)A F1 +1.624([z] The indicated)4.29 F F2(fact)4.124 E F1 1.624 +(or is multiplied by the message class \(determined by the)B .719 +(Precedence: \214eld in the user header and the)174 256.8 R F0(P)3.219 E F1 +.718(lines in the con\214guration \214le\) and)3.218 F 2.637 +(subtracted from the priority)174 268.8 R 7.637(.T)-.65 G 2.637 +(hus, messages with a higher Priority: will be)307.768 268.8 R -.1(fa)174 280.8 +S -.2(vo)-.1 G 2.5(red. Def).2 F(aults to 1800.)-.1 E 3.95(ColonOkInAddr [no) +102 297 R 4.679 +(short name] If set, colons are acceptable in e-mail addresses \(e.g.,)7.18 F +3.54(\231host:user\232\). If)174 309 R 1.04(not set, colons indicate the be) +3.54 F 1.04(ginning of a RFC 822 group con-)-.15 F 1.988 +(struct \(\231groupname: member1, member2, ... memberN;\232\).)174 321 R 1.987 +(Doubled colons are)6.987 F(al)174 333 Q -.1(wa)-.1 G 2.215(ys acceptable \(\ +\231nodename::user\232\) and proper route-addr nesting is under).1 F(-)-.2 E +1.037(stood \(\231<@relay:user@host>\232\).)174 345 R 1.037 +(Furthermore, this option def)6.037 F 1.036(aults on if the con-)-.1 F .853 +(\214guration v)174 357 R .853(ersion le)-.15 F -.15(ve)-.25 G 3.353(li).15 G +3.353(sl)274.059 357 S .853(ess than 6 \(for back compatibility\).)284.082 357 +R(Ho)5.854 E(we)-.25 E -.15(ve)-.25 G 1.654 -.4(r, i).15 H 3.354(tm).4 G(ust) +492.33 357 Q(be of)174 369 Q 2.5(ff)-.25 G(or full compatibility with RFC 822.) +203.18 369 Q(ConnectionCacheSize=)102 385.2 Q F2(N)A F1 .242 +([k] The maximum number of open connections that will be cached at a time.)174 +397.2 R(The)5.242 E(def)174 409.2 Q .385(ault is one.)-.1 F .386 +(This delays closing the current connection until either this in)5.386 F -.2 +(vo)-.4 G(ca-).2 E 1.192(tion of)174 421.2 R F2(sendmail)3.692 E F1 1.191 +(needs to connect to another host or it terminates.)3.692 F 1.191 +(Setting it to)6.191 F 2.046(zero def)174 433.2 R 2.046(aults to the old beha) +-.1 F(vior)-.2 E 4.546(,t)-.4 G 2.047 +(hat is, connections are closed immediately)322.496 433.2 R(.)-.65 E .266 +(Since this consumes \214le descriptors, the connection cache should be k)174 +445.2 R .265(ept small: 4)-.1 F(is probably a practical maximum.)174 457.2 Q +(ConnectionCacheT)102 473.4 Q(imeout=)-.35 E F2(timeout)A F1 .708 +([K] The maximum amount of time a cached connection will be permitted to idle) +174 485.4 R 1.083(without acti)174 497.4 R(vity)-.25 E 6.083(.I)-.65 G 3.583 +(ft)249.156 497.4 S 1.083(his time is e)258.849 497.4 R 1.082 +(xceeded, the connection is immediately closed.)-.15 F .417(This v)174 509.4 R +.418(alue should be small \(on the order of ten minutes\).)-.25 F(Before)5.418 +E F2(sendmail)2.918 E F1 .418(uses a)2.918 F .508(cached connection, it al)174 +521.4 R -.1(wa)-.1 G .507(ys sends a RSET command to check the connection; if) +.1 F .401(this f)174 533.4 R .401(ails, it reopens the connection.)-.1 F .401 +(This k)5.401 F .402(eeps your end from f)-.1 F .402(ailing if the other)-.1 F +1.545(end times out.)174 545.4 R 1.545 +(The point of this option is to be a good netw)6.545 F 1.544(ork neighbor and) +-.1 F -.2(avo)174 557.4 S(id using up e).2 E(xcessi)-.15 E .3 -.15(ve r)-.25 H +(esources on the other end.).15 E(The def)5 E(ault is \214v)-.1 E 2.5(em)-.15 G +(inutes.)470.25 557.4 Q(DaemonPortOptions=)102 573.6 Q F2(options)A F1 +([O] Set serv)174 585.6 Q(er SMTP options.)-.15 E(The options are)5 E F2 -.1 +(ke)2.5 G(y=value)-.2 E F1 2.5(pairs. Kno)2.5 F(wn k)-.25 E -.15(ey)-.1 G 2.5 +(sa).15 G(re:)490.2 585.6 Q 52.83(Port Name/number)214 601.8 R +(of listening port \(def)2.5 E(aults to "smtp"\))-.1 E 48.95(Addr Address)214 +613.8 R(mask \(def)2.5 E(aults IN)-.1 E(ADDR_ANY\))-.35 E -.15(Fa)214 625.8 S +41.31(mily Address).15 F -.1(fa)2.5 G(mily \(def).1 E(aults to INET\))-.1 E +44.5(Listen Size)214 637.8 R(of listen queue \(def)2.5 E(aults to 10\))-.1 E +21.72(SndBufSize Size)214 649.8 R(of TCP send b)2.5 E(uf)-.2 E(fer)-.25 E 21.17 +(RcvBufSize Size)214 661.8 R(of TCP recei)2.5 E .3 -.15(ve b)-.25 H(uf)-.05 E +(fer)-.25 E(The)174 678 Q F2(Addr)2.5 E F1 +(ess mask may be a numeric address in dot notation or a netw)A(ork name.)-.1 E +(Def)102 694.2 Q(aultCharSet=)-.1 E F2 -.15(ch)C(ar).15 E(set)-.1 E F1 .16 +([no short name] When a message that has 8-bit characters b)174 706.2 R .161 +(ut is not in MIME for)-.2 F(-)-.2 E .495(mat is con)174 718.2 R -.15(ve)-.4 G +.495(rted to MIME \(see the EightBitMode option\) a character set must be).15 F +EP +%%Page: 40 35 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-40 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF .487 +(included in the Content-T)174 96 R .487(ype: header)-.8 F 5.487(.T)-.55 G .488 +(his character set is normally set from the)338.115 96 R .133 +(Charset= \214eld of the mailer descriptor)174 108 R 5.133(.I)-.55 G 2.633(ft) +337.64 108 S .133(hat is not set, the v)346.383 108 R .133 +(alue of this option is)-.25 F 2.5(used. If)174 120 R +(this option is not set, the v)2.5 E(alue \231unkno)-.25 E +(wn-8bit\232 is used.)-.25 E(Def)102 136.2 Q(aultUser=)-.1 E/F2 10 +/Times-Italic@0 SF(user:gr)A(oup)-.45 E F1 .013([u] Set the def)174 148.2 R +.013(ault userid for mailers to)-.1 F F2(user:gr)2.513 E(oup)-.45 E F1 5.013 +(.I)C(f)386.587 148.2 Q F2(gr)2.513 E(oup)-.45 E F1 .014(is omitted and)2.514 F +F2(user)2.514 E F1(is)2.514 E 4.307(au)174 160.2 S 1.807 +(ser name \(as opposed to a numeric user id\) the def)187.747 160.2 R 1.806 +(ault group listed in the)-.1 F 1.153 +(/etc/passwd \214le for that user is used as the def)174 172.2 R 1.153 +(ault group.)-.1 F(Both)6.153 E F2(user)3.653 E F1(and)3.653 E F2(gr)3.653 E +(oup)-.45 E F1 1.153(may be numeric.)174 184.2 R 1.152(Mailers without the) +6.152 F F2(S)3.652 E F1 1.152(\215ag in the mailer de\214nition will run as) +3.652 F .142(this user)174 198.2 R 5.142(.D)-.55 G(ef)222.064 198.2 Q .142 +(aults to 1:1.)-.1 F .142(The v)5.142 F .142(alue can also be gi)-.25 F -.15 +(ve)-.25 G 2.642(na).15 G 2.642(sas)400.612 198.2 S .142(ymbolic user name.) +418.116 198.2 R/F3 7/Times-Roman@0 SF(18)497 194.2 Q F1(Deli)102 214.4 Q -.15 +(ve)-.25 G(ryMode=).15 E F2(x)A F1([d] Deli)4 E -.15(ve)-.25 G 2.5(ri).15 G 2.5 +(nm)223.03 214.4 S(ode)238.31 214.4 Q F2(x)2.5 E F1 5(.L)C -2.25 -.15(eg a) +273.3 214.4 T 2.5(lm).15 G(odes are:)300.04 214.4 Q 17.22(iD)214 230.6 S(eli) +241.22 230.6 Q -.15(ve)-.25 G 2.5(ri).15 G(nteracti)268.87 230.6 Q -.15(ve)-.25 +G(ly \(synchronously\)).15 E 15(bD)214 242.6 S(eli)241.22 242.6 Q -.15(ve)-.25 +G 2.5(ri).15 G 2.5(nb)268.87 242.6 S(ackground \(asynchronously\))281.37 242.6 +Q 15(qJ)214 254.6 S(ust queue the message \(deli)237.89 254.6 Q -.15(ve)-.25 G +2.5(rd).15 G(uring queue run\))367.74 254.6 Q 15(dD)214 266.6 S(efer deli) +241.22 266.6 Q -.15(ve)-.25 G(ry and all map lookups \(deli).15 E -.15(ve)-.25 +G 2.5(rd).15 G(uring queue run\))415.66 266.6 Q(Def)174 282.8 Q .712 +(aults to `)-.1 F(`b')-.74 E 3.212('i)-.74 G 3.212(fn)244.816 282.8 S 3.211(oo) +256.358 282.8 S .711(ption is speci\214ed, `)269.569 282.8 R(`i')-.74 E 3.211 +('i)-.74 G 3.211(fi)365.093 282.8 S 3.211(ti)374.414 282.8 S 3.211(ss)383.185 +282.8 S .711(peci\214ed b)394.176 282.8 R .711(ut gi)-.2 F -.15(ve)-.25 G 3.211 +(nn).15 G 3.211(oa)474.869 282.8 S -.18(rg)487.52 282.8 S(u-).18 E .094 +(ment \(i.e., `)174 294.8 R(`Od')-.74 E 2.594('i)-.74 G 2.594(se)246.672 294.8 +S(qui)257.596 294.8 Q -.25(va)-.25 G .094(lent to `).25 F(`Odi')-.74 E 2.594 +('\). The)-.74 F F0<ad76>2.594 E F1 .094(command line \215ag sets this to)2.594 +F F0(i)2.594 E F1(.)A(DialDelay=)102 311 Q F2(sleeptime)A F1 .799 +([no short name] Dial-on-demand netw)174 323 R .798 +(ork connections can see timeouts if a con-)-.1 F .665 +(nection is opened before the call is set up.)174 335 R .665 +(If this is set to an interv)5.665 F .665(al and a con-)-.25 F .743 +(nection times out on the \214rst connection being attempted)174 347 R F2 +(sendmail)3.242 E F1 .742(will sleep for)3.242 F .31 +(this amount of time and try ag)174 359 R 2.81(ain. This)-.05 F .31(should gi) +2.81 F .61 -.15(ve y)-.25 H .31(our system time to establish).15 F 1.543 +(the connection to your service pro)174 371 R(vider)-.15 E 6.543(.U)-.55 G +1.543(nits def)354.188 371 R 1.542(ault to seconds, so \231DialDe-)-.1 F +(lay=5\232 uses a \214v)174 383 Q 2.5(es)-.15 G(econd delay)251.7 383 Q 5(.D) +-.65 G(ef)313.81 383 Q(aults to zero \(no retry\).)-.1 E(DontExpandCnames)102 +399.2 Q .559([no short name] The standards say that all host addresses used in\ + a mail message)174 411.2 R 1.408(must be fully canonical.)174 423.2 R -.15(Fo) +6.407 G 3.907(re).15 G 1.407(xample, if your host is named \231Cruft.F)302.668 +423.2 R(oo.ORG\232)-.15 E 1.462(and also has an alias of \231FTP)174 435.2 R +(.F)-1.11 E 1.462(oo.ORG\232, the former name must be used at all)-.15 F 2.631 +(times. This)174 447.2 R .131 +(is enforced during host name canoni\214cation \($[ ... $] lookups\).)2.631 F +.13(If this)5.13 F .661 +(option is set, the protocols are ignored and the \231wrong\232 thing is done.) +174 459.2 R(Ho)5.662 E(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G .455 +(the IETF is mo)174 471.2 R .455(ving to)-.15 F -.1(wa)-.25 G .455 +(rd changing this standard, so the beha).1 F .455(viour may become)-.2 F 3.009 +(acceptable. Please)174 483.2 R .509(note that hosts do)3.009 F .509 +(wnstream may still re)-.25 F .509(write the address to be)-.25 F +(the true canonical name ho)174 495.2 Q(we)-.25 E -.15(ve)-.25 G -.55(r.).15 G +6.17(DontInitGroups [no)102 511.4 R .25(short name] If set,)2.75 F F2(sendmail) +2.75 E F1 .25(will a)2.75 F -.2(vo)-.2 G .25 +(id using the initgroups\(3\) call.).2 F .25(If you are)5.25 F .583(running NI\ +S, this causes a sequential scan of the groups.byname map, which can)174 523.4 +R .436(cause your NIS serv)174 535.4 R .436(er to be badly o)-.15 F -.15(ve) +-.15 G .435(rloaded in a lar).15 F .435(ge domain.)-.18 F .435 +(The cost of this)5.435 F .697(is that the only group found for users will be \ +their primary group \(the one in the)174 547.4 R(passw)174 559.4 Q 1.189 +(ord \214le\), which will mak)-.1 F 3.689<658c>-.1 G 1.189 +(le access permissions some)315.845 559.4 R 1.189(what more restric-)-.25 F(ti) +174 571.4 Q -.15(ve)-.25 G 5(.H).15 G(as no ef)203.32 571.4 Q +(fect on systems that don')-.25 E 2.5(th)-.18 G -2.25 -.2(av e)344.26 571.4 T +(group lists.)2.7 E -1.61(DontPruneRoutes [R])102 587.6 R(Normally)3.905 E(,) +-.65 E F2(sendmail)3.905 E F1 1.405(tries to eliminate an)3.905 F 3.905(yu)-.15 +G 1.405(nnecessary e)372.465 587.6 R 1.405(xplicit routes when)-.15 F .155 +(sending an error message \(as discussed in RFC 1123 \247 5.2.6\).)174 599.6 R +-.15(Fo)5.154 G 2.654(re).15 G .154(xample, when)447.746 599.6 R +(sending an error message to)174 611.6 Q(<@kno)214 627.8 Q(wn1,@kno)-.25 E +(wn2,@kno)-.25 E(wn3:user@unkno)-.25 E(wn>)-.25 E F2(sendmail)174 644 Q F1 +1.155(will strip of)3.655 F 3.655(ft)-.25 G 1.155(he \231@kno)272.26 644 R +(wn1,@kno)-.25 E 1.155(wn2\232 in order to mak)-.25 F 3.655(et)-.1 G 1.155 +(he route as)458.37 644 R .813(direct as possible.)174 656 R(Ho)5.813 E(we)-.25 +E -.15(ve)-.25 G 1.613 -.4(r, i).15 H 3.313(ft).4 G(he)306.435 656 Q F0(R)3.313 +E F1 .812(option is set, this will be disabled, and the)3.313 F .009 +(mail will be sent to the \214rst address in the route, e)174 668 R -.15(ve) +-.25 G 2.51(ni).15 G 2.51(fl)392.86 668 S .01(ater addresses are kno)401.48 668 +R(wn.)-.25 E(This may be useful if you are caught behind a \214re)174 680 Q -.1 +(wa)-.25 G(ll.).1 E .32 LW 76 689.6 72 689.6 DL 80 689.6 76 689.6 DL 84 689.6 +80 689.6 DL 88 689.6 84 689.6 DL 92 689.6 88 689.6 DL 96 689.6 92 689.6 DL 100 +689.6 96 689.6 DL 104 689.6 100 689.6 DL 108 689.6 104 689.6 DL 112 689.6 108 +689.6 DL 116 689.6 112 689.6 DL 120 689.6 116 689.6 DL 124 689.6 120 689.6 DL +128 689.6 124 689.6 DL 132 689.6 128 689.6 DL 136 689.6 132 689.6 DL 140 689.6 +136 689.6 DL 144 689.6 140 689.6 DL 148 689.6 144 689.6 DL 152 689.6 148 689.6 +DL 156 689.6 152 689.6 DL 160 689.6 156 689.6 DL 164 689.6 160 689.6 DL 168 +689.6 164 689.6 DL 172 689.6 168 689.6 DL 176 689.6 172 689.6 DL 180 689.6 176 +689.6 DL 184 689.6 180 689.6 DL 188 689.6 184 689.6 DL 192 689.6 188 689.6 DL +196 689.6 192 689.6 DL 200 689.6 196 689.6 DL 204 689.6 200 689.6 DL 208 689.6 +204 689.6 DL 212 689.6 208 689.6 DL 216 689.6 212 689.6 DL/F4 5/Times-Roman@0 +SF(18)93.6 700 Q/F5 8/Times-Roman@0 SF(The old)3.2 I/F6 8/Times-Bold@0 SF(g)2 E +F5(option has been combined into the)2 E F6(DefaultUser)2 E F5(option.)2 E EP +%%Page: 41 36 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-41)452.9 60 Q/F1 10/Times-Roman@0 SF(EightBitMode=)102 96 Q/F2 10 +/Times-Italic@0 SF(action)A F1 1.956([8] Set handling of eight-bit data.)174 +108 R 1.955(There are tw)6.955 F 4.455(ok)-.1 G 1.955 +(inds of eight-bit data: that)392.85 108 R 3.334(declared as such using the)174 +120 R F0(BOD)5.834 E(Y=8BITMIME)-.4 E F1 3.335(ESMTP declaration or the)5.835 F +F0(\255B8BITMIME)174 132 Q F1 .948 +(command line \215ag, and undeclared 8-bit data, that is, input that)3.449 F +1.18(just happens to be eight bits.)174 144 R 1.18 +(There are three basic operations that can happen:)6.18 F .996 +(undeclared 8-bit data can be automatically con)174 156 R -.15(ve)-.4 G .995 +(rted to 8BITMIME, undeclared).15 F .887 +(8-bit data can be passed as-is without con)174 168 R -.15(ve)-.4 G .887 +(rsion to MIME \(`).15 F .887(`just send 8')-.74 F .887('\), and)-.74 F 5.989 +(declared 8-bit data can be con)174 180 R -.15(ve)-.4 G 5.989 +(rted to 7-bits for transmission to a).15 F(non-8BITMIME mailer)174 192 Q 5(.T) +-.55 G(he possible)281.77 192 Q F2(action)2.5 E F1 2.5(sa)C(re:)364.82 192 Q +11.11(sR)219 208.2 S(eject undeclared 8-bit data \(`)240.67 208.2 Q(`strict') +-.74 E('\))-.74 E 7.22(mC)219 220.2 S(on)240.67 220.2 Q -.15(ve)-.4 G +(rt undeclared 8-bit data to MIME \(`).15 E(`mime')-.74 E('\))-.74 E 10(pP)219 +232.2 S(ass undeclared 8-bit data \(`)239.41 232.2 Q(`pass')-.74 E('\))-.74 E +2.227(In all cases properly declared 8BITMIME data will be con)174 248.4 R -.15 +(ve)-.4 G 2.228(rted to 7BIT as).15 F(needed.)174 260.4 Q(ErrorHeader=)102 +276.6 Q F2(\214le-or)A(-messa)-.2 E -.1(ge)-.1 G F1 .486 +([E] Prepend error messages with the indicated message.)174 288.6 R .486 +(If it be)5.486 F .486(gins with a slash,)-.15 F .246(it is assumed to be the \ +pathname of a \214le containing a message \(this is the recom-)174 300.6 R .86 +(mended setting\).)174 312.6 R .86(Otherwise, it is a literal message.)5.86 F +.86(The error \214le might contain)5.86 F 1.116 +(the name, email address, and/or phone number of a local postmaster who could) +174 324.6 R(pro)174 336.6 Q .174(vide assistance in to end users.)-.15 F .173 +(If the option is missing or null, or if it names a)5.174 F +(\214le which does not e)174 348.6 Q +(xist or which is not readable, no message is printed.)-.15 E(ErrorMode=)102 +364.8 Q F2(x)A F1([e] Dispose of errors using mode)174 364.8 Q F2(x)2.5 E F1 5 +(.T)C(he v)325.91 364.8 Q(alues for)-.25 E F2(x)2.5 E F1(are:)2.5 E 15(pP)214 +381 S(rint error messages \(def)239.56 381 Q(ault\))-.1 E 15(qN)214 393 S 2.5 +(om)241.22 393 S(essages, just gi)256.5 393 Q .3 -.15(ve ex)-.25 H(it status) +.15 E 12.22(mM)214 405 S(ail back errors)242.89 405 Q 12.78(wW)214 417 S +(rite back errors \(mail if user not logged in\))243.44 417 Q 15.56(eM)214 429 +S(ail back errors and gi)242.89 429 Q .3 -.15(ve z)-.25 H(ero e).15 E +(xit stat al)-.15 E -.1(wa)-.1 G(ys).1 E -.15(Fa)102 449.4 S(llbackMXhost=).15 +E F2(fallbac)A(khost)-.2 E F1 .796([V] If speci\214ed, the)174 461.4 R F2 +(fallbac)3.296 E(khost)-.2 E F1 .796(acts lik)3.296 F 3.296(eav)-.1 G .797 +(ery lo)359.608 461.4 R 3.297(wp)-.25 G .797(riority MX on e)398.722 461.4 R +-.15(ve)-.25 G .797(ry host.).15 F +(This is intended to be used by sites with poor netw)174 473.4 Q(ork connecti) +-.1 E(vity)-.25 E(.)-.65 E -.15(Fo)102 489.6 S 16.88(rkEachJob [Y]).15 F .708 +(If set, deli)3.208 F -.15(ve)-.25 G 3.208(re).15 G .707 +(ach job that is run from the queue in a separate process.)252.792 489.6 R(Use) +5.707 E .274(this option if you are short of memory)174 501.6 R 2.774(,s)-.65 G +.274(ince the def)336.922 501.6 R .275(ault tends to consume consid-)-.1 F +(erable amounts of memory while the queue is being processed.)174 513.6 Q -.15 +(Fo)102 529.8 S(rw).15 E(ardP)-.1 E(ath=)-.15 E F2(path)A F1 4.675 +([J] Set the path for searching for users' .forw)174 541.8 R 4.675 +(ard \214les.)-.1 F 4.675(The def)9.675 F 4.675(ault is)-.1 F(\231$z/.forw)174 +553.8 Q 3.23(ard\232. Some)-.1 F .731 +(sites that use the automounter may prefer to change this to)3.23 F(\231/v)174 +565.8 Q(ar/forw)-.25 E 1.696 +(ard/$u\232 to search a \214le with the same name as the user in a system)-.1 F +(directory)174 577.8 Q 5.487(.I)-.65 G 2.987(tc)220.767 577.8 S .488 +(an also be set to a sequence of paths separated by colons;)230.974 577.8 R F2 +(sendmail)2.988 E F1 4.218 +(stops at the \214rst \214le it can successfully and safely open.)174 589.8 R +-.15(Fo)9.217 G 6.717(re).15 G(xample,)472.06 589.8 Q(\231/v)174 601.8 Q +(ar/forw)-.25 E(ard/$u:$z/.forw)-.1 E .681(ard\232 will search \214rst in /v) +-.1 F(ar/forw)-.25 E(ard/)-.1 E F2(username)A F1 .682(and then)3.182 F(in)174 +613.8 Q F2(~username)2.5 E F1(/.forw)A(ard \(b)-.1 E +(ut only if the \214rst \214le does not e)-.2 E(xist\).)-.15 E(HelpFile=)102 +630 Q F2(\214le)A F1([H] Specify the help \214le for SMTP)174 630 Q(.)-1.11 E +(HoldExpensi)102 646.2 Q 8.54 -.15(ve [)-.25 H 1.394 +(c] If an outgoing mailer is mark).15 F 1.393(ed as being e)-.1 F(xpensi)-.15 E +-.15(ve)-.25 G 3.893(,d).15 G(on')415.294 646.2 Q 3.893(tc)-.18 G 1.393 +(onnect immedi-)439.557 646.2 R(ately)174 658.2 Q 5.267(.T)-.65 G .268 +(his requires that queueing be compiled in, since it will depend on a queue) +206.667 658.2 R(run process to actually send the mail.)174 670.2 Q 24.51 +(IgnoreDots [i])102 686.4 R 1.172(Ignore dots in incoming messages.)3.672 F +1.172(This is al)6.172 F -.1(wa)-.1 G 1.171(ys disabled \(that is, dots are).1 +F(al)174 698.4 Q -.1(wa)-.1 G(ys accepted\) when reading SMTP mail.).1 E EP +%%Page: 42 37 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-42 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(LogLe)102 96 Q +-.15(ve)-.25 G(l=).15 E/F2 10/Times-Italic@0 SF(n)A F1([L] Set the def)174 96 Q +(ault log le)-.1 E -.15(ve)-.25 G 2.5(lt).15 G(o)289.04 96 Q F2(n)2.5 E F1 5 +(.D)C(ef)316.26 96 Q(aults to 9.)-.1 E(M)102 112.2 Q F2 1.666(xv)C(alue)-1.666 +E F1 .255([no long v)174 112.2 R .255(ersion] Set the macro)-.15 F F2(x)2.755 E +F1(to)2.755 E F2(value)2.755 E F1 5.255(.T)C .255 +(his is intended only for use from the)357.505 112.2 R(command line.)174 124.2 +Q(The)5 E F0<ad4d>2.5 E F1(\215ag is preferred.)2.5 E 11.17(MatchGECOS [G])102 +140.4 R(Allo)3.334 E 3.334(wf)-.25 G .834(uzzy matching on the GECOS \214eld.) +222.628 140.4 R .833(If this \215ag is set, and the usual)5.833 F .867 +(user name lookups f)174 152.4 R .867 +(ail \(that is, there is no alias with this name and a)-.1 F F2 -.1(ge)3.368 G +(tpwnam).1 E F1 -.1(fa)174 164.4 S 1.155(ils\), sequentially search the passw) +.1 F 1.155(ord \214le for a matching entry in the GECOS)-.1 F 3.696 +(\214eld. This)174 176.4 R 1.196(also requires that MA)3.696 F 1.196 +(TCHGECOS be turned on during compilation.)-1.11 F +(This option is not recommended.)174 188.4 Q(MaxHopCount=)102 204.6 Q F2(N)A F1 +1.238([h] The maximum hop count.)174 216.6 R 1.238(Messages that ha)6.238 F +1.537 -.15(ve b)-.2 H 1.237(een processed more than).15 F F2(N)3.737 E F1 +(times are assumed to be in a loop and are rejected.)174 228.6 Q(Def)5 E +(aults to 25.)-.1 E(MaxHostStatAge=)102 244.8 Q F2 -.1(age)C F1 .438 +([no short name] Not yet implemented.)174 256.8 R .438 +(This option speci\214es ho)5.438 F 2.939(wl)-.25 G .439(ong host status) +443.672 256.8 R .36(information will be retained.)174 268.8 R -.15(Fo)5.36 G +2.86(re).15 G .36(xample, if a host is found to be do)315.76 268.8 R .36 +(wn, connec-)-.25 F .246 +(tions to that host will not be retried for this interv)174 280.8 R 2.746 +(al. The)-.25 F .246(units def)2.746 F .246(ault to minutes.)-.1 F +(MaxQueueRunSize=)102 297 Q F2(N)A F1 .677 +([no short name] The maximum number of jobs that will be processed in a single) +174 309 R .501(queue run.)174 321 R .501 +(If not set, there is no limit on the size.)5.501 F .501(If you ha)5.501 F .802 +-.15(ve ve)-.2 H .502(ry lar).15 F .502(ge queues)-.18 F .445(or a v)174 333 R +.445(ery short queue run interv)-.15 F .445(al this could be unstable.)-.25 F +(Ho)5.445 E(we)-.25 E -.15(ve)-.25 G 1.245 -.4(r, s).15 H .445 +(ince the \214rst).4 F F2(N)174 345 Q F1 1.115 +(jobs in queue directory order are run \(rather than the)3.615 F F2(N)3.615 E +F1 1.115(highest priority jobs\))3.615 F .136 +(this should be set as high as possible to a)174 357 R -.2(vo)-.2 G .136 +(id \231losing\232 jobs that happen to f).2 F .136(all late)-.1 F +(in the queue directory)174 369 Q(.)-.65 E(MeT)102 385.2 Q 40.86(oo [m])-.8 F +(Send to me too, e)2.5 E -.15(ve)-.25 G 2.5(ni).15 G 2.5(fIa)279.98 385.2 S 2.5 +(mi)296.08 385.2 S 2.5(na)309.14 385.2 S 2.5(na)321.08 385.2 S(lias e)333.02 +385.2 Q(xpansion.)-.15 E(MaxMessageSize=)102 401.4 Q F2(N)A F1 2.562 +([no short name] Specify the maximum message size to be adv)174 413.4 R 2.563 +(ertised in the)-.15 F(ESMTP EHLO response.)174 425.4 Q(Messages lar)5 E +(ger than this will be rejected.)-.18 E(MinFreeBlocks=)102 441.6 Q F2(N)A F1 +1.539([b] Insist on at least)174 453.6 R F2(N)4.039 E F1 1.538 +(blocks free on the \214lesystem that holds the queue \214les)4.039 F .845 +(before accepting email via SMTP)174 465.6 R 5.846(.I)-1.11 G 3.346(ft)322.368 +465.6 S .846(here is insuf)331.824 465.6 R .846(\214cient space)-.25 F F2 +(sendmail)3.346 E F1(gi)3.346 E -.15(ve)-.25 G 3.346(sa).15 G +(452 response to the MAIL command.)174 477.6 Q(This in)5 E +(vites the sender to try ag)-.4 E(ain later)-.05 E(.)-.55 E(MinQueueAge=age)102 +493.8 Q .887([no short name] Don')174 505.8 R 3.387(tp)-.18 G .887(rocess an) +274.018 505.8 R 3.387(yq)-.15 G .886(ueued jobs that ha)325.072 505.8 R 1.186 +-.15(ve b)-.2 H .886(een in the queue less).15 F 1.899 +(than the indicated time interv)174 517.8 R 4.399(al. This)-.25 F 1.899 +(is intended to allo)4.399 F 4.399(wy)-.25 G 1.9(ou to get respon-)430.81 517.8 +R(si)174 529.8 Q -.15(ve)-.25 G .665(ness by processing the queue f).15 F .665 +(airly frequently without thrashing your system)-.1 F +(by trying jobs too often.)174 541.8 Q(The def)5 E(ault units are minutes.)-.1 +E(NoRecipientAction)102 558 Q .554([no short name] The action to tak)174 570 R +3.055(ew)-.1 G .555(hen you recei)325.25 570 R .855 -.15(ve a m)-.25 H .555 +(essage that has no v).15 F(alid)-.25 E .062(recipient headers \(T)174 582 R +.062(o:, Cc:, Bcc:\).)-.8 F .062(It can be)5.062 F F0(None)2.561 E F1 .061 +(to pass the message on unmodi-)2.561 F .51 +(\214ed, which violates the protocol,)174 594 R F0(Add-T)3.01 E(o)-.92 E F1 .51 +(to add a T)3.01 F .51(o: header with an)-.8 F 3.01(yr)-.15 G(ecipients)468.45 +594 Q 4.41(it can \214nd in the en)174 606 R -.15(ve)-.4 G 4.41 +(lope \(which might e).15 F 4.41(xpose Bcc: recipients\),)-.15 F F0(Add-)6.91 E +-.25(Ap)174 618 S(par).25 E(ently-T)-.18 E(o)-.92 E F1 4.664 +(to add an Apparently-T)7.164 F 4.664(o: header \(this is only for back-)-.8 F +.875(compatibility and is of)174 630 R .875(\214cially deprecated\),)-.25 F F0 +(Add-T)3.374 E(o-Undisclosed)-.92 E F1 .874(to add a header)3.374 F<9954>174 +642 Q 1.594(o: undisclosed-recipients:;\232 to mak)-.8 F 4.094(et)-.1 G 1.594 +(he header le)339.456 642 R -.05(ga)-.15 G 4.095(lw).05 G 1.595 +(ithout disclosing an)414.29 642 R(y-)-.15 E(thing, or)174 654 Q F0(Add-Bcc)2.5 +E F1(to add an empty Bcc: header)2.5 E(.)-.55 E 1.18(OldStyleHeaders [o])102 +670.2 R 1.713 +(Assume that the headers may be in old format, i.e., spaces delimit names.) +4.214 F 1.068(This actually turns on an adapti)174 682.2 R 1.368 -.15(ve a)-.25 +H 1.068(lgorithm: if an).15 F 3.569(yr)-.15 G 1.069 +(ecipient address contains a)393.873 682.2 R 1.681 +(comma, parenthesis, or angle brack)174 694.2 R 1.681 +(et, it will be assumed that commas already)-.1 F -.15(ex)174 706.2 S 2.825 +(ist. If).15 F .325(this \215ag is not on, only commas delimit names.)2.825 F +.325(Headers are al)5.325 F -.1(wa)-.1 G .325(ys out-).1 F +(put with commas between the names.)174 718.2 Q(Def)5 E(aults to of)-.1 E(f.) +-.25 E EP +%%Page: 43 38 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-43)452.9 60 Q/F1 10/Times-Roman@0 SF(OperatorChars=)102 96 Q/F2 10 +/Times-Italic@0 SF -.15(ch)C(arlist).15 E F1 1.438([$o macro] The list of char\ +acters that are considered to be \231operators\232, that is,)174 108 R .82 +(characters that delimit tok)174 120 R 3.32(ens. All)-.1 F .82 +(operator characters are tok)3.32 F .82(ens by themselv)-.1 F(es;)-.15 E .078 +(sequences of non-operator characters are also tok)174 132 R 2.578(ens. White) +-.1 F .078(space characters sep-)2.578 F .269(arate tok)174 144 R .269(ens b) +-.1 F .269(ut are not tok)-.2 F .269(ens themselv)-.1 F .269(es \212 for e)-.15 +F .269(xample, \231)-.15 F .27(AAA.BBB\232 has three)-.8 F(tok)174 156 Q .433 +(ens, b)-.1 F .433(ut \231)-.2 F .433(AAA BBB\232 has tw)-.8 F 2.933(o. If)-.1 +F .433(not set, OperatorChars def)2.933 F .433(aults to \231.)-.1 F 1.666(:@[]) +1.666 G<9a3b>-1.666 E(additionally)174 168 Q 2.5(,t)-.65 G +(he characters \231\()228.91 168 Q 1.666(\)<>,;)1.666 G 2.5<9a61>-1.666 G +(re al)331.25 168 Q -.1(wa)-.1 G(ys operators.).1 E(PostmasterCop)102 184.2 Q +(y=)-.1 E F2(postmaster)A F1 .003 +([P] If set, copies of error messages will be sent to the named)174 196.2 R F2 +(postmaster)2.504 E F1 5.004(.O)C .004(nly the)476.496 196.2 R .627 +(header of the f)174 208.2 R .627(ailed message is sent.)-.1 F .626 +(Since most errors are user problems, this is)5.626 F .453 +(probably not a good idea on lar)174 220.2 R .453(ge sites, and ar)-.18 F .453 +(guably contains all sorts of pri)-.18 F -.25(va)-.25 G -.15(cy).25 G 1.979 +(violations, b)174 232.2 R 1.978 +(ut it seems to be popular with certain operating systems v)-.2 F(endors.)-.15 +E(Def)174 244.2 Q(aults to no postmaster copies.)-.1 E(Pri)102 260.4 Q -.25(va) +-.25 G -.15(cy).25 G(Options=).15 E F2(opt,opt,...)1.666 E F1 1.191 +([p] Set the pri)174 272.4 R -.25(va)-.25 G -.15(cy).25 G F2(opt)3.841 E F1 +3.691(ions. `)B(`Pri)-.74 E -.25(va)-.25 G -.15(cy).25 G 2.671 -.74('' i).15 H +3.692(sr).74 G 1.192(eally a misnomer; man)352.028 272.4 R 3.692(yo)-.15 G +3.692(ft)460.526 272.4 S 1.192(hese are)470.328 272.4 R .929(just a w)174 284.4 +R .928(ay of insisting on stricter adherence to the SMTP protocol.)-.1 F(The) +5.928 E F2(opt)3.428 E F1(ions)A(can be selected from:)174 296.4 Q 40.26 +(public Allo)214 312.6 R 2.5(wo)-.25 G(pen access)314.01 312.6 Q 11.38 +(needmailhelo Insist)214 324.6 R(on HELO or EHLO command before MAIL)2.5 E +(neede)214 336.6 Q 9.87(xpnhelo Insist)-.15 F +(on HELO or EHLO command before EXPN)2.5 E(noe)214 348.6 Q 35.97(xpn Disallo) +-.15 F 2.5(wE)-.25 G(XPN entirely)326.23 348.6 Q 12.5(needvrfyhelo Insist)214 +360.6 R(on HELO or EHLO command before VRFY)2.5 E(no)214 372.6 Q 38.75 +(vrfy Disallo)-.15 F 2.5(wV)-.25 G(RFY entirely)327.34 372.6 Q 14.71 +(restrictmailq Restrict)214 384.6 R(mailq command)2.5 E 19.16 +(restrictqrun Restrict)214 396.6 R(\255q command line \215ag)2.5 E 24.16 +(noreceipts Don')214 408.6 R 2.5(tr)-.18 G(eturn success DSNs)310.74 408.6 Q +(goa)214 420.6 Q -.1(wa)-.15 G 36.91(yD).1 G(isallo)288.98 420.6 Q 2.5(we)-.25 +G(ssentially all SMTP status queries)324.56 420.6 Q(authw)214 432.6 Q 11.48 +(arnings Put)-.1 F(X-Authentication-W)2.5 E(arning: headers in messages)-.8 E +.485(The \231goa)174 448.8 R -.1(wa)-.15 G .485 +(y\232 pseudo-\215ag sets all \215ags e).1 F .486 +(xcept \231restrictmailq\232 and \231restrictqrun\232.)-.15 F 1.175(If mailq i\ +s restricted, only people in the same group as the queue directory can)174 +460.8 R .207(print the queue.)174 472.8 R .207 +(If queue runs are restricted, only root and the o)5.207 F .208 +(wner of the queue)-.25 F .066(directory can run the queue.)174 484.8 R .066 +(Authentication W)5.066 F .066(arnings add w)-.8 F .066(arnings about v)-.1 F +(arious)-.25 E .77(conditions that may indicate attempts to spoof the mail sys\ +tem, such as using an)174 496.8 R(non-standard queue directory)174 508.8 Q(.) +-.65 E(QueueDirectory=)102 525 Q F2(dir)A F1([Q] Use the named)174 537 Q F2 +(dir)2.5 E F1(as the queue directory)2.5 E(.)-.65 E(QueueF)102 553.2 Q(actor=) +-.15 E F2(factor)A F1 .614([q] Use)174 565.2 R F2(factor)3.114 E F1 .613 +(as the multiplier in the map function to decide when to just queue)3.114 F +.415(up jobs rather than run them.)174 577.2 R .415(This v)5.415 F .415 +(alue is di)-.25 F .415(vided by the dif)-.25 F .415(ference between the)-.25 F +1.004(current load a)174 589.2 R -.15(ve)-.2 G 1.004(rage and the load a).15 F +-.15(ve)-.2 G 1.004(rage limit \().15 F F0(QueueLA)A F1 1.003 +(option\) to determine)3.503 F(the maximum message priority that will be sent.) +174 601.2 Q(Def)5 E(aults to 600000.)-.1 E(QueueLA=)102 617.4 Q F2(LA)A F1 .164 +([x] When the system load a)174 617.4 R -.15(ve)-.2 G .165(rage e).15 F(xceeds) +-.15 E F2(LA)2.665 E F1 2.665(,j)C .165(ust queue messages \(i.e., don')367.265 +617.4 R 2.665(tt)-.18 G(ry)495.67 617.4 Q(to send them\).)174 629.4 Q(Def)5 E +(aults to 8.)-.1 E(QueueSortOrder=)102 645.6 Q F2(algorithm)A F1 .097 +([no short name] Sets the)174 657.6 R F2(algorithm)2.597 E F1 .096 +(used for sorting the queue.)2.597 F .096(Only the \214rst char)5.096 F(-)-.2 E +1.021(acter of the v)174 669.6 R 1.021(alue is used.)-.25 F(Le)6.021 E -.05(ga) +-.15 G 3.521(lv).05 G 1.021 +(alues are \231host\232 \(to order by the name of the)317.357 669.6 R .922(\ +\214rst host name of the \214rst recipient\) and \231priority\232 \(to order s\ +trictly by message)174 681.6 R 2.527(priority\). Host)174 693.6 R .027 +(ordering mak)2.527 F .028(es better use of the connection cache, b)-.1 F .028 +(ut may tend to)-.2 F .323(process lo)174 705.6 R 2.823(wp)-.25 G .322 +(riority messages that go to a single host o)229.386 705.6 R -.15(ve)-.15 G +2.822(rh).15 G .322(igh priority messages)417.806 705.6 R 1.824(that go to se) +174 717.6 R -.15(ve)-.25 G 1.824(ral hosts; it probably shouldn').15 F 4.325 +(tb)-.18 G 4.325(eu)376.345 717.6 S 1.825(sed on slo)390.11 717.6 R 4.325(wn) +-.25 G(etw)450.055 717.6 Q 1.825(ork links.)-.1 F EP +%%Page: 44 39 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-44 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF +(Priority ordering is the def)174 96 Q(ault.)-.1 E(Resolv)102 112.2 Q +(erOptions=)-.15 E/F2 10/Times-Italic@0 SF(options)A F1 .128([I] Set resolv)174 +124.2 R .127(er options.)-.15 F -1.11(Va)5.127 G .127(lues can be set using) +1.11 F F0(+)2.627 E F2<8d61>A(g)-.1 E F1 .127(and cleared using)2.627 F F0<ad> +2.627 E F2<8d61>A(g)-.1 E F1 2.627(;t)C(he)494.56 124.2 Q F2<8d61>174 136.2 Q +(g)-.1 E F1 5.013(sc)C 2.513(an be \231deb)202.243 136.2 R 2.513 +(ug\232, \231aaonly\232, \231use)-.2 F 2.514 +(vc\232, \231primary\232, \231igntc\232, \231recurse\232, \231def-)-.25 F .867 +(names\232, \231stayopen\232, or \231dnsrch\232.)174 148.2 R .867 +(The string \231HasW)5.867 F .867(ildcardMX\232 \(without a)-.4 F F0(+)3.367 E +F1(or)3.367 E F0<ad>174 160.2 Q F1 3.82(\)c)C 1.32 +(an be speci\214ed to turn of)191.29 160.2 R 3.82(fm)-.25 G 1.32(atching ag) +311.72 160.2 R 1.32(ainst MX records when doing name)-.05 F(canoni\214cations.) +174 172.2 Q F0(N.B.)5.918 E F1 .917 +(Prior to 8.7, this option indicated that the name serv)5.918 F .917(er be)-.15 +F 1.025(responding in order to accept addresses.)174 184.2 R 1.025 +(This has been replaced by checking to)6.025 F .078(see if the \231dns\232 met\ +hod is listed in the service switch entry for the \231hosts\232 service.)174 +196.2 R(SmtpGreetingMessage=)102 212.4 Q F2(messa)A -.1(ge)-.1 G F1 .344 +([$e macro] The message printed when the SMTP serv)174 224.4 R .345 +(er starts up.)-.15 F(Def)5.345 E .345(aults to \231$j)-.1 F +(Sendmail $v ready at $b\232.)174 236.4 Q -.35(Ti)102 252.6 S(meout.).35 E F2 +(type)A F1(=)A F2(timeout)1.666 E F1 .297 +([r; subsumes old T option as well] Set timeout v)174 264.6 R 2.796(alues. The) +-.25 F .296(actual timeout is indi-)2.796 F 1.678(cated by the)174 276.6 R F2 +(type)4.178 E F1 6.678(.T)C 1.678(he recognized timeouts and their def)261.802 +276.6 R 1.679(ault v)-.1 F 1.679(alues, and their)-.25 F(minimum v)174 288.6 Q +(alues speci\214ed in RFC 1123 section 5.3.2 are:)-.25 E 23.6(initial w)214 +304.8 R(ait for initial greeting message [5m, 5m])-.1 E 29.72(helo reply)214 +316.8 R(to HELO or EHLO command [5m, none])2.5 E 29.16(mail reply)214 328.8 R +(to MAIL command [10m, 5m])2.5 E 31.39(rcpt reply)214 340.8 R +(to RCPT command [1h, 5m])2.5 E 16.94(datainit reply)214 352.8 R(to D)2.5 E +-1.21 -1.11(AT A)-.4 H(command [5m, 2m])3.61 E 8.06(datablock data)214 364.8 R +(block read [1h, 3m])2.5 E 12.5(data\214nal reply)214 376.8 R(to \214nal `)2.5 +E(`.)-.74 E 1.48 -.74('' i)-.7 H 2.5(nd).74 G(ata [1h, 10m])348.47 376.8 Q 32.5 +(rset reply)214 388.8 R(to RSET command [5m, none])2.5 E 31.38(quit reply)214 +400.8 R(to Q)2.5 E(UIT command [2m, none])-.1 E 28.05(misc reply)214 412.8 R +(to NOOP and VERB commands [2m, none])2.5 E 26.94(ident IDENT)214 424.8 R +(protocol timeout [30s, none])2.5 E 9.72(\214leopen\207 timeout)214 436.8 R +(on opening .forw)2.5 E(ard and :include: \214les [60s, none])-.1 E 2.5 +(command\207 command)214 448.8 R(read [1h, 5m])2.5 E(queuereturn\207ho)214 +460.8 Q 2.5(wl)-.25 G(ong until a message is returned [5d, 5d])289.01 460.8 Q +(queue)214 472.8 Q -.1(wa)-.25 G -1.58(rn\207 ho).1 F 2.5(wl)-.25 G +(ong until a w)285.69 472.8 Q(arning is sent [none, none])-.1 E .893(All b)174 +489 R .893(ut those mark)-.2 F .893 +(ed with a dagger \(\207\) apply to client SMTP)-.1 F 5.892(.I)-1.11 G 3.392 +(ft)437.724 489 S .892(he message is)447.226 489 R .273(submitted using the)174 +501 R/F3 9/Times-Roman@0 SF(NO)2.773 E .523(TIFY SMTP)-.36 F F1 -.15(ex)2.773 G +.273(tension, w).15 F .274(arning messages will only be sent)-.1 F(if)174 513 Q +F3(NO)3.038 E(TIFY=DELA)-.36 E(Y)-.945 E F1 .538(is speci\214ed.)3.038 F .537 +(The queuereturn and queue)5.537 F -.1(wa)-.25 G .537(rn timeouts can be).1 F +1.234(further quali\214ed with a tag based on the Precedence: \214eld in the m\ +essage; the)174 525 R(y)-.15 E 1.9(must be one of \231ur)174 537 R 1.9 +(gent\232 \(indicating a positi)-.18 F 2.2 -.15(ve n)-.25 H 1.9 +(on-zero precedence\) \231normal\232).15 F .251 +(\(indicating a zero precedence\), or \231non-ur)174 549 R .251 +(gent\232 \(indicating ne)-.18 F -.05(ga)-.15 G(ti).05 E .552 -.15(ve p)-.25 H +(recedences\).).15 E -.15(Fo)174 561 S 4.423(re).15 G 1.923 +(xample, setting \231T)196.453 561 R(imeout.queue)-.35 E -.1(wa)-.25 G(rn.ur).1 +E 1.923(gent=1h\232 sets the w)-.18 F 1.922(arning timeout)-.1 F .222(for ur) +174 573 R .223(gent messages only to one hour)-.18 F 5.223(.T)-.55 G .223 +(he def)336.749 573 R .223(ault if no precedence is indicated is)-.1 F +(to set the timeout for all precedences.)174 585 Q(RecipientF)102 601.2 Q +(actor=)-.15 E F2(fact)A F1 .638([y] The indicated)174 613.2 R F2(fact)3.137 E +F1 .637(or is added to the priority \(thus)B F2(lowering)3.137 E F1 .637 +(the priority of the)3.137 F .23(job\) for each recipient, i.e., this v)174 +625.2 R .231(alue penalizes jobs with lar)-.25 F .231(ge numbers of recipi-) +-.18 F 2.5(ents. Def)174 637.2 R(aults to 30000.)-.1 E(RefuseLA=)102 653.4 Q F2 +(LA)A F1 1.012([X] When the system load a)174 653.4 R -.15(ve)-.2 G 1.012 +(rage e).15 F(xceeds)-.15 E F2(LA)3.512 E F1 3.512(,r)C 1.011 +(efuse incoming SMTP connec-)376.816 653.4 R 2.5(tions. Def)174 665.4 R +(aults to 12.)-.1 E(RetryF)102 681.6 Q(actor=)-.15 E F2(fact)A F1 .771([Z] The) +3.74 F F2(fact)3.271 E F1 .771(or is added to the priority e)B -.15(ve)-.25 G +.772(ry time a job is processed.).15 F .772(Thus, each)5.772 F .994 +(time a job is processed, its priority will be decreased by the indicated v)174 +693.6 R 3.493(alue. In)-.25 F 1.107(most en)174 705.6 R 1.107 +(vironments this should be positi)-.4 F -.15(ve)-.25 G 3.608(,s).15 G 1.108 +(ince hosts that are do)357.354 705.6 R 1.108(wn are all too)-.25 F(often do) +174 717.6 Q(wn for a long time.)-.25 E(Def)5 E(aults to 90000.)-.1 E EP +%%Page: 45 40 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-45)452.9 60 Q/F1 10/Times-Roman@0 SF(Sa)102 96 Q -.15(ve)-.2 G 10.41 +(FromLine [f]).15 F(Sa)4.909 E 2.709 -.15(ve U)-.2 H 2.408 +(nix-style \231From\232 lines at the front of headers.).15 F 2.408 +(Normally the)7.408 F 4.908(ya)-.15 G(re)496.23 96 Q +(assumed redundant and discarded.)174 108 Q(SendMIMEErrors)102 124.2 Q .815 +([j] If set, send error messages in MIME format \(see RFC1521 and RFC1344 for) +174 136.2 R(details\).)174 148.2 Q(ServiceSwitchFile=)102 164.4 Q/F2 10 +/Times-Italic@0 SF(\214lename)A F1 1.533([no short name] If your host operatin\ +g system has a service switch abstraction)174 176.4 R .003(\(e.g., /etc/nsswit\ +ch.conf on Solaris or /etc/svc.conf on Ultrix and DEC OSF/1\) that)174 188.4 R +.814(service will be consulted and this option is ignored.)174 200.4 R .814 +(Otherwise, this is the name)5.814 F 1.082(of a \214le that pro)174 212.4 R +1.082(vides the list of methods used to implement particular services.)-.15 F +1.069(The syntax is a series of lines, each of which is a sequence of w)174 +224.4 R 3.569(ords. The)-.1 F(\214rst)3.569 E -.1(wo)174 236.4 S 1.363 +(rd is the service name, and follo).1 F 1.363(wing w)-.25 F 1.364 +(ords are service types.)-.1 F 1.364(The services)6.364 F(that)174 248.4 Q F2 +(sendmail)4.11 E F1 1.61(consults directly are \231aliases\232 and \231hosts.) +4.11 F 6.61<9a53>-.7 G 1.61(ervice types can be)422.81 248.4 R 1.754 +(\231dns\232, \231nis\232, \231nisplus\232, or \231\214les\232 \(with the ca) +174 260.4 R -.15(ve)-.2 G 1.755(at that the appropriate support).15 F .791 +(must be compiled in before the service can be referenced\).)174 272.4 R .79 +(If ServiceSwitchFile)5.791 F 1.303(is not speci\214ed, it def)174 284.4 R +1.303(aults to /etc/service.switch.)-.1 F 1.303(If that \214le does not e)6.303 +F 1.304(xist, the)-.15 F(def)174 296.4 Q(ault switch is:)-.1 E 20.28 +(aliases \214les)214 312.6 R 26.38(hosts dns)214 324.6 R(nis \214les)2.5 E +(The def)174 340.8 Q(ault \214le is \231/etc/service.switch\232.)-.1 E(Se)102 +357 Q -.15(ve)-.25 G 12.12(nBitInput [7]).15 F .322(Strip input to se)2.822 F +-.15(ve)-.25 G 2.822(nb).15 G .321(its for compatibility with old systems.) +274.93 357 R .321(This shouldn')5.321 F 2.821(tb)-.18 G(e)499.56 357 Q +(necessary)174 369 Q(.)-.65 E(StatusFile=)102 385.2 Q F2(\214le)A F1 .299 +([S] Log summary statistics in the named)174 385.2 R F2(\214le)2.799 E F1 5.299 +(.I)C 2.799(fn)363.602 385.2 S .3(ot set, no summary statistics are)374.731 +385.2 R(sa)174 397.2 Q -.15(ve)-.2 G 3.775(d. This).15 F 1.275 +(\214le does not gro)3.775 F 3.775(wi)-.25 G 3.775(ns)308.82 397.2 S 3.775 +(ize. It)321.485 397.2 R 1.275(can be printed using the)3.775 F F2(mailstats) +3.775 E F1(\(8\))A(program.)174 409.2 Q 28.4(SuperSafe [s])102 425.4 R .372 +(Be super)2.872 F .372(-safe when running things, i.e., al)-.2 F -.1(wa)-.1 G +.373(ys instantiate the queue \214le, e).1 F -.15(ve)-.25 G(n).15 E .697 +(if you are going to attempt immediate deli)174 437.4 R -.15(ve)-.25 G(ry).15 E +(.)-.65 E F2(Sendmail)5.697 E F1(al)3.197 E -.1(wa)-.1 G .697 +(ys instantiates the).1 F 2.688 +(queue \214le before returning control the client under an)174 449.4 R 5.188 +(yc)-.15 G 5.188(ircumstances. This)423.822 449.4 R(should really)174 461.4 Q +F2(always)2.5 E F1(be set.)2.5 E -.7(Te)102 477.6 S(mpFileMode=).7 E F2(mode)A +F1 .332([F] The \214le mode for queue \214les.)174 489.6 R .331 +(It is interpreted in octal by def)5.331 F 2.831(ault. Def)-.1 F .331(aults to) +-.1 F(0600.)174 501.6 Q -.35(Ti)102 517.8 S(meZoneSpec=).35 E F2(tzinfo)A F1 +.218([t] Set the local time zone info to)174 529.8 R F2(tzinfo)2.718 E F1 2.718 +<8a66>2.718 G .218(or e)351.168 529.8 R .218(xample, \231PST8PDT\232.)-.15 F +(Actually)5.218 E 2.718(,i)-.65 G(f)500.67 529.8 Q 1.346 +(this is not set, the TZ en)174 541.8 R 1.346(vironment v)-.4 F 1.346 +(ariable is cleared \(so the system def)-.25 F 1.345(ault is)-.1 F .208 +(used\); if set b)174 553.8 R .208(ut null, the user')-.2 F 2.708(sT)-.55 G +2.708(Zv)306.916 553.8 S .208(ariable is used, and if set and non-null the TZ) +320.484 553.8 R -.25(va)174 565.8 S(riable is set to this v).25 E(alue.)-.25 E +-.35(Tr)102 582 S 5.96(yNullMXList [w]).35 F .114 +(If this system is the \231best\232 \(that is, lo)2.614 F .114 +(west preference\) MX for a gi)-.25 F -.15(ve)-.25 G 2.613(nh).15 G .113 +(ost, its)477.767 582 R 1.168(con\214guration rules should normally detect thi\ +s situation and treat that condition)174 594 R .258(specially by forw)174 606 R +.258(arding the mail to a UUCP feed, treating it as local, or whate)-.1 F -.15 +(ve)-.25 G -.55(r.).15 G(Ho)174 618 Q(we)-.25 E -.15(ve)-.25 G 1.685 -.4(r, i) +.15 H 3.385(ns).4 G .886(ome cases \(such as Internet \214re)230.54 618 R -.1 +(wa)-.25 G .886(lls\) you may w).1 F .886(ant to try to con-)-.1 F .07 +(nect directly to that host as though it had no MX records at all.)174 630 R +.07(Setting this option)5.07 F(causes)174 642 Q F2(sendmail)3.013 E F1 .514 +(to try this.)3.013 F .514(The do)5.514 F .514 +(wnside is that errors in your con\214guration are)-.25 F(lik)174 654 Q 2.116 +(ely to be diagnosed as \231host unkno)-.1 F 2.116 +(wn\232 or \231message timed out\232 instead of)-.25 F +(something more meaningful.)174 666 Q(This option is disrecommended.)5 E +(UnixFromLine=)102 682.2 Q F2(fr)A(omline)-.45 E F1 .236 +([$l macro] De\214nes the format used when)174 694.2 R F2(sendmail)2.736 E F1 +.236(must add a UNIX-style From_)2.736 F 1.325(line \(that is, a line be)174 +706.2 R 1.325(ginning \231From<space>user\232\).)-.15 F(Def)6.324 E 1.324 +(aults to \231From $g)-.1 F($d\232.)6.324 E(Don')174 718.2 Q 2.645(tc)-.18 G +.146(hange this unless your system uses a dif)204.235 718.2 R .146 +(ferent UNIX mailbox format \(v)-.25 F(ery)-.15 E EP +%%Page: 46 41 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-46 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(unlik)174 96 Q +(ely\).)-.1 E(UseErrorsT)102 112.2 Q 21.15(o[)-.8 G .826 +(l] If there is an \231Errors-T)177.33 112.2 R .826(o:\232 header)-.8 F 3.326 +(,s)-.4 G .826(end error messages to the addresses listed)332.414 112.2 R 3.134 +(there. The)174 124.2 R 3.134(yn)-.15 G .634(ormally go to the en)230.658 124.2 +R -.15(ve)-.4 G .635(lope sender).15 F 5.635(.U)-.55 G .635 +(se of this option causes)383.895 124.2 R/F2 10/Times-Italic@0 SF(send-)3.135 E +(mail)174 136.2 Q F1(to violate RFC 1123.)2.5 E +(This option is disrecommended and deprecated.)5 E(UserDatabaseSpec=)102 152.4 +Q F2(udbspec)A F1([U] The user database speci\214cation.)174 164.4 Q -1.11(Ve) +102 180.6 S 37.29(rbose [v])1.11 F .561(Run in v)3.061 F .561(erbose mode.)-.15 +F .561(If this is set,)5.561 F F2(sendmail)3.061 E F1 .56(adjusts options)3.061 +F F0(HoldExpensi)3.06 E -.1(ve)-.1 G F1(\(old)174 192.6 Q F0(c)2.635 E F1 2.635 +(\)a)C(nd)207.59 192.6 Q F0(Deli)2.635 E -.1(ve)-.1 G(ryMode).1 E F1(\(old) +2.635 E F0(d)2.635 E F1 2.635(\)s)C 2.635(ot)317.36 192.6 S .135 +(hat all mail is deli)327.775 192.6 R -.15(ve)-.25 G .136 +(red completely in a sin-).15 F 1.244 +(gle job so that you can see the entire deli)174 204.6 R -.15(ve)-.25 G 1.244 +(ry process.).15 F(Option)6.244 E F0 -1(Ve)3.743 G(rbose)1 E F1(should)3.743 E +F2(ne)174 216.6 Q(ver)-.15 E F1(be set in the con\214guration \214le; it is in\ +tended for command line use only)2.5 E(.)-.65 E .108(All options can be speci\ +\214ed on the command line using the \255O or \255o \215ag, b)102 232.8 R .109 +(ut most will cause)-.2 F F2(send-)2.609 E(mail)102 244.8 Q F1 1.135 +(to relinquish its setuid permissions.)3.635 F 1.135 +(The options that will not cause this are MinFreeBlocks)6.135 F .513([b], Deli) +102 256.8 R -.15(ve)-.25 G .513 +(ryMode [d], ErrorMode [e], IgnoreDots [i], LogLe).15 F -.15(ve)-.25 G 3.014 +(l[).15 G .514(L], MeT)369.118 256.8 R .514(oo [m], OldStyleHeaders)-.8 F .53 +([o], Pri)102 268.8 R -.25(va)-.25 G -.15(cy).25 G .53(Options [p], T).15 F .53 +(imeouts [r], SuperSafe [s], V)-.35 F .53(erbose [v], CheckpointInterv)-1.11 F +.53(al [C], and Se)-.25 F(v-)-.25 E(enBitInput [7].)102 280.8 Q(Also, M \(de\ +\214ne macro\) when de\214ning the r or s macros is also considered \231safe\ +\232.)5 E F0 2.5(5.7. P)87 304.8 R 2.5<8a50>2.5 G -.18(re)134.22 304.8 S +(cedence De\214nitions).18 E F1 -1.11(Va)127 321 S .164 +(lues for the \231Precedence:\232 \214eld may be de\214ned using the)1.11 F F0 +(P)2.664 E F1 .164(control line.)2.664 F .164(The syntax of this)5.164 F +(\214eld is:)102 333 Q F0(P)142 349.2 Q F2(name)A F0(=)A F2(num)A F1 .384 +(When the)102 365.4 R F2(name)2.884 E F1 .384 +(is found in a \231Precedence:\232 \214eld, the message class is set to)2.884 F +F2(num)2.883 E F1 5.383(.H)C .383(igher numbers)446.127 365.4 R .85 +(mean higher precedence.)102 377.4 R .85(Numbers less than zero ha)5.85 F 1.15 +-.15(ve t)-.2 H .85(he special property that if an error occurs).15 F 1.551 +(during processing the body of the message will not be returned; this is e)102 +389.4 R 1.551(xpected to be used for)-.15 F<9962>102 401.4 Q .461 +(ulk\232 mail such as through mailing lists.)-.2 F .461(The def)5.461 F .461 +(ault precedence is zero.)-.1 F -.15(Fo)5.461 G 2.962(re).15 G .462 +(xample, our list of)429.284 401.4 R(precedences is:)102 413.4 Q +(P\214rst-class=0)142 429.6 Q(Pspecial-deli)142 441.6 Q -.15(ve)-.25 G(ry=100) +.15 E(Plist=\25530)142 453.6 Q(Pb)142 465.6 Q(ulk=\25560)-.2 E(Pjunk=\255100) +142 477.6 Q 1.059(People writing mailing list e)102 493.8 R 1.058 +(xploders are encouraged to use \231Precedence: list\232.)-.15 F 1.058(Older v) +6.058 F 1.058(ersions of)-.15 F F2(sendmail)102 505.8 Q F1 1.19 +(\(which discarded all error returns for ne)3.69 F -.05(ga)-.15 G(ti).05 E 1.49 +-.15(ve p)-.25 H 1.19(recedences\) didn').15 F 3.69(tr)-.18 G 1.19 +(ecognize this name,)422.47 505.8 R(gi)102 517.8 Q .599(ving it a def)-.25 F +.598(ault precedence of zero.)-.1 F .598(This allo)5.598 F .598 +(ws list maintainers to see error returns on both old)-.25 F(and ne)102 529.8 Q +2.5(wv)-.25 G(ersions of)142.7 529.8 Q F2(sendmail)2.5 E F1(.)A F0 2.5(5.8. V) +87 553.8 R 2.5<8a43>2.5 G(on\214guration V)136.44 553.8 Q(ersion Le)-1 E -.1 +(ve)-.15 G(l).1 E F1 3.181 -.8(To p)127 570 T(ro).8 E 1.581 +(vide compatibility with old con\214guration \214les, the)-.15 F F0(V)4.081 E +F1 1.582(line has been added to de\214ne)4.082 F 1.11(some v)102 582 R 1.11 +(ery basic semantics of the con\214guration \214le.)-.15 F 1.11 +(These are not intended to be long term sup-)6.11 F .033(ports; rather)102 594 +R 2.533(,t)-.4 G(he)158.046 594 Q 2.533(yd)-.15 G .033 +(escribe compatibility features which will probably be remo)179.869 594 R -.15 +(ve)-.15 G 2.533(di).15 G 2.533(nf)435.903 594 S .034(uture releases.)446.766 +594 R F0(N.B.:)127 610.2 Q F1 .197(these v)2.697 F(ersion)-.15 E F2(le)2.697 E +(vels)-.15 E F1(ha)2.697 E .496 -.15(ve n)-.2 H .196(othing to do with the v) +.15 F(ersion)-.15 E F2(number)2.696 E F1 .196(on the \214les.)2.696 F -.15(Fo) +5.196 G 2.696(re).15 G(xam-)483.45 610.2 Q(ple, as of this writing v)102 622.2 +Q(ersion 8 con\214g \214les \(speci\214cally)-.15 E 2.5(,8)-.65 G(.7\) used v) +333.41 622.2 Q(ersion le)-.15 E -.15(ve)-.25 G 2.5(l6c).15 G(on\214gurations.) +432.84 622.2 Q 1.102(\231Old\232 con\214guration \214les are de\214ned as v)127 +638.4 R 1.102(ersion le)-.15 F -.15(ve)-.25 G 3.602(lo).15 G 3.602(ne. V) +353.006 638.4 R 1.102(ersion le)-1.11 F -.15(ve)-.25 G 3.602(lt).15 G 1.302 -.1 +(wo \214)430.622 638.4 T 1.103(les mak).1 F 3.603(et)-.1 G(he)494.56 638.4 Q +(follo)102 650.4 Q(wing changes:)-.25 E 12.5(\(1\) Host)107 666.6 R .727(name \ +canoni\214cation \($[ ... $]\) appends a dot if the name is recognized; this g\ +i)3.227 F -.15(ve)-.25 G 3.226(st).15 G(he)494.56 666.6 Q 1.974 +(con\214g \214le a w)133.66 678.6 R 1.974(ay of \214nding out if an)-.1 F 1.974 +(ything matched.)-.15 F(\(Actually)6.974 E 4.475(,t)-.65 G 1.975 +(his just initializes the)413.345 678.6 R .739 +(\231host\232 map with the \231\255a.)133.66 690.6 R 5.739<9a8d>-.7 G .739 +(ag \212 you can reset it to an)251.445 690.6 R .738 +(ything you prefer by declaring the)-.15 F(map e)133.66 702.6 Q(xplicitly)-.15 +E(.\))-.65 E EP +%%Page: 47 42 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-47)452.9 60 Q/F1 10/Times-Roman@0 SF 12.5(\(2\) Def)107 96 R .384 +(ault host name e)-.1 F .385(xtension is consistent throughout processing; v) +-.15 F .385(ersion le)-.15 F -.15(ve)-.25 G 2.885(lo).15 G .385(ne con\214gu-) +458.345 96 R .83(rations turned of)133.66 108 R 3.33(fd)-.25 G .83(omain e) +212.83 108 R .83 +(xtension \(that is, adding the local domain name\) during certain)-.15 F .4 +(points in processing.)133.66 120 R -1.11(Ve)5.4 G .4(rsion le)1.11 F -.15(ve) +-.25 G 2.9(lt).15 G .6 -.1(wo c)280.53 120 T .4(on\214gurations are e).1 F .4 +(xpected to include a trailing dot)-.15 F +(to indicate that the name is already canonical.)133.66 132 Q 12.5(\(3\) Local) +107 148.2 R .072(names that are not aliases are passed through a ne)2.572 F +2.572(wd)-.25 G .072(istinguished ruleset \214v)372.752 148.2 R .072 +(e; this can)-.15 F 1.426(be used to append a local relay)133.66 160.2 R 6.426 +(.T)-.65 G 1.426(his beha)279.902 160.2 R 1.426(viour can be pre)-.2 F -.15(ve) +-.25 G 1.426(nted by resolving the local).15 F .209(name with an initial `@'.) +133.66 172.2 R .209(That is, something that resolv)5.209 F .209 +(es to a local mailer and a user name)-.15 F 1.072 +(of \231vikki\232 will be passed through ruleset \214v)133.66 184.2 R 1.072 +(e, b)-.15 F 1.073(ut a user name of \231@vikki\232 will ha)-.2 F 1.373 -.15 +(ve t)-.2 H(he).15 E .417 +(`@' stripped, will not be passed through ruleset \214v)133.66 196.2 R .417 +(e, b)-.15 F .416(ut will otherwise be treated the same)-.2 F 1.702 +(as the prior e)133.66 208.2 R 4.202(xample. The)-.15 F -.15(ex)4.202 G 1.703 +(pectation is that this might be used to implement a polic).15 F(y)-.15 E .136 +(where mail sent to \231vikki\232 w)133.66 220.2 R .135 +(as handled by a central hub, b)-.1 F .135 +(ut mail sent to \231vikki@localhost\232)-.2 F -.1(wa)133.66 232.2 S 2.5(sd).1 +G(eli)156.61 232.2 Q -.15(ve)-.25 G(red directly).15 E(.)-.65 E -1.11(Ve)127 +248.4 S 1.382(rsion le)1.11 F -.15(ve)-.25 G 3.882(lt).15 G 1.382 +(hree \214les allo)187.134 248.4 R 3.882(w#i)-.25 G 1.382 +(nitiated comments on all lines.)266.292 248.4 R 1.383 +(Exceptions are backslash)6.383 F(escaped # marks and the $# syntax.)102 260.4 +Q -1.11(Ve)127 276.6 S 1.208(rsion le)1.11 F -.15(ve)-.25 G 3.708(lf).15 G +1.208(our con\214gurations are completely equi)187.336 276.6 R -.25(va)-.25 G +1.207(lent to le).25 F -.15(ve)-.25 G 3.707(lt).15 G 1.207 +(hree for historical rea-)411.249 276.6 R(sons.)102 288.6 Q -1.11(Ve)127 304.8 +S 1.234(rsion le)1.11 F -.15(ve)-.25 G 3.734<6c8c>.15 G 1.534 -.15(ve c)189.618 +304.8 T 1.234(on\214guration \214les change the def).15 F 1.234 +(ault de\214nition of)-.1 F F0($w)3.734 E F1 1.234(to be just the \214rst)3.734 +F(component of the hostname.)102 316.8 Q -1.11(Ve)127 333 S 1.589(rsion le)1.11 +F -.15(ve)-.25 G 4.089(ls).15 G 1.589(ix con\214guration \214les change man) +188.658 333 R 4.088(yo)-.15 G 4.088(ft)342.272 333 S 1.588 +(he local processing options \(such as)352.47 333 R .48 +(aliasing and matching the be)102 345 R .481 +(ginning of the address for `|' characters\) to be mailer \215ags; this allo) +-.15 F(ws)-.25 E 1.345(\214ne-grained control o)102 357 R -.15(ve)-.15 G 3.845 +(rt).15 G 1.345(he special local processing.)210.435 357 R(Le)6.345 E -.15(ve) +-.25 G 3.845(ls).15 G 1.344(ix con\214guration \214les may also use)360.34 357 +R 1.221(long option names.)102 369 R(The)6.221 E F0(ColonOkInAddr)3.721 E F1 +1.221(option \(to allo)3.721 F 3.722(wc)-.25 G 1.222 +(olons in the local-part of addresses\))355.42 369 R(def)102 381 Q(aults)-.1 E +F0(on)3.44 E F1 .94(for lo)3.44 F .94(wer numbered con\214guration \214les; th\ +e con\214guration \214le requires some additional)-.25 F +(intelligence to properly handle the RFC 822 group construct.)102 393 Q(The)127 +409.2 Q F0(V)2.677 E F1 .177(line may ha)2.677 F .477 -.15(ve a)-.2 H 2.677(no) +.15 G(ptional)231.022 409.2 Q F0(/)2.677 E/F2 10/Times-Italic@0 SF(vendor)A F1 +.178(to indicate that this con\214guration \214le uses modi\214ca-)2.677 F .865 +(tions speci\214c to a particular v)102 423.2 R(endor)-.15 E/F3 7/Times-Roman@0 +SF(19)246.986 419.2 Q F1 5.866(.Y)253.986 423.2 S .866(ou may use \231/Berk) +268.472 423.2 R(ele)-.1 E .866(y\232 to emphasize that this con\214gura-)-.15 F +(tion \214le uses the Berk)102 435.2 Q(ele)-.1 E 2.5(yd)-.15 G(ialect of)213.13 +435.2 Q F2(sendmail)2.5 E F1(.)A F0 2.5(5.9. K)87 459.2 R 2.5<8a4b>2.5 G +(ey File Declaration)137.31 459.2 Q F1 +(Special maps can be de\214ned using the line:)127 475.4 Q +(Kmapname mapclass ar)142 491.6 Q(guments)-.18 E(The)102 507.8 Q F2(mapname) +2.751 E F1 .251(is the handle by which this map is referenced in the re)2.751 F +.25(writing rules.)-.25 F(The)5.25 E F2(mapclass)2.75 E F1(is)2.75 E 1.889 +(the name of a type of map; these are compiled in to)102 519.8 R F2(sendmail) +4.389 E F1 6.889(.T)C(he)384.013 519.8 Q F2(ar)4.389 E(guments)-.37 E F1 1.889 +(are interpreted)4.389 F .791(depending on the class; typically)102 531.8 R +3.291(,t)-.65 G .791(here w)244.185 531.8 R .791(ould be a single ar)-.1 F .79 +(gument naming the \214le containing the)-.18 F(map.)102 543.8 Q +(Maps are referenced using the syntax:)127 560 Q($\()142 576.2 Q F2(map k)2.5 E +-.3(ey)-.1 G F1($@)2.8 E F2(ar)2.5 E(guments)-.37 E F1($:)2.5 E F2(default)2.5 +E F1($\))2.5 E .64(where either or both of the)102 592.4 R F2(ar)3.14 E +(guments)-.37 E F1(or)3.141 E F2(default)3.141 E F1 .641 +(portion may be omitted.)3.141 F(The)5.641 E F2 .641($@ ar)3.141 F(guments)-.37 +E F1(may)3.141 E 1.277(appear more than once.)102 604.4 R 1.277(The indicated) +6.277 F F2 -.1(ke)3.777 G(y)-.2 E F1(and)3.776 E F2(ar)3.776 E(guments)-.37 E +F1 1.276(are passed to the appropriate mapping)3.776 F 3.253(function. If)102 +616.4 R .753(it returns a v)3.253 F .753(alue, it replaces the input.)-.25 F +.753(If it does not return a v)5.753 F .753(alue and the)-.25 F F2(default) +3.253 E F1(is)3.253 E(speci\214ed, the)102 628.4 Q F2(default)2.5 E F1 +(replaces the input.)2.5 E(Otherwise, the input is unchanged.)5 E 1.042 +(During replacement of either a map v)127 644.6 R 1.042(alue or def)-.25 F +1.042(ault the string \231%)-.1 F F2(n)A F1 3.542<9a28>C(where)417.414 644.6 Q +F2(n)3.542 E F1 1.041(is a digit\) is)3.541 F .481 +(replaced by the corresponding)102 656.6 R F2(ar)2.981 E(gument)-.37 E F1 5.481 +(.A)C -.18(rg)280.385 656.6 S .482(ument zero is al).18 F -.1(wa)-.1 G .482 +(ys the database k).1 F -.15(ey)-.1 G 5.482(.F)-.5 G .482(or e)456.458 656.6 R +(xample,)-.15 E(the rule)102 668.6 Q .32 LW 76 678.2 72 678.2 DL 80 678.2 76 +678.2 DL 84 678.2 80 678.2 DL 88 678.2 84 678.2 DL 92 678.2 88 678.2 DL 96 +678.2 92 678.2 DL 100 678.2 96 678.2 DL 104 678.2 100 678.2 DL 108 678.2 104 +678.2 DL 112 678.2 108 678.2 DL 116 678.2 112 678.2 DL 120 678.2 116 678.2 DL +124 678.2 120 678.2 DL 128 678.2 124 678.2 DL 132 678.2 128 678.2 DL 136 678.2 +132 678.2 DL 140 678.2 136 678.2 DL 144 678.2 140 678.2 DL 148 678.2 144 678.2 +DL 152 678.2 148 678.2 DL 156 678.2 152 678.2 DL 160 678.2 156 678.2 DL 164 +678.2 160 678.2 DL 168 678.2 164 678.2 DL 172 678.2 168 678.2 DL 176 678.2 172 +678.2 DL 180 678.2 176 678.2 DL 184 678.2 180 678.2 DL 188 678.2 184 678.2 DL +192 678.2 188 678.2 DL 196 678.2 192 678.2 DL 200 678.2 196 678.2 DL 204 678.2 +200 678.2 DL 208 678.2 204 678.2 DL 212 678.2 208 678.2 DL 216 678.2 212 678.2 +DL/F4 5/Times-Roman@0 SF(19)93.6 688.6 Q/F5 8/Times-Roman@0 SF .214 +(And of course, v)3.2 J .214(endors are encouraged to add themselv)-.12 F .214 +(es to the list of recognized v)-.12 F .214(endors by editing the routine)-.12 +F/F6 8/Times-Italic@0 SF(setvendor)2.214 E F5(in)2.214 E F6(conf)72 701.4 Q(.c) +-.12 E F5 4(.P)C(lease send e-mail to sendmail@CS.Berk)101.656 701.4 Q(ele)-.08 +E -.52(y.)-.12 G(EDU to re).52 E(gister your v)-.12 E(endor dialect.)-.12 E EP +%%Page: 48 43 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-48 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(R$\255 ! $+)142 +96 Q($: $\(uucp $1 $@ $2 $: %1 @ %0 . UUCP $\))250 96 Q 1.269(Looks up the UUC\ +P name in a \(user de\214ned\) UUCP map; if not found it turns it into \231.UU\ +CP\232)102 112.2 R 2.5(form. The)102 124.2 R +(database might contain records lik)2.5 E(e:)-.1 E(decv)142 140.4 Q 77.43 +(ax %1@%0.DEC.COM)-.25 F 72.19(research %1@%0.A)142 152.4 R(TT)-1.11 E(.COM) +-.74 E .741(The b)127 172.8 R .741(uilt in map with both name and class \231ho\ +st\232 is the host name canonicalization lookup.)-.2 F(Thus, the syntax:)102 +184.8 Q($\(host)142 201 Q/F2 10/Times-Italic@0 SF(hostname)2.5 E F1($\))A +(is equi)102 217.2 Q -.25(va)-.25 G(lent to:).25 E($[)142 233.4 Q F2(hostname)A +F1($])A(There are man)127 253.8 Q 2.5(yd)-.15 G(e\214ned classes.)197.1 253.8 Q +51.72(dbm Database)102 270 R 1.623(lookups using the ndbm\(3\) library)4.123 F +(.)-.65 E F2(Sendmail)6.623 E F1 1.623(must be compiled with)4.123 F F0(NDBM) +174 282 Q F1(de\214ned.)2.5 E 49.51(btree Database)102 298.2 R 1.284 +(lookups using the btree interf)3.784 F 1.285(ace to the Berk)-.1 F(ele)-.1 E +3.785(yd)-.15 G 1.285(b\(3\) library)425.99 298.2 R(.)-.65 E F2(Send-)6.285 E +(mail)174 310.2 Q F1(must be compiled with)2.5 E F0(NEWDB)2.5 E F1(de\214ned.) +2.5 E 51.17(hash Database)102 326.4 R .122(lookups using the hash interf)2.622 +F .122(ace to the Berk)-.1 F(ele)-.1 E 2.622(yd)-.15 G .121(b\(3\) library) +413.868 326.4 R(.)-.65 E F2(Sendmail)5.121 E F1(must be compiled with)174 338.4 +Q F0(NEWDB)2.5 E F1(de\214ned.)2.5 E 57.83(nis NIS)102 354.6 R(lookups.)2.5 E +F2(Sendmail)5 E F1(must be compiled with)2.5 E F0(NIS)2.5 E F1(de\214ned.)2.5 E +41.16(nisplus NIS+)102 370.8 R(lookups.)3.733 E F2(Sendmail)6.233 E F1 1.233 +(must be compiled with)3.733 F F0(NISPLUS)3.733 E F1 3.733(de\214ned. The)3.733 +F(ar)3.733 E(gu-)-.18 E .495 +(ment is the name of the table to use for lookups, and the)174 382.8 R F0<ad6b> +2.995 E F1(and)2.995 E F0<ad76>2.995 E F1 .495(\215ags may be)2.995 F +(used to set the k)174 394.8 Q .3 -.15(ey a)-.1 H(nd v).15 E +(alue columns respecti)-.25 E -.15(ve)-.25 G(ly).15 E(.)-.65 E 43.39 +(hesiod Hesiod)102 411 R(lookups.)2.5 E F2(Sendmail)5 E F1 +(must be compiled with)2.5 E F0(HESIOD)2.5 E F1(de\214ned.)2.5 E 41.17 +(netinfo NeXT)102 427.2 R(NetInfo lookups.)2.5 E F2(Sendmail)5 E F1 +(must be compiled with)2.5 E F0(NETINFO)2.5 E F1(de\214ned.)2.5 E(te)102 443.4 +Q 54.65(xt T)-.15 F -.15(ex)-.7 G 2.917<748c>.15 G .417(le lookups.)199.957 +443.4 R .417(The format of the te)5.417 F .418(xt \214le is de\214ned by the) +-.15 F F0<ad6b>2.918 E F1(\(k)2.918 E .718 -.15(ey \214)-.1 H .418(eld num-).15 +F(ber\),)174 455.4 Q F0<ad76>2.5 E F1(\(v)2.5 E(alue \214eld number\), and)-.25 +E F0<ad7a>2.5 E F1(\(\214eld delimiter\) \215ags.)2.5 E 53.39(stab Internal)102 +471.6 R(symbol table lookups.)2.5 E(Used internally for aliasing.)5 E 38.38 +(implicit Really)102 487.8 R .546 +(should be called \231alias\232 \212 this is used to get the def)3.046 F .546 +(ault lookups for alias)-.1 F(\214les, and is the def)174 499.8 Q +(ault if no class is speci\214ed for alias \214les.)-.1 E 52.84(user Looks)102 +516 R .476(up users using)2.976 F F2 -.1(ge)2.976 G(tpwnam).1 E F1 2.976 +(\(3\). The)B F0<ad76>2.976 E F1 .477(\215ag can be used to specify the name) +2.976 F .142 +(of the \214eld to return \(although this is normally used only to check the e) +174 528 R .142(xistence of)-.15 F 2.5(au)174 540 S(ser\).)185.94 540 Q 52.83 +(host Canoni\214es)102 556.2 R .2(host domain names.)2.7 F(Gi)5.2 E -.15(ve) +-.25 G 2.7(nah).15 G .2(ost name it calls the name serv)343.68 556.2 R .2 +(er to \214nd)-.15 F(the canonical name for that host.)174 568.2 Q 32.85 +(sequence The)102 584.4 R(ar)3.35 E .849 +(guments on the `K' line are a list of maps; the resulting map searches the) +-.18 F(ar)174 596.4 Q .438 +(gument maps in order until it \214nds a match for the indicated k)-.18 F -.15 +(ey)-.1 G 5.439(.F)-.5 G .439(or e)456.501 596.4 R(xample,)-.15 E(if the k)174 +608.4 Q .3 -.15(ey d)-.1 H(e\214nition is:).15 E(Kmap1 ...)214 624.6 Q +(Kmap2 ...)214 636.6 Q(Kseqmap sequence map1 map2)214 648.6 Q .968 +(then a lookup ag)174 664.8 R .968 +(ainst \231seqmap\232 \214rst does a lookup in map1.)-.05 F .968 +(If that is found, it)5.968 F(returns immediately)174 676.8 Q 5(.O)-.65 G +(therwise, the same k)268.34 676.8 Q .3 -.15(ey i)-.1 H 2.5(su).15 G +(sed for map2.)375.85 676.8 Q 43.39(switch Much)102 693 R(lik)2.8 E 2.8(et)-.1 +G .3(he \231sequence\232 map e)220.61 693 R .301 +(xcept that the order of maps is determined by the)-.15 F .392(service switch.) +174 705 R .392(The ar)5.392 F .391 +(gument is the name of the service to be look)-.18 F .391(ed up; the v)-.1 F +(al-)-.25 E 1.492 +(ues from the service switch are appended to the map name to create ne)174 717 +R 3.993(wm)-.25 G(ap)494.56 717 Q EP +%%Page: 49 44 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-49)452.9 60 Q/F1 10/Times-Roman@0 SF 2.5(names. F)174 96 R(or e)-.15 E +(xample, consider the k)-.15 E .3 -.15(ey d)-.1 H(e\214nition:).15 E +(Kali switch aliases)214 112.2 Q(together with the service switch entry:)174 +128.4 Q 78.84(aliases nis)214 144.6 R(\214les)2.5 E 1.633 +(This causes a query ag)174 160.8 R 1.633 +(ainst the map \231ali\232 to search maps named \231ali.nis\232 and)-.05 F +(\231ali.\214les\232 in that order)174 172.8 Q(.)-.55 E 37.84(dequote Strip)102 +189 R .96(double quotes \("\) from a name.)3.46 F .961 +(It does not strip backslashes, and will not)5.961 F .173 +(strip quotes if the resulting string w)174 201 R .172 +(ould contain unscannable syntax \(that is, basic)-.1 F .386(errors lik)174 213 +R 2.886(eu)-.1 G .386(nbalanced angle brack)222.992 213 R .386 +(ets; more sophisticated errors such as unkno)-.1 F(wn)-.25 E .252 +(hosts are not check)174 225 R 2.752(ed\). The)-.1 F .251 +(intent is for use when trying to accept mail from sys-)2.752 F +(tems such as DECnet that routinely quote odd syntax such as)174 237 Q +("49ers::ubell")214 253.2 Q 2.5(At)174 269.4 S +(ypical usage is probably something lik)186.5 269.4 Q(e:)-.1 E +(Kdequote dequote)214 285.6 Q(...)214 309.6 Q 88.19(R$\255 $:)214 333.6 R +($\(dequote $1 $\))2.5 E(R$\255 $+)214 345.6 Q($: $>3 $1 $2)322 345.6 Q +(Care must be tak)174 361.8 Q(en to pre)-.1 E -.15(ve)-.25 G(nt une).15 E +(xpected results; for e)-.15 E(xample,)-.15 E("|someprogram < input > output") +214 378 Q 1.31(will ha)174 394.2 R 1.61 -.15(ve q)-.2 H 1.31(uotes stripped, b) +.15 F 1.31(ut the result is probably not what you had in mind.)-.2 F -.15(Fo) +174 406.2 S(rtunately these cases are rare.).15 E .488 +(Most of these accept as ar)127 422.4 R .488 +(guments the same optional \215ags and a \214lename \(or a mapname for)-.18 F +.31(NIS; the \214lename is the root of the database path, so that \231.db\232 \ +or some other e)102 434.4 R .31(xtension appropriate)-.15 F +(for the database type will be added to get the actual database name\).)102 +446.4 Q(Kno)5 E(wn \215ags are:)-.25 E 58.86(\255o Indicates)102 462.6 R 1.147 +(that this map is optional \212 that is, if it cannot be opened, no error is) +3.648 F(produced, and)174 474.6 Q/F2 10/Times-Italic@0 SF(sendmail)2.5 E F1 +(will beha)2.5 E .3 -.15(ve a)-.2 H 2.5(si).15 G 2.5(ft)333.9 474.6 S(he map e) +342.51 474.6 Q(xisted b)-.15 E(ut w)-.2 E(as empty)-.1 E(.)-.65 E .647 +(\255N, \255O)102 490.8 R .647(If neither)174.647 490.8 R F0<ad4e>3.147 E F1 +(or)3.147 E F0<ad4f>3.147 E F1 .647(are speci\214ed,)3.147 F F2(sendmail)3.147 +E F1 .647(uses an adapti)3.147 F .947 -.15(ve a)-.25 H .648(lgorithm to decide) +.15 F .108(whether or not to look for null bytes on the end of k)174 502.8 R +-.15(ey)-.1 G 2.608(s. It).15 F .107(starts by trying both; if)2.608 F .819 +(it \214nds an)174 514.8 R 3.319(yk)-.15 G 1.119 -.15(ey w)228.157 514.8 T .819 +(ith a null byte it ne).15 F -.15(ve)-.25 G 3.319(rt).15 G .82(ries ag)345.83 +514.8 R .82(ain without a null byte and vice)-.05 F -.15(ve)174 526.8 S 2.828 +(rsa. If).15 F F0<ad4e>2.828 E F1 .328(is speci\214ed it ne)2.828 F -.15(ve) +-.25 G 2.828(rt).15 G .328(ries without a null byte and if)311.696 526.8 R F0 +<ad4f>2.827 E F1 .327(is speci\214ed it)2.827 F(ne)174 538.8 Q -.15(ve)-.25 G +2.886(rt).15 G .386(ries with a null byte.)201.476 538.8 R .386 +(Setting one of these can speed matches b)5.386 F .386(ut are ne)-.2 F -.15(ve) +-.25 G(r).15 E(necessary)174 550.8 Q 5.546(.I)-.65 G 3.046(fb)223.596 550.8 S +(oth)234.972 550.8 Q F0<ad4e>3.046 E F1(and)3.046 E F0<ad4f>3.046 E F1 .545 +(are speci\214ed,)3.045 F F2(sendmail)3.045 E F1 .545(will ne)3.045 F -.15(ve) +-.25 G 3.045(rt).15 G .545(ry an)442.52 550.8 R 3.045(ym)-.15 G(atches)479.01 +550.8 Q(at all \212 that is, e)174 562.8 Q -.15(ve)-.25 G +(rything will appear to f).15 E(ail.)-.1 E<ad61>102 579 Q F2(x)A F1 1.356 +(Append the string)174 579 R F2(x)3.856 E F1 1.357(on successful matches.)3.856 +F -.15(Fo)6.357 G 3.857(re).15 G 1.357(xample, the def)382.852 579 R(ault)-.1 E +F2(host)3.857 E F1(map)3.857 E(appends a dot on successful matches.)174 591 Q +60.53(\255f Do)102 607.2 R(not fold upper to lo)2.5 E +(wer case before looking up the k)-.25 E -.15(ey)-.1 G(.)-.5 E 56.08 +(\255m Match)102 623.4 R .4(only \(without replacing the v)2.9 F 2.899 +(alue\). If)-.25 F .399(you only care about the e)2.899 F .399(xistence of)-.15 +F 7.306(ak)174 635.4 S 5.107 -.15(ey a)190.646 635.4 T 4.807(nd not the v).15 F +4.807(alue \(as you might when searching the NIS map)-.25 F 1.947 +(\231hosts.byname\232 for e)174 647.4 R 1.947(xample\), this \215ag pre)-.15 F +-.15(ve)-.25 G 1.947(nts the map from substituting the).15 F -.25(va)174 659.4 +S 2.849(lue. Ho).25 F(we)-.25 E -.15(ve)-.25 G 1.149 -.4(r, T).15 H .349 +(he \255a ar).4 F .349(gument is still appended on a match, and the def)-.18 F +.35(ault is)-.1 F(still tak)174 671.4 Q(en if the match f)-.1 E(ails.)-.1 E +<ad6b>102 687.6 Q F2 -.1(ke)C(ycol)-.2 E F1(The k)174 687.6 Q .3 -.15(ey c)-.1 +H(olumn name \(for NIS+\) or number \(for te).15 E(xt lookups\).)-.15 E<ad76> +102 703.8 Q F2(valcol)A F1(The v)174 703.8 Q +(alue column name \(for NIS+\) or number \(for te)-.25 E(xt lookups\).)-.15 E +EP +%%Page: 50 45 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-50 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF<ad7a>102 96 Q/F2 +10/Times-Italic@0 SF(delim)A F1 .219(The column delimiter \(for te)174 96 R +.219(xt lookups\).)-.15 F .218(It can be a single character or one of the)5.219 +F 1.825(special strings \231)174 108 R 1.825(\\n\232 or \231)1.666 F 1.826 +(\\t\232 to indicate ne)1.666 F 1.826(wline or tab respecti)-.25 F -.15(ve)-.25 +G(ly).15 E 6.826(.I)-.65 G 4.326(fo)465.784 108 S(mitted)478.44 108 Q(entirely) +174 120 Q 2.5(,t)-.65 G(he column separator is an)211.68 120 Q 2.5(ys)-.15 G +(equence of whitespace.)325.12 120 Q<ad73>102 136.2 Q F2(spacesub)A F1 -.15(Fo) +174 136.2 S 3.101(rt).15 G .601(he dequote map only)193.621 136.2 R 3.101(,t) +-.65 G .601(he character to use to replace space characters after a)286.755 +136.2 R(successful dequote.)174 148.2 Q(The)127 164.4 Q F2(dbm)3.356 E F1 .856 +(map appends the strings \231.pag\232 and \231.dir\232 to the gi)3.356 F -.15 +(ve)-.25 G 3.356<6e8c>.15 G .856(lename; the tw)399.052 164.4 R(o)-.1 E F2(db) +3.356 E F1(-based)A(maps append \231.db\232.)102 176.4 Q -.15(Fo)5 G 2.5(re).15 +G(xample, the map speci\214cation)206.4 176.4 Q -.15(Ku)142 192.6 S +(ucp dbm \255o \255N /usr/lib/uucpmap).15 E .21 +(speci\214es an optional map named \231uucp\232 of class \231dbm\232; it al)102 +208.8 R -.1(wa)-.1 G .21(ys has null bytes at the end of e).1 F -.15(ve)-.25 G +(ry).15 E(string, and the data is located in /usr/lib/uucpmap.{dir)102 220.8 Q +(,pag}.)-.4 E 1.094(The program)127 237 R F2(mak)3.594 E(emap)-.1 E F1 1.094 +(\(8\) can be used to b)B 1.094(uild an)-.2 F 3.594(yo)-.15 G 3.594(ft)347.736 +237 S 1.095(he three database-oriented maps.)357.44 237 R(It)6.095 E(tak)102 +249 Q(es the follo)-.1 E(wing \215ags:)-.25 E 60.53(\255f Do)102 265.2 R +(not fold upper to lo)2.5 E(wer case in the map.)-.25 E 56.64(\255N Include)102 +281.4 R(null bytes in k)2.5 E -.15(ey)-.1 G(s.).15 E 58.86(\255o Append)102 +297.6 R(to an e)2.5 E(xisting \(old\) \214le.)-.15 E 60.53(\255r Allo)102 313.8 +R 3.669(wr)-.25 G 1.169(eplacement of e)205.749 313.8 R 1.168(xisting k)-.15 F +-.15(ey)-.1 G 1.168(s; normally).15 F 3.668(,r)-.65 G 1.168(e-inserting an e) +371.63 313.8 R 1.168(xisting k)-.15 F 1.468 -.15(ey i)-.1 H 3.668(sa).15 G(n) +499 313.8 Q(error)174 325.8 Q(.)-.55 E 58.86(\255v Print)102 342 R +(what is happening.)2.5 E(The)102 358.2 Q F2(sendmail)3.605 E F1 1.105 +(daemon does not ha)3.605 F 1.405 -.15(ve t)-.2 H 3.605(ob).15 G 3.605(er) +272.975 358.2 S 1.106(estarted to read the ne)284.35 358.2 R 3.606(wm)-.25 G +1.106(aps as long as you change)394.88 358.2 R +(them in place; \214le locking is used so that the maps w)102 372.2 Q(on')-.1 E +2.5(tb)-.18 G 2.5(er)336.71 372.2 S(ead while the)346.98 372.2 Q 2.5(ya)-.15 G +(re being updated.)412.09 372.2 Q/F3 7/Times-Roman@0 SF(20)481.24 368.2 Q F1 +(Ne)127 388.4 Q 2.5(wc)-.25 G(lasses can be added in the routine)152.57 388.4 Q +F0(setupmaps)2.5 E F1(in \214le)2.5 E F0(conf)2.5 E(.c)-.15 E F1(.)A F0 2.5 +(5.10. The)87 412.4 R(User Database)2.5 E F1 .108(If you ha)127 428.6 R .408 +-.15(ve a ve)-.2 H .109(rsion of).15 F F2(sendmail)2.609 E F1 .109 +(with the user database package compiled in, the handling of)2.609 F +(sender and recipient addresses is modi\214ed.)102 440.6 Q +(The location of this database is controlled with the)127 456.8 Q F0 +(UserDatabaseSpec)2.5 E F1(option.)2.5 E F0 2.5(5.10.1. Structur)102 480.8 R +2.5(eo)-.18 G 2.5(ft)182.92 480.8 S(he user database)192.08 480.8 Q F1 +(The database is a sorted \(BT)142 497 Q(ree-based\) structure.)-.35 E +(User records are stored with the k)5 E -.15(ey)-.1 G(:).15 E F2(user)157 513.2 +Q(-name)-.2 E F0(:)A F2(\214eld-name)A F1 .128 +(The sorted database format ensures that user records are clustered together) +117 529.4 R 5.128(.M)-.55 G .128(eta-information is)432.492 529.4 R(al)117 +541.4 Q -.1(wa)-.1 G(ys stored with a leading colon.).1 E +(Field names de\214ne both the syntax and semantics of the v)142 557.6 Q 2.5 +(alue. De\214ned)-.25 F(\214elds include:)2.5 E 33.39(maildrop The)117 573.8 R +(deli)4.872 E -.15(ve)-.25 G 2.372(ry address for this user).15 F 7.372(.T)-.55 +G 2.373(here may be multiple v)349.472 573.8 R 2.373(alues of this)-.25 F 2.675 +(record. In)189 585.8 R(particular)2.675 E 2.675(,m)-.4 G .175 +(ailing lists will ha)284.095 585.8 R .475 -.15(ve o)-.2 H(ne).15 E F2(maildr) +2.675 E(op)-.45 E F1 .175(record for each user)2.675 F(on the list.)189 597.8 Q +30.06(mailname The)117 614 R 1.026(outgoing mailname for this user)3.526 F +6.026(.F)-.55 G 1.027(or each outgoing name, there should)353.336 614 R .08 +(be an appropriate)189 626 R F2(maildr)2.58 E(op)-.45 E F1 .08 +(record for that name to allo)2.58 F 2.58(wr)-.25 G .08(eturn mail.)422.38 626 +R .08(See also)5.08 F F2(:default:mailname)189 638 Q F1(.)A 25.62 +(mailsender Changes)117 654.2 R(an)3.447 E 3.447(ym)-.15 G .947 +(ail sent to this address to ha)252.404 654.2 R 1.248 -.15(ve t)-.2 H .948 +(he indicated en).15 F -.15(ve)-.4 G .948(lope sender).15 F(.)-.55 E 2.736 +(This is intended for mailing lists, and will normally be the name of an)189 +666.2 R .32 LW 76 675.8 72 675.8 DL 80 675.8 76 675.8 DL 84 675.8 80 675.8 DL +88 675.8 84 675.8 DL 92 675.8 88 675.8 DL 96 675.8 92 675.8 DL 100 675.8 96 +675.8 DL 104 675.8 100 675.8 DL 108 675.8 104 675.8 DL 112 675.8 108 675.8 DL +116 675.8 112 675.8 DL 120 675.8 116 675.8 DL 124 675.8 120 675.8 DL 128 675.8 +124 675.8 DL 132 675.8 128 675.8 DL 136 675.8 132 675.8 DL 140 675.8 136 675.8 +DL 144 675.8 140 675.8 DL 148 675.8 144 675.8 DL 152 675.8 148 675.8 DL 156 +675.8 152 675.8 DL 160 675.8 156 675.8 DL 164 675.8 160 675.8 DL 168 675.8 164 +675.8 DL 172 675.8 168 675.8 DL 176 675.8 172 675.8 DL 180 675.8 176 675.8 DL +184 675.8 180 675.8 DL 188 675.8 184 675.8 DL 192 675.8 188 675.8 DL 196 675.8 +192 675.8 DL 200 675.8 196 675.8 DL 204 675.8 200 675.8 DL 208 675.8 204 675.8 +DL 212 675.8 208 675.8 DL 216 675.8 212 675.8 DL/F4 5/Times-Roman@0 SF(20)93.6 +686.2 Q/F5 8/Times-Roman@0 SF .466(That is, don')3.2 J 2.466(tc)-.144 G .466 +(reate ne)148.294 689.4 R 2.466(wm)-.2 G .466(aps and then use)188.122 689.4 R +/F6 8/Times-Italic@0 SF(mv)2.466 E F5 .466(\(1\) to mo)B .706 -.12(ve t)-.12 H +.466(hem into place.).12 F .465(Since the maps are already open the ne)4.466 F +2.465(wm)-.2 G(aps)493.336 689.4 Q(will ne)72 699 Q -.12(ve)-.2 G 2(rb).12 G 2 +(es)109.896 699 S(een.)118.56 699 Q EP +%%Page: 51 46 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-51)452.9 60 Q/F1 10/Times-Roman@0 SF .655 +(appropriate -request address.)189 96 R .656(It is v)5.656 F .656 +(ery similar to the o)-.15 F(wner)-.25 E(-)-.2 E/F2 10/Times-Italic@0 SF(list)A +F1 .656(syntax in the)3.156 F(alias \214le.)189 108 Q 33.95(fullname The)117 +124.2 R(full name of the user)2.5 E(.)-.55 E(of)117 140.4 Q 13.66 +(\214ce-address The)-.25 F(of)2.5 E(\214ce address for this user)-.25 E(.)-.55 +E(of)117 156.6 Q 19.21(\214ce-phone The)-.25 F(of)2.5 E +(\214ce phone number for this user)-.25 E(.)-.55 E(of)117 172.8 Q(\214ce-f)-.25 +E 30.98(ax The)-.1 F(of)2.5 E(\214ce F)-.25 E(AX number for this user)-.74 E(.) +-.55 E 13.96(home-address The)117 189 R(home address for this user)2.5 E(.)-.55 +E 19.51(home-phone The)117 205.2 R(home phone number for this user)2.5 E(.)-.55 +E(home-f)117 221.4 Q 31.28(ax The)-.1 F(home F)2.5 E(AX number for this user) +-.74 E(.)-.55 E 41.73(project A)117 237.6 R .856 +(\(short\) description of the project this person is af)3.356 F .855 +(\214liated with.)-.25 F .855(In the Uni-)5.855 F -.15(ve)189 249.6 S +(rsity this is often just the name of their graduate advisor).15 E(.)-.55 E +52.28(plan A)117 265.8 R +(pointer to a \214le from which plan information can be g)2.5 E(athered.)-.05 E +.924(As of this writing, only a fe)142 282 R 3.424(wo)-.25 G 3.424(ft)273.208 +282 S .925(hese \214elds are actually being used by)282.742 282 R F2(sendmail) +3.425 E F1(:)A F2(mail-)3.425 E(dr)117 294 Q(op)-.45 E F1(and)2.5 E F2 +(mailname)2.5 E F1 5(.A)C F2(\214ng)211.54 294 Q(er)-.1 E F1 +(program that uses the other \214elds is planned.)2.5 E F0 2.5(5.10.2. User)102 +318 R(database semantics)2.5 E F1 .996(When the re)142 334.2 R .995 +(writing rules submit an address to the local mailer)-.25 F 3.495(,t)-.4 G .995 +(he user name is passed)408.93 334.2 R .78(through the alias \214le.)117 346.2 +R .781 +(If no alias is found \(or if the alias points back to the same address\), the) +5.78 F 1.778(name \(with \231:maildrop\232 appended\) is then used as a k)117 +358.2 R 2.077 -.15(ey i)-.1 H 4.277(nt).15 G 1.777(he user database.)375.985 +358.2 R 1.777(If no match)6.777 F +(occurs \(or if the maildrop points at the same address\), forw)117 370.2 Q +(arding is tried.)-.1 E .55(If the \214rst tok)142 386.4 R .551(en of the user\ + name returned by ruleset 0 is an \231@\232 sign, the user database)-.1 F .626 +(lookup is skipped.)117 398.4 R .625 +(The intent is that the user database will act as a set of def)5.626 F .625 +(aults for a cluster)-.1 F 1.533(\(in our case, the Computer Science Di)117 +410.4 R 1.533(vision\); mail sent to a speci\214c machine should ignore)-.25 F +(these def)117 422.4 Q(aults.)-.1 E .351 +(When mail is sent, the name of the sending user is look)142 438.6 R .351 +(ed up in the database.)-.1 F .351(If that user)5.351 F .04 +(has a \231mailname\232 record, the v)117 450.6 R .041 +(alue of that record is used as their outgoing name.)-.25 F -.15(Fo)5.041 G +2.541(re).15 G .041(xample, I)466.189 450.6 R(might ha)117 462.6 Q .3 -.15 +(ve a r)-.2 H(ecord:).15 E 48.29(eric:mailname Eric.Allman@CS.Berk)157 478.8 R +(ele)-.1 E -.65(y.)-.15 G(EDU).65 E(This w)117 495 Q +(ould cause my outgoing mail to be sent as Eric.Allman.)-.1 E .52 +(If a \231maildrop\232 is found for the user)142 511.2 R 3.019(,b)-.4 G .519 +(ut no corresponding \231mailname\232 record e)299.686 511.2 R .519(xists, the) +-.15 F 1.127(record \231:def)117 523.2 R 1.127(ault:mailname\232 is consulted.) +-.1 F 1.127(If present, this is the name of a host to o)6.127 F -.15(ve)-.15 G +1.128(rride the).15 F .625(local host.)117 535.2 R -.15(Fo)5.625 G 3.125(re).15 +G .625(xample, in our case we w)185.515 535.2 R .625 +(ould set it to \231CS.Berk)-.1 F(ele)-.1 E -.65(y.)-.15 G 3.125(EDU\232. The) +.65 F(ef)3.125 E .625(fect is that)-.25 F(an)117 547.2 Q .881(yone kno)-.15 F +.882(wn in the database gets their outgoing mail stamped as \231user@CS.Berk) +-.25 F(ele)-.1 E -.65(y.)-.15 G(EDU\232,).65 E -.2(bu)117 559.2 S 2.5(tp).2 G +(eople not listed in the database use the local hostname.)137.08 559.2 Q F0 2.5 +(5.10.3. Cr)102 585.2 R(eating the database)-.18 E/F3 7/Times-Bold@0 SF(21) +228.2 581.2 Q F1 .375(The user database is b)142 601.4 R .375(uilt from a te) +-.2 F .375(xt \214le using the)-.15 F F2(mak)2.875 E(emap)-.1 E F1 .375 +(utility \(in the distrib)2.875 F .375(ution in)-.2 F 1.039(the mak)117 613.4 R +1.039(emap subdirectory\).)-.1 F 1.039(The te)6.039 F 1.038 +(xt \214le is a series of lines corresponding to userdb records;)-.15 F 1.588 +(each line has a k)117 625.4 R 1.889 -.15(ey a)-.1 H 1.589(nd a v).15 F 1.589 +(alue separated by white space.)-.25 F 1.589(The k)6.589 F 1.889 -.15(ey i)-.1 +H 4.089(sa).15 G -.1(lwa)421.943 625.4 S 1.589(ys in the format).1 F +(described abo)117 637.4 Q .3 -.15(ve \212 f)-.15 H(or e).15 E(xample:)-.15 E +(eric:maildrop)157 653.6 Q .448 +(This \214le is normally installed in a system directory; for e)117 669.8 R +.447(xample, it might be called)-.15 F F2(/etc/user)2.947 E(db)-.37 E F1(.)A +.32 LW 76 679.4 72 679.4 DL 80 679.4 76 679.4 DL 84 679.4 80 679.4 DL 88 679.4 +84 679.4 DL 92 679.4 88 679.4 DL 96 679.4 92 679.4 DL 100 679.4 96 679.4 DL 104 +679.4 100 679.4 DL 108 679.4 104 679.4 DL 112 679.4 108 679.4 DL 116 679.4 112 +679.4 DL 120 679.4 116 679.4 DL 124 679.4 120 679.4 DL 128 679.4 124 679.4 DL +132 679.4 128 679.4 DL 136 679.4 132 679.4 DL 140 679.4 136 679.4 DL 144 679.4 +140 679.4 DL 148 679.4 144 679.4 DL 152 679.4 148 679.4 DL 156 679.4 152 679.4 +DL 160 679.4 156 679.4 DL 164 679.4 160 679.4 DL 168 679.4 164 679.4 DL 172 +679.4 168 679.4 DL 176 679.4 172 679.4 DL 180 679.4 176 679.4 DL 184 679.4 180 +679.4 DL 188 679.4 184 679.4 DL 192 679.4 188 679.4 DL 196 679.4 192 679.4 DL +200 679.4 196 679.4 DL 204 679.4 200 679.4 DL 208 679.4 204 679.4 DL 212 679.4 +208 679.4 DL 216 679.4 212 679.4 DL/F4 5/Times-Roman@0 SF(21)93.6 689.8 Q/F5 8 +/Times-Roman@0 SF .289(These instructions are kno)3.2 J .289 +(wn to be incomplete.)-.2 F 2.289(Af)4.289 G .289(uture v)266.464 693 R .289 +(ersion of the user database is planned including things such as \214n-)-.12 F +(ger service \212 and good documentation.)72 702.6 Q EP +%%Page: 52 47 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-52 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 1.6 -.8(To m)117 +96 T(ak).8 E 2.5(et)-.1 G(he database v)156.65 96 Q +(ersion of the map, run the program:)-.15 E(mak)157 112.2 Q +(emap btree /etc/userdb)-.1 E(.db < /etc/userdb)-.4 E .077 +(Then create a con\214g \214le that uses this.)117 128.4 R -.15(Fo)5.077 G +2.577(re).15 G .077(xample, using the V8 M4 con\214guration, include the) +296.531 128.4 R(follo)117 140.4 Q(wing line in your .mc \214le:)-.25 E +(de\214ne\(\222confUSERDB_SPEC\264, /etc/userdb)157 156.6 Q(.db\))-.4 E F0 2.5 +(6. O)72 184.8 R(THER CONFIGURA)-.4 E(TION)-.95 E F1 .907 +(There are some con\214guration changes that can be made by recompiling)112 201 +R/F2 10/Times-Italic@0 SF(sendmail)3.407 E F1 5.907(.T)C .906(his section) +460.594 201 R 1.139 +(describes what changes can be made and what has to be modi\214ed to mak)87 213 +R 3.639(et)-.1 G 3.639(hem. In)403.894 213 R 1.139(most cases this)3.639 F +(should be unnecessary unless you are porting)87 225 Q F2(sendmail)2.5 E F1 +(to a ne)2.5 E 2.5(we)-.25 G -.4(nv)349.76 225 S(ironment.).4 E F0 2.5(6.1. P) +87 249 R(arameters in sr)-.1 E(c/Mak)-.18 E(e\214le)-.1 E F1 .92 +(These parameters are intended to describe the compilation en)127 265.2 R .92 +(vironment, not site polic)-.4 F 2.22 -.65(y, a)-.15 H(nd).65 E +(should normally be de\214ned in src/Mak)102 277.2 Q(e\214le.)-.1 E 39.5 +(NDBM If)102 293.4 R .664(set, the ne)3.164 F 3.164(wv)-.25 G .664 +(ersion of the DBM library that allo)240.406 293.4 R .665 +(ws multiple databases will be)-.25 F 2.543(used. If)174 305.4 R .042 +(neither NDBM nor NEWDB are set, a much less ef)2.543 F .042 +(\214cient method of alias)-.25 F(lookup is used.)174 317.4 Q 32.84(NEWDB If) +102 333.6 R .141(set, use the ne)2.641 F 2.642(wd)-.25 G .142 +(atabase package from Berk)254.436 333.6 R(ele)-.1 E 2.642(y\()-.15 G .142 +(from 4.4BSD\).)385.814 333.6 R .142(This package)5.142 F .267 +(is substantially f)174 345.6 R .267(aster than DBM or NDBM.)-.1 F .267 +(If NEWDB and NDBM are both set,)5.267 F F2(sendmail)174 357.6 Q F1 +(will read DBM \214les, b)2.5 E(ut will create and use NEWDB \214les.)-.2 E +53.39(NIS Include)102 373.8 R .119(support for NIS.)2.619 F .119 +(If set together with)5.119 F F2(both)2.619 E F1 .119(NEWDB and NDBM,)2.619 F +F2(sendmail)2.62 E F1 .947(will create both DBM and NEWDB \214les if and only \ +if an alias \214le includes the)174 385.8 R 3.409 +(substring \231/yp/\232 in the name.)174 397.8 R 3.409 +(This is intended for compatibility with Sun)8.409 F(Microsystems')174 409.8 Q +F2(mkalias)2.5 E F1(program used on YP masters.)2.5 E 28.94(NISPLUS Compile)102 +426 R(in support for NIS+.)2.5 E 26.73(NETINFO Compile)102 442.2 R +(in support for NetInfo \(NeXT stations\).)2.5 E 32.84(HESIOD Compile)102 458.4 +R(in support for Hesiod.)2.5 E(_P)102 474.6 Q -1.11(AT)-.92 G(H_SENDMAILCF)1.11 +E(The pathname of the sendmail.cf \214le.)174 486.6 Q(_P)102 502.8 Q -1.11(AT) +-.92 G(H_SENDMAILPID)1.11 E(The pathname of the sendmail.pid \214le.)174 514.8 +Q 1.44(There are also se)127 531 R -.15(ve)-.25 G 1.439 +(ral compilation \215ags to indicate the en).15 F 1.439 +(vironment such as \231_AIX3\232 and)-.4 F 2.5(\231_SCO_unix_\232. See)102 543 +R(the READ_ME \214le for the latest scoop on these \215ags.)2.5 E F0 2.5 +(6.2. P)87 567 R(arameters in sr)-.1 E(c/conf)-.18 E(.h)-.15 E F1 -.15(Pa)127 +583.2 S .895(rameters and compilation options are de\214ned in conf.h.).15 F +.896(Most of these need not normally)5.895 F .193(be tweak)102 595.2 R .192 +(ed; common parameters are all in sendmail.cf.)-.1 F(Ho)5.192 E(we)-.25 E -.15 +(ve)-.25 G .992 -.4(r, t).15 H .192(he sizes of certain primiti).4 F .492 -.15 +(ve ve)-.25 H(c-).15 E(tors, etc., are included in this \214le.)102 607.2 Q +(The numbers follo)5 E(wing the parameters are their def)-.25 E(ault v)-.1 E +(alue.)-.25 E 1.247(This document is not the best source of information for co\ +mpilation \215ags in conf.h \212 see)127 623.4 R +(src/READ_ME or src/conf.h itself.)102 635.4 Q 1.91(MAXLINE [2048])102 651.6 R +1.909(The maximum line length of an)190.31 651.6 R 4.409(yi)-.15 G 1.909 +(nput line.)338.276 651.6 R 1.909(If message lines e)6.909 F 1.909(xceed this) +-.15 F .575(length the)188.4 663.6 R 3.075(yw)-.15 G .575 +(ill still be processed correctly; ho)243.84 663.6 R(we)-.25 E -.15(ve)-.25 G +1.375 -.4(r, h).15 H .575(eader lines, con\214gura-).4 F +(tion \214le lines, alias lines, etc., must \214t within this limit.)188.4 +675.6 Q(MAXN)102 691.8 Q(AME [256])-.35 E(The maximum length of an)9.82 E 2.5 +(yn)-.15 G(ame, such as a host or a user name.)309.63 691.8 Q .231(MAXPV [40]) +102 708 R .231(The maximum number of parameters to an)188.631 708 R 2.731(ym) +-.15 G(ailer)376.458 708 Q 5.231(.T)-.55 G .23(his limits the number of)407.519 +708 R .375(recipients that may be passed in one transaction.)188.4 720 R .376 +(It can be set to an)5.376 F 2.876(ya)-.15 G(rbitrary)474.01 720 Q EP +%%Page: 53 48 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-53)452.9 60 Q/F1 10/Times-Roman@0 SF .876(number abo)188.4 96 R 1.176 +-.15(ve a)-.15 H .876(bout 10, since).15 F/F2 10/Times-Italic@0 SF(sendmail) +3.376 E F1 .876(will break up a deli)3.376 F -.15(ve)-.25 G .875 +(ry into smaller).15 F .886(batches as needed.)188.4 108 R 3.386(Ah)5.886 G +.887(igher number may reduce load on your system, ho)285.804 108 R(w-)-.25 E +-2.15 -.25(ev e)188.4 120 T -.55(r.).25 G(MAXA)102 136.2 Q -.18(TO)-1.11 G +2.559(M[).18 G 8.26(100] The)159.369 136.2 R .059 +(maximum number of atoms \(tok)2.559 F .058(ens\) in a single address.)-.1 F +-.15(Fo)5.058 G 2.558(re).15 G .058(xample, the)457.282 136.2 R +(address \231eric@CS.Berk)188.4 148.2 Q(ele)-.1 E -.65(y.)-.15 G(EDU\232 is se) +.65 E -.15(ve)-.25 G 2.5(na).15 G(toms.)367.93 148.2 Q .112(MAXMAILERS [25])102 +164.4 R .112(The maximum number of mailers that may be de\214ned in the con\ +\214guration \214le.).02 F(MAXR)102 180.6 Q .401(WSETS [200])-.55 F .401 +(The maximum number of re).01 F .401(writing sets that may be de\214ned.)-.25 F +.4(The \214rst half of)5.4 F .034(these are reserv)188.4 192.6 R .034 +(ed for numeric speci\214cation \(e.g., `)-.15 F(`S92')-.74 E .035 +('\), while the upper half)-.74 F .492(are reserv)188.4 204.6 R .492 +(ed for auto-numbering \(e.g., `)-.15 F(`Sfoo')-.74 E 2.992('\). Thus,)-.74 F +.492(with a v)2.992 F .491(alue of 200 an)-.25 F(attempt to use `)188.4 216.6 Q +(`S99')-.74 E 2.5('w)-.74 G(ill succeed, b)284.13 216.6 Q(ut `)-.2 E(`S100') +-.74 E 2.5('w)-.74 G(ill f)388.82 216.6 Q(ail.)-.1 E(MAXPRIORITIES [25])102 +232.8 Q 2.481(The maximum number of v)188.4 244.8 R 2.482 +(alues for the \231Precedence:\232 \214eld that may be)-.25 F +(de\214ned \(using the)188.4 256.8 Q F0(P)2.5 E F1(line in sendmail.cf\).)2.5 E +(MAXUSERENVIR)102 273 Q(ON [100])-.4 E .399 +(The maximum number of items in the user en)188.4 285 R .399 +(vironment that will be passed to)-.4 F(subordinate mailers.)188.4 297 Q +(MAXMXHOSTS [20])102 313.2 Q +(The maximum number of MX records we will accept for an)188.4 325.2 Q 2.5(ys) +-.15 G(ingle host.)439.03 325.2 Q .712(MAXALIASDB [12])102 341.4 R .712 +(The maximum number of alias databases that can be open at an).58 F 3.213(yt) +-.15 G 3.213(ime. Note)461.347 341.4 R +(that there may also be an open \214le limit.)188.4 353.4 Q(MAXMAPST)102 369.6 +Q -.4(AC)-.93 G 2.5(K[).4 G(12])184.28 369.6 Q 1.65 +(The maximum number of maps that may be "stack)188.4 381.6 R 1.65(ed" in a)-.1 +F F0(sequence)4.15 E F1(class)4.15 E(map.)188.4 393.6 Q(MAXMIMEARGS [20])102 +409.8 Q .718(The maximum number of ar)188.4 421.8 R .718 +(guments in a MIME Content-T)-.18 F .718(ype: header; addi-)-.8 F(tional ar) +188.4 433.8 Q(guments will be ignored.)-.18 E(MAXMIMENESTING [20])102 450 Q .4 +(The maximum depth to which MIME messages may be nested \(that is, nested)188.4 +462 R 1.344 +(Message or Multipart documents; this does not limit the number of compo-)188.4 +474 R(nents in a single Multipart document\).)188.4 486 Q 2.851(An)102 502.2 S +.351(umber of other compilation options e)117.071 502.2 R 2.851(xist. These) +-.15 F .35(specify whether or not speci\214c code should be)2.851 F +(compiled in.)102 514.2 Q(Ones mark)5 E(ed with \207 are 0/1 v)-.1 E(alued.) +-.25 E 36.69(NETINET\207 If)102 530.4 R .829 +(set, support for Internet protocol netw)3.329 F .829(orking is compiled in.) +-.1 F(Pre)5.829 E .83(vious v)-.25 F(er)-.15 E(-)-.2 E .178(sions of)188.4 +542.4 R F2(sendmail)2.678 E F1 .178(referred to this as)2.678 F/F3 9 +/Times-Roman@0 SF -.36(DA)2.678 G(EMON).36 E F1 2.677(;t)C .177 +(his old usage is no)381.715 542.4 R 2.677(wi)-.25 G(ncorrect.)468.74 542.4 Q +(Def)188.4 554.4 Q 1.87(aults on; turn it of)-.1 F 4.37(fi)-.25 G 4.37(nt) +292.67 554.4 S 1.87(he Mak)304.82 554.4 R 1.87(e\214le if your system doesn') +-.1 F 4.37(ts)-.18 G 1.87(upport the)461.3 554.4 R(Internet protocols.)188.4 +566.4 Q 43.35(NETISO\207 If)102 582.6 R .143 +(set, support for ISO protocol netw)2.643 F .142 +(orking is compiled in \(it may be appropri-)-.1 F +(ate to #de\214ne this in the Mak)188.4 594.6 Q(e\214le instead of conf.h\).) +-.1 E 63.35(LOG If)102 610.8 R .5(set, the)3 F F2(syslo)3 E(g)-.1 E F1 .5 +(routine in use at some sites is used.)3 F .5(This mak)5.5 F .5(es an informa-) +-.1 F .504(tional log record for each message processed, and mak)188.4 622.8 R +.504(es a higher priority log)-.1 F .052(record for internal system errors.) +188.4 634.8 R F0(STR)5.052 E(ONGL)-.3 E 2.552(YR)-.92 G(ECOMMENDED)389.682 +634.8 Q F1 2.553<8a69>2.552 G 2.553(fy)483.117 634.8 S(ou)494 634.8 Q -.1(wa) +188.4 646.8 S(nt no logging, turn it of).1 E 2.5(fi)-.25 G 2.5(nt)301.66 646.8 +S(he con\214guration \214le.)311.94 646.8 Q(MA)102 663 Q 11.12 +(TCHGECOS\207 Compile)-1.11 F 3.555(in the code to do `)6.055 F 3.555 +(`fuzzy matching')-.74 F 6.055('o)-.74 G 6.055(nt)404.22 663 S 3.555 +(he GECOS \214eld in)418.055 663 R 2.5(/etc/passwd. This)188.4 675 R +(also requires that the)2.5 E F0(MatchGECOS)2.5 E F1(option be turned on.)2.5 E +-.35(NA)102 691.2 S 13.15(MED_BIND\207 Compile).35 F .412 +(in code to use the Berk)2.912 F(ele)-.1 E 2.913(yI)-.15 G .413 +(nternet Name Domain \(BIND\) serv)342.405 691.2 R .413(er to)-.15 F(resolv) +188.4 703.2 Q 2.5(eT)-.15 G(CP/IP host names.)225.74 703.2 Q EP +%%Page: 54 49 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-54 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(NO)102 96 Q +38.76(TUNIX If)-.4 F .248 +(you are using a non-UNIX mail format, you can set this \215ag to turn of)2.748 +F 2.747(fs)-.25 G(pe-)491.23 96 Q +(cial processing of UNIX-style \231From \232 lines.)188.4 108 Q -.1(QU)102 +124.2 S 50.12(EUE This).1 F 1.559 +(\215ag should be set to compile in the queueing code.)4.059 F 1.56 +(If this is not set,)6.56 F +(mailers must accept the mail immediately or it will be returned to the sender) +188.4 136.2 Q(.)-.55 E 57.78(SMTP If)102 152.4 R .756 +(set, the code to handle user and serv)3.256 F .756 +(er SMTP will be compiled in.)-.15 F .756(This is)5.756 F 2.507 +(only necessary if your machine has some mailer that speaks SMTP \(this)188.4 +164.4 R(means most machines e)188.4 176.4 Q -.15(ve)-.25 G(rywhere\).).15 E +39.45(USERDB\207 Include)102 192.6 R(the)3.449 E F0(experimental)3.449 E F1 +(Berk)3.449 E(ele)-.1 E 3.449(yu)-.15 G .949(ser information database package.) +341.356 192.6 R(This)5.948 E .27(adds a ne)188.4 204.6 R 2.77(wl)-.25 G -2.15 +-.25(ev e)238.67 204.6 T 2.77(lo).25 G 2.77(fl)262.7 204.6 S .27(ocal name e) +271.58 204.6 R .27(xpansion between aliasing and forw)-.15 F 2.77(arding. It) +-.1 F(also uses the NEWDB package.)188.4 216.6 Q +(This may change in future releases.)5 E(The follo)102 232.8 Q +(wing options are normally turned on in per)-.25 E +(-operating-system clauses in conf.h.)-.2 E(IDENTPR)102 249 Q -1.88 -.4(OT O) +-.4 H 19.61<8743>.4 G .376 +(ompile in the IDENT protocol as de\214ned in RFC 1413.)195.07 249 R .375 +(This def)5.375 F .375(aults on for)-.1 F 1.053(all systems e)188.4 261 R 1.053 +(xcept Ultrix, which apparently has the interesting \231feature\232 that)-.15 F +.83(when it recei)188.4 273 R -.15(ve)-.25 G 3.33(sa\231).15 G .83 +(host unreachable\232 message it closes all open connections)270.18 273 R 1.921 +(to that host.)188.4 285 R 1.921(Since some \214re)6.921 F -.1(wa)-.25 G 1.922 +(ll g).1 F(ate)-.05 E -.1(wa)-.25 G 1.922(ys send this error code when you).1 F +2.055 +(access an unauthorized port \(such as 113, used by IDENT\), Ultrix cannot) +188.4 297 R(recei)188.4 309 Q .3 -.15(ve e)-.25 H(mail from such hosts.).15 E +39.45(SYSTEM5 Set)102 325.2 R +(all of the compilation parameters appropriate for System V)2.5 E(.)-1.29 E +26.12(HASFLOCK\207 Use)102 341.4 R(Berk)2.844 E(ele)-.1 E(y-style)-.15 E F0 +(\215ock)2.844 E F1 .344(instead of System V)2.844 F F0(lockf)2.845 E F1 .345 +(to do \214le locking.)2.845 F .345(Due to)5.345 F .184 +(the highly unusual semantics of locks across forks in)188.4 353.4 R F0(lockf) +2.684 E F1 2.684(,t)C .184(his should al)432.722 353.4 R -.1(wa)-.1 G(ys).1 E +(be used if at all possible.)188.4 365.4 Q(HASINITGR)102 381.6 Q 4.86(OUPS Set) +-.4 F 1.284(this if your system has the)3.783 F/F2 10/Times-Italic@0 SF(initgr) +3.784 E(oups\(\))-.45 E F1 1.284(call \(if you ha)3.784 F 1.584 -.15(ve m)-.2 H +1.284(ultiple group).15 F 4.417(support\). This)188.4 393.6 R 1.917(is the def) +4.417 F 1.917(ault if SYSTEM5 is)-.1 F F2(not)4.416 E F1 1.916 +(de\214ned or if you are on)4.416 F(HPUX.)188.4 405.6 Q(HASUN)102 421.8 Q 27.59 +(AME Set)-.35 F 1.148(this if you ha)3.648 F 1.448 -.15(ve t)-.2 H(he).15 E F2 +(uname)3.648 E F1 1.149(\(2\) system call \(or corresponding library rou-)B 2.5 +(tine\). Set)188.4 433.8 R(by def)2.5 E(ault if SYSTEM5 is set.)-.1 E(HASGETDT) +102 450 Q(ABLESIZE)-.93 E(Set this if you ha)188.4 462 Q .3 -.15(ve t)-.2 H(he) +.15 E F2 -.1(ge)2.5 G(tdtablesize).1 E F1(\(2\) system call.)A(HASW)102 478.2 Q +22.89(AITPID Set)-1.2 F(this if you ha)2.5 E .3 -.15(ve t)-.2 H(he).15 E F2 +(haswaitpid)2.5 E F1(\(2\) system call.)A 37.22(SFS_TYPE The)102 494.4 R .517 +(mechanism that can be used to get \214le system capacity information.)3.017 F +(The)5.516 E -.25(va)188.4 506.4 S .214(lues can be one of SFS_UST).25 F 2.435 +-1.11(AT \()-.93 H .215(use the ustat\(2\) syscall\), SFS_4ARGS \(use)1.11 F +.415(the four ar)188.4 518.4 R .415 +(gument statfs\(2\) syscall\), SFS_VFS \(use the tw)-.18 F 2.915(oa)-.1 G -.18 +(rg)435.165 518.4 S .415(ument statfs\(2\)).18 F .716 +(syscall including <sys/vfs.h>\), SFS_MOUNT \(use the tw)188.4 530.4 R 3.217 +(oa)-.1 G -.18(rg)434.863 530.4 S .717(ument statfs\(2\)).18 F 4.32 +(syscall including <sys/mount.h>\), SFS_ST)188.4 542.4 R -1.11(AT)-.93 G 4.32 +(FS \(use the tw)1.11 F 6.82(oa)-.1 G -.18(rg)470.85 542.4 S(ument).18 E 1.108 +(statfs\(2\) syscall including <sys/statfs.h>\), SFS_ST)188.4 554.4 R -1.11(AT) +-.93 G 1.109(VFS \(use the tw)1.11 F 3.609(oa)-.1 G -.18(rg)487.52 554.4 S(u-) +.18 E 1.511 +(ment statfs\(2\) syscall including <sys/statvfs.h>\), or SFS_NONE \(no w)188.4 +566.4 R 1.511(ay to)-.1 F(get this information\).)188.4 578.4 Q 40.57 +(LA_TYPE The)102 594.6 R(load a)2.5 E -.15(ve)-.2 G(rage type.).15 E +(Details are described belo)5 E -.65(w.)-.25 G .342(The are se)102 610.8 R -.15 +(ve)-.25 G .342(ral b).15 F .342(uilt-in w)-.2 F .342 +(ays of computing the load a)-.1 F -.15(ve)-.2 G(rage.).15 E F2(Sendmail)5.342 +E F1 .343(tries to auto-con\214gure them)2.842 F .267 +(based on imperfect guesses; you can select one using the)102 622.8 R F2(cc) +2.766 E F1(option)2.766 E F0(\255DLA_TYPE=)2.766 E F2(type)A F1 2.766(,w)C +(here)467.364 622.8 Q F2(type)2.766 E F1(is:)102 634.8 Q 48.91(LA_INT The)102 +651 R -.1(ke)3.452 G .952(rnel stores the load a).1 F -.15(ve)-.2 G .952 +(rage in the k).15 F .952(ernel as an array of long inte)-.1 F(gers.)-.15 E +(The actual v)188.4 663 Q(alues are scaled by a f)-.25 E(actor FSCALE \(def)-.1 +E(ault 256\).)-.1 E(LA_SHOR)102 679.2 Q 35.89(TT)-.6 G .794(he k)194.51 679.2 R +.794(ernel stores the load a)-.1 F -.15(ve)-.2 G .794(rage in the k).15 F .793 +(ernel as an array of short inte)-.1 F(gers.)-.15 E(The actual v)188.4 691.2 Q +(alues are scaled by a f)-.25 E(actor FSCALE \(def)-.1 E(ault 256\).)-.1 E +(LA_FLO)102 707.4 Q 37.03 -1.11(AT T)-.35 H .088(he k)1.11 F .088 +(ernel stores the load a)-.1 F -.15(ve)-.2 G .089(rage in the k).15 F .089 +(ernel as an array of double precision)-.1 F(\215oats.)188.4 719.4 Q EP +%%Page: 55 50 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-55)452.9 60 Q/F1 10/Times-Roman@0 SF(LA_MA)102 96 Q 35.97(CH Use)-.4 F +(MA)2.5 E(CH-style load a)-.4 E -.15(ve)-.2 G(rages.).15 E 39.45(LA_SUBR Call) +102 112.2 R(the)2.5 E/F2 10/Times-Italic@0 SF -.1(ge)2.5 G(tloadavg).1 E F1 +(routine to get the load a)2.5 E -.15(ve)-.2 G(rage as an array of doubles.).15 +E(LA_ZER)102 128.4 Q 42.36(OA)-.4 G -.1(lwa)195.62 128.4 S +(ys return zero as the load a).1 E -.15(ve)-.2 G 2.5(rage. This).15 F(is the f) +2.5 E(allback case.)-.1 E .494(If type)102 144.6 R/F3 9/Times-Roman@0 SF +(LA_INT)2.994 E F1(,)A F3(LA_SHOR)2.994 E(T)-.54 E F1 2.994(,o)C(r)224.806 +144.6 Q F3(LA_FLO)2.993 E -.999(AT)-.315 G F1 .493 +(is speci\214ed, you may also need to specify)3.992 F F3(_P)2.993 E -.999(AT) +-.828 G(H_UNIX).999 E F1 .948(\(the path to your system binary\) and)102 156.6 +R F3(LA_A)3.448 E(VENR)-1.215 E(UN)-.36 E F1 .949(\(the name of the v)3.448 F +.949(ariable containing the load)-.25 F -2.25 -.2(av e)102 168.6 T +(rage in the k).2 E(ernel; usually \231_a)-.1 E -.15(ve)-.2 G +(nrun\232 or \231a).15 E -.15(ve)-.2 G(nrun\232\).).15 E F0 2.5 +(6.3. Con\214guration)87 192.6 R(in sr)2.5 E(c/conf)-.18 E(.c)-.15 E F1 +(The follo)127 208.8 Q(wing changes can be made in conf.c.)-.25 E F0 2.5 +(6.3.1. Built-in)102 232.8 R(Header Semantics)2.5 E F1 1.248 +(Not all header semantics are de\214ned in the con\214guration \214le.)142 249 +R 1.247(Header lines that should)6.247 F .305(only be included by certain mail\ +ers \(as well as other more obscure semantics\) must be speci\214ed)117 261 R +.047(in the)117 273 R F2(HdrInfo)2.547 E F1 .047(table in)2.547 F F2(conf)2.547 +E(.c)-.15 E F1 5.047(.T)C .046 +(his table contains the header name \(which should be in all lo)246.842 273 R +(wer)-.25 E(case\) and a set of header control \215ags \(described belo)117 285 +Q(w\), The \215ags are:)-.25 E(H_A)117 301.2 Q 30.97(CHECK Normally)-.4 F .007 +(when the check is made to see if a header line is compatible with)2.507 F +2.941(am)203.4 313.2 S(ailer)218.561 313.2 Q(,)-.4 E F2(sendmail)2.941 E F1 +.441(will not delete an e)2.941 F .441(xisting line.)-.15 F .44 +(If this \215ag is set,)5.441 F F2(send-)2.94 E(mail)203.4 325.2 Q F1 .152 +(will delete e)2.652 F -.15(ve)-.25 G 2.652(ne).15 G .152 +(xisting header lines.)293.998 325.2 R .152 +(That is, if this bit is set and the)5.152 F 1.425(mailer does not ha)203.4 +337.2 R 1.725 -.15(ve \215)-.2 H 1.425 +(ag bits set that intersect with the required mailer).15 F 2.204 +(\215ags in the header de\214nition in sendmail.cf, the header line is)203.4 +349.2 R F2(always)4.704 E F1(deleted.)203.4 361.2 Q 51.13(H_EOH If)117 377.4 R +.206(this header \214eld is set, treat it lik)2.706 F 2.706(eab)-.1 G .206 +(lank line, i.e., it will signal the end)363.95 377.4 R +(of the header and the be)203.4 389.4 Q(ginning of the message te)-.15 E(xt.) +-.15 E 39.45(H_FORCE Add)117 405.6 R 2.038(this header entry e)4.538 F -.15(ve) +-.25 G 4.538(ni).15 G 4.538(fo)326.22 405.6 S 2.038(ne e)339.088 405.6 R 2.039 +(xisted in the message before.)-.15 F 2.039(If a)7.039 F 2.189 +(header entry does not ha)203.4 417.6 R 2.488 -.15(ve t)-.2 H 2.188 +(his bit set,).15 F F2(sendmail)4.688 E F1 2.188(will not add another)4.688 F +.62(header line if a header line of this name already e)203.4 429.6 R 3.12 +(xisted. This)-.15 F -.1(wo)3.12 G .62(uld nor).1 F(-)-.2 E +(mally be used to stamp the message by e)203.4 441.6 Q -.15(ve)-.25 G +(ryone who handled it.).15 E(H_TRA)117 457.8 Q 39.3(CE If)-.4 F 1.044 +(set, this is a timestamp \(trace\) \214eld.)3.544 F 1.043 +(If the number of trace \214elds in a)6.043 F .705(message e)203.4 469.8 R .705 +(xceeds a preset amount the message is returned on the assump-)-.15 F +(tion that it has an aliasing loop.)203.4 481.8 Q 46.67(H_RCPT If)117 498 R +.332(set, this \214eld contains recipient addresses.)2.833 F .332 +(This is used by the)5.332 F F0<ad74>2.832 E F1 .332(\215ag to)2.832 F 1.349 +(determine who to send to when it is collecting recipients from the mes-)203.4 +510 R(sage.)203.4 522 Q(H_FR)117 538.2 Q 43.74(OM This)-.4 F 1.673 +(\215ag indicates that this \214eld speci\214es a sender)4.174 F 6.673(.T)-.55 +G 1.673(he order of these)432.061 538.2 R .898(\214elds in the)203.4 550.2 R F2 +(HdrInfo)3.398 E F1 .898(table speci\214es)3.398 F F2(sendmail)3.398 E F1 1.998 +-.55('s p)D .898(reference for which \214eld).55 F +(to return error messages to.)203.4 562.2 Q(H_ERR)117 578.4 Q(ORST)-.4 E 22.53 +(OA)-.18 G(ddresses in this header should recei)210.62 578.4 Q .3 -.15(ve e) +-.25 H(rror messages.).15 E 52.79(H_CTE This)117 594.6 R(header is a Content-T) +2.5 E(ransfer)-.35 E(-Encoding header)-.2 E(.)-.55 E 40.01(H_CTYPE This)117 +610.8 R(header is a Content-T)2.5 E(ype header)-.8 E(.)-.55 E(H_STRIPV)117 627 +Q 25.25(AL Strip)-1.35 F(the v)2.5 E(alue from the header \(for Bcc:\).)-.25 E +(Let')117 643.2 Q 2.5(sl)-.55 G(ook at a sample)142.28 643.2 Q F2(HdrInfo)2.5 E +F1(speci\214cation:)2.5 E EP +%%Page: 56 51 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-56 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(struct hdrinfo) +157 96 Q(HdrInfo[] =)295.76 96 Q({)157 108 Q +(/* originator \214elds, most to least signi\214cant)189.5 120 Q(*/)5 E 52.29 +("resent-sender", H_FR)177 132 R(OM,)-.4 E 58.95("resent-from", H_FR)177 144 R +(OM,)-.4 E 79.5("sender", H_FR)177 156 R(OM,)-.4 E 86.16("from", H_FR)177 168 R +(OM,)-.4 E 66.72("full-name", H_A)177 180 R(CHECK,)-.4 E 71.17 +("errors-to", H_FR)177 192 R -1.667(OM | H_ERR)-.4 F(ORST)-.4 E(O,)-.18 E +(/* destination \214elds */)189.5 204 Q 97.82("to", H_RCPT)177 216 R(,)-.74 E +70.61("resent-to", H_RCPT)177 228 R(,)-.74 E 96.72("cc", H_RCPT)177 240 R(,) +-.74 E 91.72("bcc", H_RCPT)177 252 R .833(|H).833 G(_STRIPV)-.833 E(AL,)-1.35 E +(/* message identi\214cation and control */)189.5 264 Q 71.72 +("message", H_EOH,)177 276 R("te)177 288 Q 90.75(xt", H_EOH,)-.15 F +(/* trace \214elds */)189.5 300 Q("recei)177 312 Q -.15(ve)-.25 G 72.13 +(d", H_TRA).15 F -1.667(CE | H_FORCE,)-.4 F(/* miscellaneous \214elds */)189.5 +324 Q("content-transfer)177 336 Q 2.5(-encoding", H_CTE,)-.2 F 55.61 +("content-type", H_CTYPE,)177 348 R 87.1(NULL, 0,)177 372 R(};)157 384 Q 2.435 +(This structure indicates that the \231T)117 400.2 R 2.435 +(o:\232, \231Resent-T)-.8 F 2.435 +(o:\232, and \231Cc:\232 \214elds all specify recipient)-.8 F 3.161 +(addresses. An)117 412.2 R 3.161<7999>-.15 G .662(Full-Name:\232 \214eld will \ +be deleted unless the required mailer \215ag \(indicated in)188.152 412.2 R +.246(the con\214guration \214le\) is speci\214ed.)117 424.2 R .245 +(The \231Message:\232 and \231T)5.246 F -.15(ex)-.7 G .245 +(t:\232 \214elds will terminate the header;).15 F 1.936 +(these are used by random dissenters around the netw)117 436.2 R 1.936(ork w) +-.1 F 4.436(orld. The)-.1 F(\231Recei)4.436 E -.15(ve)-.25 G 1.937 +(d:\232 \214eld will).15 F(al)117 448.2 Q -.1(wa)-.1 G +(ys be added, and can be used to trace messages.).1 E .446 +(There are a number of important points here.)142 464.4 R .445 +(First, header \214elds are not added automati-)5.446 F .656 +(cally just because the)117 476.4 R 3.156(ya)-.15 G .656(re in the)216.674 +476.4 R/F2 10/Times-Italic@0 SF(HdrInfo)3.157 E F1 .657(structure; the)3.157 F +3.157(ym)-.15 G .657(ust be speci\214ed in the con\214guration)358.225 476.4 R +.728(\214le in order to be added to the message.)117 488.4 R(An)5.727 E 3.227 +(yh)-.15 G .727(eader \214elds mentioned in the con\214guration \214le)312.988 +488.4 R -.2(bu)117 500.4 S 3.24(tn).2 G .74(ot mentioned in the)137.82 500.4 R +F2(HdrInfo)3.24 E F1 .74(structure ha)3.24 F 1.04 -.15(ve d)-.2 H(ef).15 E .74 +(ault processing performed; that is, the)-.1 F 3.24(ya)-.15 G(re)496.23 500.4 Q +1.375(added unless the)117 512.4 R 3.875(yw)-.15 G 1.375 +(ere in the message already)201.795 512.4 R 6.375(.S)-.65 G 1.374(econd, the) +326.6 512.4 R F2(HdrInfo)3.874 E F1 1.374(structure only speci\214es)3.874 F +.324 +(cliched processing; certain headers are processed specially by ad hoc code re) +117 524.4 R -.05(ga)-.15 G .325(rdless of the sta-).05 F .481 +(tus speci\214ed in)117 536.4 R F2(HdrInfo)2.981 E F1 5.481(.F)C .481(or e) +226.554 536.4 R .481 +(xample, the \231Sender:\232 and \231From:\232 \214elds are al)-.15 F -.1(wa) +-.1 G .48(ys scanned on).1 F(ARP)117 550.4 Q .751 +(ANET mail to determine the sender)-.92 F/F3 7/Times-Roman@0 SF(22)282.315 +546.4 Q F1 3.251(;t)289.315 550.4 S .75 +(his is used to perform the \231return to sender\232 func-)298.126 550.4 R +2.976(tion. The)117 562.4 R .476(\231From:\232 and \231Full-Name:\232 \214elds\ + are used to determine the full name of the sender if)2.976 F +(possible; this is stored in the macro)117 574.4 Q F0($x)2.5 E F1 +(and used in a number of w)2.5 E(ays.)-.1 E F0 2.5(6.3.2. Restricting)102 598.4 +R(Use of Email)2.5 E F1 .15 +(If it is necessary to restrict mail through a relay)142 614.6 R 2.649(,t)-.65 +G(he)339.755 614.6 Q F2 -.15(ch)2.649 G(ec).15 E(kcompat)-.2 E F1 .149 +(routine can be modi\214ed.)2.649 F .163(This routine is called for e)117 626.6 +R -.15(ve)-.25 G .163(ry recipient address.).15 F .163(It returns an e)5.163 F +.163(xit status indicating the status of)-.15 F .895(the message.)117 638.6 R +.895(The status)5.895 F/F4 9/Times-Roman@0 SF(EX_OK)3.395 E F1 .895 +(accepts the address,)3.395 F F4(EX_TEMPF)3.395 E(AIL)-.666 E F1 .895 +(queues the message for a)3.395 F .263(later try)117 650.6 R 2.763(,a)-.65 G +.263(nd other v)157.696 650.6 R .264(alues \(commonly)-.25 F F4(EX_UN)2.764 E +-1.215(AVA)-.315 G(ILABLE)1.215 E F1 2.764(\)r)C .264(eject the message.) +358.372 650.6 R .264(It is up to)5.264 F F2 -.15(ch)2.764 G(ec).15 E(k-)-.2 E +(compat)117 662.6 Q F1 2.477(to print an error message \(using)4.978 F F2(usr) +4.977 E(err)-.37 E F1 4.977(\)i)C 4.977(ft)331.418 662.6 S 2.477 +(he message is rejected.)342.505 662.6 R -.15(Fo)7.477 G 4.977(re).15 G +(xample,)472.06 662.6 Q .32 LW 76 672.2 72 672.2 DL 80 672.2 76 672.2 DL 84 +672.2 80 672.2 DL 88 672.2 84 672.2 DL 92 672.2 88 672.2 DL 96 672.2 92 672.2 +DL 100 672.2 96 672.2 DL 104 672.2 100 672.2 DL 108 672.2 104 672.2 DL 112 +672.2 108 672.2 DL 116 672.2 112 672.2 DL 120 672.2 116 672.2 DL 124 672.2 120 +672.2 DL 128 672.2 124 672.2 DL 132 672.2 128 672.2 DL 136 672.2 132 672.2 DL +140 672.2 136 672.2 DL 144 672.2 140 672.2 DL 148 672.2 144 672.2 DL 152 672.2 +148 672.2 DL 156 672.2 152 672.2 DL 160 672.2 156 672.2 DL 164 672.2 160 672.2 +DL 168 672.2 164 672.2 DL 172 672.2 168 672.2 DL 176 672.2 172 672.2 DL 180 +672.2 176 672.2 DL 184 672.2 180 672.2 DL 188 672.2 184 672.2 DL 192 672.2 188 +672.2 DL 196 672.2 192 672.2 DL 200 672.2 196 672.2 DL 204 672.2 200 672.2 DL +208 672.2 204 672.2 DL 212 672.2 208 672.2 DL 216 672.2 212 672.2 DL/F5 5 +/Times-Roman@0 SF(22)93.6 682.6 Q/F6 8/Times-Roman@0 SF(Actually)3.2 I 2.631 +(,t)-.52 G .631 +(his is no longer true in SMTP; this information is contained in the en)132.487 +685.8 R -.12(ve)-.32 G 2.632(lope. The).12 F .632(older ARP)2.632 F .632 +(ANET protocols did)-.736 F(not completely distinguish en)72 695.4 Q -.12(ve) +-.32 G(lope from header).12 E(.)-.44 E EP +%%Page: 57 52 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-57)452.9 60 Q/F1 10/Times-Italic@0 SF -.15(ch)117 96 S(ec).15 E +(kcompat)-.2 E/F2 10/Times-Roman@0 SF(could read:)2.5 E/F3 9/Times-Roman@0 SF +(int)157 111 Q(checkcompat\(to, e\))157 121.8 Q(re)175 132.6 Q +(gister ADDRESS *to;)-.135 E(re)175 143.4 Q(gister ENVELOPE *e;)-.135 E({)157 +154.2 Q(re)175 165 Q(gister ST)-.135 E(AB *s;)-.837 E 2.25(s=s)175 186.6 S +(tab\("pri)191.578 186.6 Q -.225(va)-.225 G(te", ST_MAILER, ST_FIND\);).225 E +(if \(s != NULL && e\255>e_from.q_mailer != LocalMailer &&)175 197.4 Q +(to->q_mailer == s->s_mailer\))184 208.2 Q({)175 219 Q(usrerr\("No pri)193 +229.8 Q -.225(va)-.225 G(te net mail allo).225 E(wed through this machine"\);) +-.225 E(return \(EX_UN)193 240.6 Q -1.215(AVA)-.315 G(ILABLE\);)1.215 E(})175 +251.4 Q(if \(MsgSize > 50000 && bitnset\(M_LOCALMAILER, to\255>q_mailer\)\))175 +262.2 Q({)175 273 Q(usrerr\("Message too lar)193 283.8 Q(ge for non-local deli) +-.162 E -.135(ve)-.225 G(ry"\);).135 E(e\255>e_\215ags |= EF_NORETURN;)193 +294.6 Q(return \(EX_UN)193 305.4 Q -1.215(AVA)-.315 G(ILABLE\);)1.215 E(})175 +316.2 Q(return \(EX_OK\);)175 327 Q(})157 337.8 Q F2 5.146(This w)117 354 R +5.147(ould reject messages greater than 50000 bytes unless the)-.1 F 7.647(yw) +-.15 G 5.147(ere local.)436.506 354 R(The)488.45 354 Q F1(EF_NORETURN)117 366 Q +F2 .942(\215ag can be set in)3.442 F F1(e)3.441 E/F4 10/Symbol SF<ae>A F1 +(e_\215a)A(gs)-.1 E F2 .941(to suppress the return of the actual body of the) +3.441 F .128(message in the error return.)117 378 R .129 +(The actual use of this routine is highly dependent on the implemen-)5.129 F +(tation, and use should be limited.)117 390 Q F0 2.5(6.3.3. Load)102 414 R -.6 +-1(Av e)2.5 H(rage Computation)1 E F2 .18(The routine)142 430.2 R F1 -.1(ge) +2.68 G(tla).1 E F2 .18 +(should return an approximation of the current system load a)2.68 F -.15(ve)-.2 +G .18(rage as an).15 F(inte)117 442.2 Q(ger)-.15 E 5(.T)-.55 G(here are se) +157.68 442.2 Q -.15(ve)-.25 G(ral v).15 E +(ersions included on compilation \215ags as described abo)-.15 E -.15(ve)-.15 G +(.).15 E F0 2.5(6.3.4. New)102 466.2 R(Database Map Classes)2.5 E F2(Ne)142 +482.4 Q 2.875(wk)-.25 G .675 -.15(ey m)168.405 482.4 T .375(aps can be added b\ +y creating a class initialization function and a lookup func-).15 F 2.5 +(tion. These)117 494.4 R(are then added to the routine)2.5 E F1(setupmaps.)2.5 +E F2(The initialization function is called as)142 510.6 Q F1(xxx)157 526.8 Q F2 +(_map_init\(MAP *map, char *mapname, char *ar)A(gs\))-.18 E(The)117 543 Q F1 +(map)2.555 E F2 .055(is an internal data structure.)2.555 F(The)5.055 E F1 +(mapname)2.555 E F2 .054(is the name of the map \(used for error mes-)2.554 F +2.819(sages\). The)117 555 R F1(ar)2.819 E(gs)-.37 E F2 .32(is a pointer to th\ +e rest of the con\214guration \214le line; \215ags and \214lenames can be)2.819 +F -.15(ex)117 567 S .675(tracted from this line.).15 F .675 +(The initialization function must return)5.675 F F3(TR)3.175 E(UE)-.36 E F2 +.674(if it successfully opened)3.174 F(the map,)117 579 Q F3 -.666(FA)2.5 G +(LSE).666 E F2(otherwise.)2.5 E(The lookup function is called as)142 595.2 Q F1 +(xxx)157 611.4 Q F2(_map_lookup\(MAP *map, char b)A(uf[], int b)-.2 E +(ufsize, char **a)-.2 E 1.3 -.65(v, i)-.2 H(nt *statp\)).65 E(The)117 627.6 Q +F1(map)3.475 E F2 .975(de\214nes the map internally)3.475 F 5.975(.T)-.65 G +.975(he parameters)277.18 627.6 R F1 -.2(bu)3.475 G(f).2 E F2(and)3.475 E F1 +-.2(bu)3.475 G(fsize).2 E F2(ha)3.476 E 1.276 -.15(ve t)-.2 H .976(he input k) +.15 F -.15(ey)-.1 G 5.976(.T)-.5 G(his)492.33 627.6 Q .043 +(may be \(and often is\) used destructi)117 639.6 R -.15(ve)-.25 G(ly).15 E +5.043(.T)-.65 G(he)289.831 639.6 Q F1(av)2.543 E F2 .043(is a list of ar)2.543 +F .042(guments passed in from the re)-.18 F(write)-.25 E 3.654(line. The)117 +651.6 R 1.154(lookup function should return a pointer to the ne)3.654 F 3.655 +(wv)-.25 G 3.655(alue. IF)378.335 651.6 R 1.155(the map lookup f)3.655 F(ails,) +-.1 E F1(*statp)117 663.6 Q F2 1.272(should be set to an e)3.772 F 1.272 +(xit status code; in particular)-.15 F 3.772(,i)-.4 G 3.771(ts)357.652 663.6 S +1.271(hould be set to)368.093 663.6 R F3(EX_TEMPF)3.771 E(AIL)-.666 E F2(if) +3.771 E(reco)117 675.6 Q -.15(ve)-.15 G(ry is to be attempted by the higher le) +.15 E -.15(ve)-.25 G 2.5(lc).15 G(ode.)308.76 675.6 Q EP +%%Page: 58 53 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-58 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E 2.5(6.3.5. Queueing)102 96 R(Function) +2.5 E/F1 10/Times-Roman@0 SF .782(The routine)142 112.2 R/F2 10/Times-Italic@0 +SF(shouldqueue)3.282 E F1 .783 +(is called to decide if a message should be queued or processed)3.283 F +(immediately)117 124.2 Q 6.619(.T)-.65 G 1.618 +(ypically this compares the message priority to the current load a)180.779 +124.2 R -.15(ve)-.2 G 4.118(rage. The).15 F(def)117 136.2 Q +(ault de\214nition is:)-.1 E(bool)157 152.4 Q(shouldqueue\(pri, ctime\))157 +164.4 Q(long pri;)175 176.4 Q(time_t ctime;)175 188.4 Q({)157 200.4 Q +(if \(CurrentLA < QueueLA\))175 212.4 Q(return \(F)193 224.4 Q(ALSE\);)-.74 E +(return \(pri > \(QueueF)175 236.4 Q +(actor / \(CurrentLA \255 QueueLA + 1\)\)\);)-.15 E(})157 248.4 Q 2.062 +(If the current load a)117 264.6 R -.15(ve)-.2 G 2.062(rage \(global v).15 F +(ariable)-.25 E F2(Curr)4.562 E(entLA)-.37 E F1 4.562(,w)C 2.062 +(hich is set before this function is)361.636 264.6 R 1.058 +(called\) is less than the lo)117 276.6 R 3.558(wt)-.25 G 1.058 +(hreshold load a)234.198 276.6 R -.15(ve)-.2 G 1.058(rage \(option).15 F F0(x) +3.557 E F1 3.557(,v)C(ariable)375.526 276.6 Q F2(QueueLA)3.557 E F1(\),)A F2 +(shouldqueue)3.557 E F1(returns)117 288.6 Q/F3 9/Times-Roman@0 SF -.666(FA) +2.586 G(LSE).666 E F1 .086(immediately \(that is, it should)2.586 F F2(not) +2.586 E F1 2.586(queue\). If)2.586 F .086(the current load a)2.586 F -.15(ve) +-.2 G .087(rage e).15 F .087(xceeds the)-.15 F .588(high threshold load a)117 +300.6 R -.15(ve)-.2 G .588(rage \(option).15 F F0(X)3.087 E F1 3.087(,v)C +(ariable)281.846 300.6 Q F2(RefuseLA)3.087 E F1(\),)A F2(shouldqueue)3.087 E F1 +(returns)3.087 E F3(TR)3.087 E(UE)-.36 E F1(immedi-)3.087 E(ately)117 312.6 Q +7.125(.O)-.65 G 2.125 +(therwise, it computes the function based on the message priority)152.635 312.6 +R 4.626(,t)-.65 G 2.126(he queue f)438.208 312.6 R(actor)-.1 E(\(option)117 +324.6 Q F0(q)2.5 E F1 2.5(,g)C(lobal v)163.95 324.6 Q(ariable)-.25 E F2(QueueF) +2.5 E(actor)-.75 E F1(\), and the current and threshold load a)A -.15(ve)-.2 G +(rages.).15 E 1.067(An implementation wishing to tak)142 340.8 R 3.567(et)-.1 G +1.066(he actual age of the message into account can also)293.625 340.8 R 1.41 +(use the)117 352.8 R F2(ctime)3.91 E F1(parameter)3.91 E 3.91(,w)-.4 G 1.41 +(hich is the time that the message w)229.15 352.8 R 1.41 +(as \214rst submitted to)-.1 F F2(sendmail)3.91 E F1(.)A .929(Note that the)117 +364.8 R F2(pri)3.428 E F1 .928 +(parameter is already weighted by the number of times the message has been) +3.428 F .395(tried \(although this tends to lo)117 376.8 R .395 +(wer the priority of the message with time\); the e)-.25 F .395 +(xpectation is that)-.15 F(the)117 388.8 Q F2(ctime)2.674 E F1 -.1(wo)2.674 G +.174(uld be used as an \231escape clause\232 to ensure that messages are e).1 F +-.15(ve)-.25 G .174(ntually processed.).15 F F0 2.5(6.3.6. Refusing)102 412.8 R +(Incoming SMTP Connections)2.5 E F1 1.148(The function)142 429 R F2 -.37(re) +3.648 G(fuseconnections).37 E F1(returns)3.648 E F3(TR)3.648 E(UE)-.36 E F1 +1.148(if incoming SMTP connections should be)3.648 F 3.564(refused. The)117 441 +R 1.063(current implementation is based e)3.563 F(xclusi)-.15 E -.15(ve)-.25 G +1.063(ly on the current load a).15 F -.15(ve)-.2 G 1.063(rage and the).15 F +(refuse load a)117 453 Q -.15(ve)-.2 G(rage option \(option).15 E F0(X)2.5 E F1 +2.5(,g)C(lobal v)273.56 453 Q(ariable)-.25 E F2(RefuseLA)2.5 E F1(\):)A(bool) +157 469.2 Q(refuseconnections\(\))157 481.2 Q({)157 493.2 Q +(return \(CurrentLA >= RefuseLA\);)175 505.2 Q(})157 517.2 Q 2.5(Am)117 533.4 S +(ore cle)134.5 533.4 Q -.15(ve)-.25 G 2.5(ri).15 G +(mplementation could look at more system resources.)179.08 533.4 Q F0 2.5 +(6.3.7. Load)102 557.4 R -.6 -1(Av e)2.5 H(rage Computation)1 E F1 .243 +(The routine)142 573.6 R F2 -.1(ge)2.743 G(tla).1 E F1 .243 +(returns the current load a)2.743 F -.15(ve)-.2 G .243 +(rage \(as a rounded inte).15 F 2.743(ger\). The)-.15 F(distrib)2.744 E(ution) +-.2 E 1.157(includes se)117 585.6 R -.15(ve)-.25 G 1.157 +(ral possible implementations.).15 F 1.157(If you are porting to a ne)6.157 F +3.657(we)-.25 G -.4(nv)418.757 585.6 S 1.157(ironment you may).4 F +(need to add some ne)117 599.6 Q 2.5(wt)-.25 G(weaks.)210.9 599.6 Q/F4 7 +/Times-Roman@0 SF(23)238.39 595.6 Q F0 2.5(6.4. Con\214guration)87 623.6 R +(in sr)2.5 E(c/daemon.c)-.18 E F1 .4(The \214le)127 639.8 R F2(sr)2.9 E +(c/daemon.c)-.37 E F1 .4 +(contains a number of routines that are dependent on the local netw)2.9 F(ork-) +-.1 E(ing en)102 651.8 Q 2.5(vironment. The)-.4 F -.15(ve)2.5 G +(rsion supplied assumes you ha).15 E .3 -.15(ve B)-.2 H(SD style sock).15 E +(ets.)-.1 E 2.16(In pre)127 668 R 2.16 +(vious releases, we recommended that you modify the routine)-.25 F F2 +(maphostname)4.66 E F1 2.16(if you)4.66 F -.1(wa)102 680 S 1.918 +(nted to generalize).1 F F0($[)4.418 E F1(...)4.418 E F0($])4.418 E F1 4.418 +(lookups. W)4.418 F 4.418(en)-.8 G 2.418 -.25(ow r)293.904 680 T 1.918 +(ecommend that you create a ne).25 F 4.419(wk)-.25 G -.15(ey)463.631 680 S +1.919(ed map).15 F .32 LW 76 689.6 72 689.6 DL 80 689.6 76 689.6 DL 84 689.6 80 +689.6 DL 88 689.6 84 689.6 DL 92 689.6 88 689.6 DL 96 689.6 92 689.6 DL 100 +689.6 96 689.6 DL 104 689.6 100 689.6 DL 108 689.6 104 689.6 DL 112 689.6 108 +689.6 DL 116 689.6 112 689.6 DL 120 689.6 116 689.6 DL 124 689.6 120 689.6 DL +128 689.6 124 689.6 DL 132 689.6 128 689.6 DL 136 689.6 132 689.6 DL 140 689.6 +136 689.6 DL 144 689.6 140 689.6 DL 148 689.6 144 689.6 DL 152 689.6 148 689.6 +DL 156 689.6 152 689.6 DL 160 689.6 156 689.6 DL 164 689.6 160 689.6 DL 168 +689.6 164 689.6 DL 172 689.6 168 689.6 DL 176 689.6 172 689.6 DL 180 689.6 176 +689.6 DL 184 689.6 180 689.6 DL 188 689.6 184 689.6 DL 192 689.6 188 689.6 DL +196 689.6 192 689.6 DL 200 689.6 196 689.6 DL 204 689.6 200 689.6 DL 208 689.6 +204 689.6 DL 212 689.6 208 689.6 DL 216 689.6 212 689.6 DL/F5 5/Times-Roman@0 +SF(23)93.6 700 Q/F6 8/Times-Roman@0 SF +(If you do, please send updates to sendmail@CS.Berk)3.2 I(ele)-.08 E -.52(y.) +-.12 G(EDU.).52 E EP +%%Page: 59 54 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-59)452.9 60 Q/F1 10/Times-Roman@0 SF(instead.)102 96 Q F0 2.5 +(7. CHANGES)72 120 R(IN VERSION 8)2.5 E F1 .196(The follo)112 136.2 R .196 +(wing summarizes changes since the last commonly a)-.25 F -.25(va)-.2 G .196 +(ilable v).25 F .196(ersion of)-.15 F/F2 10/Times-Italic@0 SF(sendmail)2.695 E +F1(\(5.67\).)2.695 E -.15(Fo)87 148.2 S 2.702(rad).15 G .202 +(etailed list, consult the \214le RELEASE_NO)115.584 148.2 R .203 +(TES in the root directory of the)-.4 F F2(sendmail)2.703 E F1(distrib)2.703 E +(ution.)-.2 E F0 2.5(7.1. Connection)87 172.2 R(Caching)2.5 E F1 .398 +(Instead of closing SMTP connections immediately)127 188.4 R 2.897(,t)-.65 G +.397(hose connections are cached for possible)339.005 188.4 R .597(future use.) +102 200.4 R .597(The adv)5.597 F .597(ent of MX records made this ef)-.15 F +(fecti)-.25 E .897 -.15(ve f)-.25 H .598 +(or mailing lists; in addition, substantial).15 F(performance impro)102 212.4 Q +-.15(ve)-.15 G(ments can be e).15 E(xpected for queue processing.)-.15 E F0 2.5 +(7.2. MX)87 236.4 R(Piggybacking)2.5 E F1 1.258(If tw)127 252.6 R 3.757(oh)-.1 +G 1.257(osts with dif)161.075 252.6 R 1.257 +(ferent names in a single message happen to ha)-.25 F 1.557 -.15(ve t)-.2 H +1.257(he same set of MX).15 F .94(hosts, the)102 264.6 R 3.44(yc)-.15 G .94 +(an be sent in the same transaction.)153.45 264.6 R -1.11(Ve)5.94 G .94 +(rsion 8 notices this and tries to batch the mes-)1.11 F(sages.)102 276.6 Q F0 +2.5(7.3. RFC)87 300.6 R(1123 Compliance)2.5 E F1 3.463(An)127 316.8 S .963 +(umber of changes ha)142.683 316.8 R 1.262 -.15(ve b)-.2 H .962 +(een made to mak).15 F(e)-.1 E F2(sendmail)3.462 E F1 .962 +(\231conditionally compliant\232 \(that is,)3.462 F F2(sendmail)102 328.8 Q F1 +.049(satis\214es all of the \231MUST\232 clauses and most b)2.549 F .05 +(ut not all of the \231SHOULD\232 clauses in RFC)-.2 F(1123\).)102 340.8 Q +(The major areas of change are \(numbers are RFC 1123 section numbers\):)127 +357 Q 15(5.2.7 Response)102 373.2 R(to RCPT command is f)2.5 E(ast.)-.1 E 15 +(5.2.8 Numeric)102 389.4 R(IP addresses are logged in Recei)2.5 E -.15(ve)-.25 +G(d: lines.).15 E 10(5.2.17 Self)102 405.6 R +(domain literal is properly handled.)2.5 E 15(5.3.2 Better)102 421.8 R +(control o)2.5 E -.15(ve)-.15 G 2.5(ri).15 G(ndi)220.02 421.8 Q +(vidual timeouts.)-.25 E 15(5.3.3 Error)102 438 R +(messages are sent as \231From:<>\232.)2.5 E 15(5.3.3 Error)102 454.2 R +(messages are ne)2.5 E -.15(ve)-.25 G 2.5(rs).15 G(ent to \231<>\232.)246.28 +454.2 Q 15(5.3.3 Route-addrs)102 470.4 R(are pruned.)2.5 E(The areas in which) +102 486.6 Q F2(sendmail)2.5 E F1(is not \231unconditionally compliant\232 are:) +2.5 E(5.2.6)102 502.8 Q F2(Sendmail)139.5 502.8 Q F1(does do header munging.) +2.5 E(5.2.10)102 519 Q F2(Sendmail)139.5 519 Q F1(doesn')2.5 E 2.5(ta)-.18 G +-.1(lwa)215.42 519 S(ys use the e).1 E(xact SMTP message te)-.15 E +(xt as listed in RFC 821.)-.15 E(5.3.1.1)102 535.2 Q F2(Sendmail)139.5 535.2 Q +F1(doesn')2.5 E 2.5(tg)-.18 G +(uarantee only one connect for each host in queue runs.)215.98 535.2 Q(5.3.1.1) +102 551.4 Q F2(Sendmail)139.5 551.4 Q F1(doesn')2.5 E 2.5(ta)-.18 G -.1(lwa) +215.42 551.4 S(ys pro).1 E(vide adequate concurrenc)-.15 E 2.5(yl)-.15 G +(imits.)366.54 551.4 Q F0 2.5(7.4. Extended)87 575.4 R(SMTP Support)2.5 E F1 +-1.11(Ve)127 591.6 S .155(rsion 8 includes both sending and recei)1.11 F .154 +(ving support for Extended SMTP support as de\214ned)-.25 F(by RFC 1651 \(basi\ +c\) and RFC 1653 \(SIZE\); and limited support for RFC 1652 \(BOD)102 603.6 Q +(Y\).)-.55 E F0 2.5(7.5. Eight-Bit)87 627.6 R(Clean)2.5 E F1(Pre)127 643.8 Q +1.263(vious v)-.25 F 1.263(ersions of)-.15 F F2(sendmail)3.763 E F1 1.264 +(used the 0200 bit for quoting.)3.763 F 1.264(This v)6.264 F 1.264(ersion a) +-.15 F -.2(vo)-.2 G 1.264(ids that use.).2 F(Ho)102 655.8 Q(we)-.25 E -.15(ve) +-.25 G .8 -.4(r, f).15 H +(or compatibility with RFC 822, you can set option `7' to get se).4 E -.15(ve) +-.25 G 2.5(nb).15 G(it stripping.)418.86 655.8 Q(Indi)127 672 Q +(vidual mailers can still produce se)-.25 E -.15(ve)-.25 G 2.5(nb).15 G +(it output using the `7' mailer \215ag.)300.77 672 Q F0 2.5(7.6. User)87 696 R +(Database)2.5 E F1 1.073(The user database is an as-yet e)127 712.2 R 1.072 +(xperimental attempt to pro)-.15 F 1.072(vide uni\214ed lar)-.15 F 1.072 +(ge-site name sup-)-.18 F 2.5(port. W)102 724.2 R 2.5(ea)-.8 G +(re installing it at Berk)145.63 724.2 Q(ele)-.1 E(y; future v)-.15 E +(ersions may sho)-.15 E 2.5(ws)-.25 G(igni\214cant modi\214cations.)363.57 +724.2 Q EP +%%Page: 60 55 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-60 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E 2.5(7.7. Impr)87 96 R -.1(ove)-.18 G +2.5(dB).1 G(IND Support)158.01 96 Q/F1 10/Times-Roman@0 SF .489 +(The BIND support, particularly for MX records, had a number of anno)127 112.2 +R .49(ying \231features\232 which)-.1 F(ha)102 124.2 Q 1.212 -.15(ve b)-.2 H +.912(een remo).15 F -.15(ve)-.15 G 3.412(di).15 G 3.412(nt)187.116 124.2 S .912 +(his release.)198.308 124.2 R .912(In particular)5.912 F 3.412(,t)-.4 G .912 +(hese more tightly bind \(pun intended\) the name)307.916 124.2 R(serv)102 +136.2 Q(er to)-.15 E/F2 10/Times-Italic@0 SF(sendmail)2.5 E F1 2.5(,s)C 2.5(ot) +184.06 136.2 S(hat the name serv)194.34 136.2 Q +(er resolution rules are incorporated directly into)-.15 E F0(sendmail)2.5 E F1 +(.)A F0 2.5(7.8. K)87 160.2 R(ey)-.25 E(ed Files)-.1 E F1 .365(Generalized k) +127 176.4 R -.15(ey)-.1 G .365(ed \214les is an idea tak).15 F .365 +(en directly from)-.1 F/F3 9/Times-Roman@0 SF(ID)2.866 E(A)-.36 E F2(sendmail) +2.866 E F1 .366(\(albeit with a completely)2.866 F(dif)102 188.4 Q +(ferent implementation\).)-.25 E(The)5 E 2.5(yc)-.15 G(an be useful on lar) +239.63 188.4 Q(ge sites.)-.18 E -1.11(Ve)127 204.6 S +(rsion 8 also understands YP)1.11 E(.)-1.11 E F0 2.5(7.9. Multi-W)87 228.6 R +(ord Classes)-.75 E F1(Classes can no)127 244.8 Q 2.5(wb)-.25 G 2.5(em)200.35 +244.8 S(ultiple w)215.07 244.8 Q 2.5(ords. F)-.1 F(or e)-.15 E(xample,)-.15 E +(CShofmann.CS.Berk)142 261 Q(ele)-.1 E -.65(y.)-.15 G(EDU).65 E(allo)102 277.2 +Q 2.664(ws you to match the entire string \231hofmann.CS.Berk)-.25 F(ele)-.1 E +-.65(y.)-.15 G 2.663(EDU\232 using the single construct).65 F(\231$=S\232.)102 +289.2 Q F0 2.5(7.10. Deferr)87 313.2 R(ed Macr)-.18 E 2.5(oE)-.18 G(xpansion) +189.94 313.2 Q F1(The)127 329.4 Q F0($&)2.5 E F2(x)A F1 +(construct has been adopted from)2.5 E F3(ID)2.5 E(A)-.36 E F1(.)A F0 2.5 +(7.11. IDENT)87 353.4 R(Pr)2.5 E(otocol Support)-.18 E F1 +(The IDENT protocol as de\214ned in RFC 1413 is supported.)127 369.6 Q F0 2.5 +(7.12. P)87 393.6 R(arsing Bug Fixes)-.1 E F1 4.03(An)127 409.8 S 1.53 +(umber of small b)143.25 409.8 R 1.53(ugs ha)-.2 F 1.53 +(ving to do with things lik)-.2 F 4.03(eb)-.1 G 1.53 +(ackslash-escaped quotes inside of)364.72 409.8 R(comments ha)102 421.8 Q .3 +-.15(ve b)-.2 H(een \214x).15 E(ed.)-.15 E F0 2.5(7.13. Separate)87 445.8 R(En) +2.5 E -.1(ve)-.4 G(lope/Header Pr).1 E(ocessing)-.18 E F1 .854 +(Since the From: line is passed in separately from the en)127 462 R -.15(ve)-.4 +G .854(lope sender).15 F 3.354(,t)-.4 G .854(hese ha)420.978 462 R 1.154 -.15 +(ve b)-.2 H .854(oth been).15 F .427(made visible; the)102 474 R F0($g)2.927 E +F1 .427(macro is set to the en)2.927 F -.15(ve)-.4 G .428 +(lope sender during processing of mailer ar).15 F .428(gument v)-.18 F(ec-)-.15 +E(tors and the header sender during processing of headers.)102 486 Q .085 +(It is also possible to specify separate per)127 502.2 R .085(-mailer en)-.2 F +-.15(ve)-.4 G .084(lope and header processing.).15 F(The)5.084 E F0(S)2.584 E +F1(ender)A(-)-.2 E -.55(RW)102 514.2 S .512(Set and).55 F F0(R)3.012 E F1 +(ecipientR)A .512(Wset ar)-.55 F .512 +(guments for mailers can be speci\214ed as)-.18 F F2(en)3.013 E(velope/header) +-.4 E F1 .513(to gi)3.013 F .813 -.15(ve d)-.25 H(if-).15 E(ferent re)102 526.2 +Q(writings for en)-.25 E -.15(ve)-.4 G(lope v).15 E(ersus header addresses.) +-.15 E F0 2.5(7.14. Owner)87 550.2 R(-List Pr)-.37 E(opagates to En)-.18 E -.1 +(ve)-.4 G(lope).1 E F1 1.001(When an alias has an associated o)127 566.4 R 1 +(wner\255list name, that alias is used to change the en)-.25 F -.15(ve)-.4 G +(lope).15 E(sender address.)102 578.4 Q(This will cause do)5 E +(wnstream errors to be returned to that o)-.25 E(wner)-.25 E(.)-.55 E F0 2.5 +(7.15. Dynamic)87 602.4 R(Header Allocation)2.5 E F1(The \214x)127 618.6 Q +(ed size limit on header lines has been eliminated.)-.15 E F0 2.5(7.16. New)87 +642.6 R(Command Line Flags)2.5 E F1(The)127 658.8 Q F0<ad42>2.5 E F1 +(\215ag has been added to pass in body type information.)2.5 E(The)127 675 Q F0 +<ad70>2.5 E F1(\215ag has been added to pass in protocol information.)2.5 E +(The)127 691.2 Q F0<ad58>2.6 E F1 .1(\215ag has been added to allo)2.6 F 2.6 +(wl)-.25 G .1(ogging of all protocol in and out of)279.89 691.2 R F2(sendmail) +2.6 E F1 .1(for deb)2.6 F(ug-)-.2 E(ging.)102 703.2 Q EP +%%Page: 61 56 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-61)452.9 60 Q/F1 10/Times-Roman@0 SF(The)127 96 Q F0<ad4f>2.5 E F1 +(\215ag simplies setting long-form options.)2.5 E F0 2.5(7.17. Enhanced)87 120 +R(Command Line Flags)2.5 E F1(The)127 136.2 Q F0<ad71>4.007 E F1 1.507(\215ag \ +can limit limit a queue run to speci\214c recipients, senders, or queue ids us\ +ing)4.007 F F0(\255qR)102 148.2 Q/F2 10/Times-Italic@0 SF(substring)A F0 2.5 +<2cad>C(qS)168.41 148.2 Q F2(substring)A F0 2.5(,o)C 2.5<72ad>226.76 148.2 S +(qI)239.4 148.2 Q F2(substring)A F0 -.18(re)2.5 G(specti).18 E -.1(ve)-.1 G(ly) +.1 E(.)-.7 E 2.5(7.18. New)87 172.2 R(and Old Con\214guration Line T)2.5 E +(ypes)-.74 E F1(The)127 188.4 Q F0(K)2.5 E F1 +(line has been added to declare database maps.)2.5 E(The)127 204.6 Q F0(V)2.5 E +F1(line has been added to declare the con\214guration v)2.5 E(ersion le)-.15 E +-.15(ve)-.25 G(l.).15 E(The)127 220.8 Q F0(M)2.796 E F1 .297(line has a \231D=\ +\232 \214eld that lets you change into a temporary directory while that mailer) +2.796 F .581(is running.)102 232.8 R .581 +(It also has a \231U=\232 \214eld to allo)5.581 F 3.081(wy)-.25 G .58 +(ou to set the user and group id to be used when run-)289.85 232.8 R +(ning the mailer)102 244.8 Q(.)-.55 E F0 2.5(7.19. New)87 268.8 R(Options)2.5 E +F1(Se)127 285 Q -.15(ve)-.25 G .9(ral ne).15 F 3.4(wo)-.25 G .9(ptions ha)184.8 +285 R 1.2 -.15(ve b)-.2 H .9(een added, man).15 F 3.4(yt)-.15 G 3.4(os)314.89 +285 S .9(upport ne)327.18 285 R 3.4(wf)-.25 G .9(eatures, others to allo)379.83 +285 R 3.4(wt)-.25 G(uning)481.22 285 Q 1.187(that w)102 297 R 1.187(as pre)-.1 +F 1.187(viously a)-.25 F -.25(va)-.2 G 1.187(ilable only by recompiling.).25 F +(The)6.186 E 3.686(ya)-.15 G 1.186(re described in detail in Section 5.1.5.) +345.514 297 R(Brie\215y)102 309 Q(,)-.65 E 31(bI)102 325.2 S +(nsist on a minimum number of disk blocks.)141.33 325.2 Q 29.33(CS)102 341.4 S +(et checkpoint interv)143.56 341.4 Q(al.)-.25 E 29.89(ED)102 357.6 S(ef)145.22 +357.6 Q(ault error message.)-.1 E 28.78(GE)102 373.8 S(nable GECOS matching.) +144.11 373.8 Q 31(hM)102 390 S(aximum hop count.)146.89 390 Q 33.22(jS)102 +406.2 S(end errors in MIME-encapsulated format.)143.56 406.2 Q 32.11(JF)102 +422.4 S(orw)143.41 422.4 Q(ard \214le path.)-.1 E 31(kC)102 438.6 S +(onnection cache size)144.67 438.6 Q 28.78(KC)102 454.8 S +(onnection cache lifetime.)144.67 454.8 Q 33.22(lE)102 471 S .333 +(nable Errors-T)144.11 471 R .333(o: header)-.8 F 5.334(.T)-.55 G .334 +(hese headers violate RFC 1123; this option is included to pro-)252.89 471 R +(vide back compatibility with old v)138 483 Q(ersions of)-.15 E F2(sendmail)2.5 +E F1(.)A 28.78(OS)102 499.2 S +(et incoming SMTP daemon options, such as an alternate SMTP port.)143.56 499.2 +Q 31(pP)102 515.4 S(ri)143.56 515.4 Q -.25(va)-.25 G .3 -.15(cy o).25 H +(ptions.).15 E 29.33(RD)102 531.6 S(on')145.22 531.6 Q 2.5(tp)-.18 G +(rune route-addrs.)168.65 531.6 Q 28.78(UU)102 547.8 S(ser database spec.) +145.22 547.8 Q 28.78(VF)102 564 S(allback \231MX\232 host.)143.41 564 Q 28.78 +<7799>102 580.2 S(Best MX\232 handling technique.)142.44 580.2 Q 31(7D)102 +596.4 S 2.5(on)145.22 596.4 S(ot run eight bit clean.)157.72 596.4 Q 31(8E)102 +612.6 S(ight bit data handling mode.)144.11 612.6 Q F0 2.5(7.20. Extended)87 +636.6 R(Options)2.5 E F1(The)127 652.8 Q F0(r)3.764 E F1 1.264 +(\(read timeout\),)3.764 F F0(I)3.764 E F1 1.264(\(use BIND\), and)3.764 F F0 +(T)3.764 E F1 1.264(\(queue timeout\) options ha)3.764 F 1.564 -.15(ve b)-.2 H +1.264(een e).15 F 1.264(xtended to)-.15 F(pass in more information.)102 664.8 Q +F0 2.5(7.21. New)87 688.8 R(Mailer Flags)2.5 E F1(Se)127 705 Q -.15(ve)-.25 G +(ral ne).15 E 2.5(wm)-.25 G(ailer \215ags ha)185.78 705 Q .3 -.15(ve b)-.2 H +(een added.).15 E EP +%%Page: 62 57 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-62 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 31.56(aT)102 96 +S .636(ry to use ESMTP when creating a connection.)143.76 96 R .636 +(If this is not set,)5.636 F/F2 10/Times-Italic@0 SF(sendmail)3.136 E F1 .636 +(will still try if)3.136 F .221(the other end hints that it kno)138 108 R .22 +(ws about ESMTP in its greeting message; this \215ag says to try)-.25 F -2.15 +-.25(ev e)138 120 T 2.595(ni).25 G 2.595(fi)161.855 120 S 2.595(td)170.56 120 S +(oesn')180.935 120 Q 2.595(th)-.18 G 2.595(int. If)212.79 120 R .095 +(the EHLO \(e)2.595 F .095(xtended hello\) command f)-.15 F(ails,)-.1 E F2 +(sendmail)2.596 E F1 -.1(fa)2.596 G .096(lls back to).1 F(old SMTP)138 132 Q(.) +-1.11 E 28.78(AT)102 148.2 S +(ry the user part of addresses for this mailer as aliases.)143.76 148.2 Q 31 +(bE)102 164.4 S(nsure that there is a blank line at the end of all messages.) +144.11 164.4 Q 31.56(cS)102 180.6 S .68(trip all comments from addresses; this\ + should only be used as a last resort when dealing)143.56 180.6 R(with crank) +138 192.6 Q 2.5(ym)-.15 G(ailers.)195.62 192.6 Q 31(gN)102 208.8 S -2.15 -.25 +(ev e)145.22 208.8 T 2.64(ru).25 G .14(se the null sender as the en)169.67 +208.8 R -.15(ve)-.4 G .141(lope sender).15 F 2.641(,e)-.4 G -.15(ve)341.495 +208.8 S 2.641(nw).15 G .141(hen running SMTP)365.646 208.8 R 5.141(.A)-1.11 G +.141(lthough this)456.349 208.8 R 1.521(violates RFC 1123, it may be necessary\ + when you must deal with some obnoxious old)138 220.8 R(hosts.)138 232.8 Q 31 +(kT)102 249 S(urn of)143.66 249 Q 2.5(ft)-.25 G +(he loopback check in the HELO protocol; doing this may cause mailer loops.) +176.18 249 Q 31(oA)102 265.2 S -.1(lwa)145.22 265.2 S +(ys run the mailer as the recipient of the message.).1 E 28.78(wT)102 281.4 S +(his user should ha)144.11 281.4 Q .3 -.15(ve a p)-.2 H(asswd \214le entry).15 +E(.)-.65 E 31(5T)102 297.6 S(ry ruleset 5 if no local aliases.)143.76 297.6 Q +31(7S)102 313.8 S(trip all output to 7 bits.)143.56 313.8 Q 33.22(:C)102 330 S +(heck for :include: \214les.)144.67 330 Q 34(|C)102 346.2 S +(heck for |program addresses.)144.67 346.2 Q 33.22(/C)102 362.4 S +(heck for /\214le addresses.)144.67 362.4 Q 26.79(@C)102 378.6 S +(heck this user ag)144.67 378.6 Q(ainst the user database.)-.05 E F0 2.5 +(7.22. Long)87 402.6 R(Option Names)2.5 E F1 .856 +(All options can be speci\214ed using long names, and some ne)127 418.8 R 3.356 +(wo)-.25 G .856(ptions can only be speci\214ed)389.476 418.8 R +(with long names.)102 430.8 Q F0 2.5(7.23. New)87 454.8 R(Pr)2.5 E +(e-De\214ned Macr)-.18 E(os)-.18 E F1(The follo)127 471 Q +(wing macros are pre-de\214ned:)-.25 E 23.5($k The)102 487.2 R +(UUCP node name, nominally from)2.5 E F2(uname)2.5 E F1(\(2\) call.)A 20.72 +($m The)102 503.4 R(domain part of our full hostname.)2.5 E 23.5($_ The)102 +519.6 R(RFC 1413-pro)2.5 E(vided sender address.)-.15 E F0 2.5(7.24. New)87 +543.6 R(LHS T)2.5 E(ok)-.92 E(en)-.1 E F1 -1.11(Ve)127 559.8 S 1.376 +(rsion 8 allo)1.11 F(ws)-.25 E F0($@)3.876 E F1 1.376 +(on the Left Hand Side of an \231R\232 line to match zero tok)3.876 F 3.875 +(ens. This)-.1 F(is)3.875 E(intended to be used to match the null input.)102 +571.8 Q F0 2.5(7.25. Bigger)87 595.8 R(Defaults)2.5 E F1 -1.11(Ve)127 612 S +1.283(rsion 8 allo)1.11 F 1.284(ws up to 100 rulesets instead of 30.)-.25 F +1.284(It is recommended that rulesets 0\2559 be)6.284 F(reserv)102 624 Q +(ed for)-.15 E F2(sendmail)2.5 E F1 1.1 -.55('s d)D +(edicated use in future releases.).55 E +(The total number of MX records that can be used has been raised to 20.)127 +640.2 Q .335(The number of queued messages that can be handled at one time has\ + been raised from 600 to)127 656.4 R(1000.)102 668.4 Q F0 2.5(7.26. Differ)87 +692.4 R(ent Default T)-.18 E(uning P)-.92 E(arameters)-.1 E F1 -1.11(Ve)127 +708.6 S .8(rsion 8 has changed the def)1.11 F .8 +(ault parameters for tuning queue costs to mak)-.1 F 3.3(et)-.1 G .8 +(he number of)449.08 708.6 R .712(recipients more important than the size of t\ +he message \(for small messages\).)102 720.6 R .712(This is reasonable if)5.712 +F EP +%%Page: 63 58 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-63)452.9 60 Q/F1 10/Times-Roman@0 SF +(you are connected with reasonably f)102 96 Q(ast links.)-.1 E F0 2.5(7.27. A) +87 120 R(uto-Quoting in Addr)-.5 E(esses)-.18 E F1(Pre)127 136.2 Q(viously)-.25 +E 2.61(,t)-.65 G .111(he \231Full Name <email address>\232 syntax w)176.77 +136.2 R .111(ould generate incorrect protocol output)-.1 F +(if \231Full Name\232 had special characters such as dot.)102 148.2 Q(This v)5 +E(ersion puts quotes around such names.)-.15 E F0 2.5(7.28. Symbolic)87 172.2 R +(Names On Err)2.5 E(or Mailer)-.18 E F1(Se)127 188.4 Q -.15(ve)-.25 G +(ral names ha).15 E .3 -.15(ve b)-.2 H(een b).15 E +(uilt in to the $@ portion of the $#error mailer)-.2 E(.)-.55 E F0 2.5 +(7.29. SMTP)87 212.4 R(VRFY Doesn't Expand)2.5 E F1(Pre)127 228.6 Q 1.438 +(vious v)-.25 F 1.438(ersions of)-.15 F/F2 10/Times-Italic@0 SF(sendmail)3.938 +E F1 1.438(treated VRFY and EXPN the same.)3.938 F 1.437(In this v)6.437 F +1.437(ersion, VRFY)-.15 F(doesn')102 240.6 Q 2.5(te)-.18 G +(xpand aliases or follo)138.05 240.6 Q 2.5(w.)-.25 G(forw)235.84 240.6 Q +(ard \214les.)-.1 E(EXPN still does.)5 E .681 +(As an optimization, if you run with your def)127 256.8 R .682(ault deli)-.1 F +-.15(ve)-.25 G .682(ry mode being queue-only or deli).15 F -.15(ve)-.25 G -.2 +(r-).15 G 1.582 +(in-background, the RCPT command will also not chase aliases and .forw)102 +268.8 R 1.582(ard \214les.)-.1 F 1.582(It will chase)6.582 F +(them when it processes the queue.)102 280.8 Q F0 2.5(7.30. [IPC])87 304.8 R +(Mailers Allo)2.5 E 2.5(wM)-.1 G(ultiple Hosts)210.49 304.8 Q F1 .447 +(When an address resolv)127 321 R .448 +(es to a mailer that has \231[IPC]\232 as its \231P)-.15 F .448 +(ath\232, the $@ part \(host name\))-.15 F .138 +(can be a colon-separated list of hosts instead of a single hostname.)102 333 R +.137(This asks)5.137 F F2(sendmail)2.637 E F1 .137(to search the)2.637 F .16 +(list for the \214rst entry that is a)102 345 R -.25(va)-.2 G .16(ilable e).25 +F .161(xactly as though it were an MX record.)-.15 F .161 +(The intent is to route)5.161 F .738(internal traf)102 357 R .738 +(\214c through internal netw)-.25 F .738 +(orks without publishing an MX record to the net.)-.1 F .737(MX e)5.737 F +(xpan-)-.15 E(sion is still done on the indi)102 369 Q(vidual items.)-.25 E F0 +2.5(7.31. Aliases)87 393 R(Extended)2.5 E F1 1.456 +(The implementation has been mer)127 409.2 R 1.457(ged with maps.)-.18 F 1.457 +(Among other things, this supports NIS-)6.457 F(based aliases.)102 421.2 Q F0 +2.5(7.32. P)87 445.2 R(ortability and Security Enhancements)-.2 E F1 2.5(An)127 +461.4 S(umber of internal changes ha)141.72 461.4 Q .3 -.15(ve b)-.2 H +(een made to enhance portability).15 E(.)-.65 E(Se)127 477.6 Q -.15(ve)-.25 G +(ral \214x).15 E(es ha)-.15 E .3 -.15(ve b)-.2 H +(een made to increase the paranoia f).15 E(actor)-.1 E(.)-.55 E F0 2.5 +(7.33. Miscellaneous)87 501.6 R(Changes)2.5 E F2(Sendmail)127 517.8 Q F1 +(writes a)2.5 E F2(/etc/sendmail.pid)2.5 E F1 +(\214le with the current process id of the SMTP daemon.)2.5 E -1 -.8(Tw o)127 +534 T 1.647(people using the same program in their .forw)4.947 F 1.646 +(ard \214le are considered dif)-.1 F 1.646(ferent so that)-.25 F +(duplicate elimination doesn')102 546 Q 2.5(td)-.18 G(elete one of them.)225.98 +546 Q(The)127 562.2 Q F2(mailstats)3.18 E F1 .681 +(program prints mailer names and gets the location of the)3.18 F F2 +(sendmail.st)3.181 E F1 .681(\214le from)3.181 F F2(/etc/sendmail.cf)102 574.2 +Q F1(.)A(Man)127 590.4 Q 2.5(ym)-.15 G(inor b)160.46 590.4 Q(ugs ha)-.2 E .3 +-.15(ve b)-.2 H(een \214x).15 E +(ed, such as handling of backslashes inside of quotes.)-.15 E 2.5(Ah)127 606.6 +S(ook \(ruleset 5\) has been added to allo)141.72 606.6 Q 2.5(wr)-.25 G -.25 +(ew)304.21 606.6 S(riting of local addresses after aliasing.).25 E F0 2.5(8. A) +72 630.6 R(CKNO)-.55 E(WLEDGEMENTS)-.5 E F1(I')112 646.8 Q 2.037 -.15(ve w)-.5 +H(ork).05 E 1.737(ed on)-.1 F F2(sendmail)4.237 E F1 1.737(for man)4.237 F +4.237(yy)-.15 G 1.737(ears, and man)267.502 646.8 R 4.237(ye)-.15 G(mplo) +339.763 646.8 Q 1.737(yers ha)-.1 F 2.037 -.15(ve b)-.2 H 1.737 +(een remarkably patient).15 F .403(about letting me w)87 658.8 R .403 +(ork on a lar)-.1 F .403(ge project that w)-.18 F .404(as not part of my of)-.1 +F .404(\214cial job)-.25 F 5.404(.T)-.4 G .404(his includes time on the)407.384 +658.8 R .282(INGRES Project at the Uni)87 670.8 R -.15(ve)-.25 G .282 +(rsity of California at Berk).15 F(ele)-.1 E 1.582 -.65(y, a)-.15 H 2.782(tB) +.65 G .282(ritton Lee, and ag)348.21 670.8 R .281(ain on the Mammoth)-.05 F +(and T)87 682.8 Q(itan Projects at Berk)-.35 E(ele)-.1 E -.65(y.)-.15 G .453 +(Much of the second w)112 699 R -2.25 -.2(av e)-.1 H .453(of impro)3.153 F -.15 +(ve)-.15 G .453(ments should be credited to Bryan Costales of ICSI.).15 F .454 +(As he)5.454 F .781(passed me drafts of his book on)87 711 R F2(sendmail)3.281 +E F1 3.281(Iw)3.281 G .781(as inspired to start w)274.741 711 R .781 +(orking on things ag)-.1 F 3.281(ain. Bryan)-.05 F -.1(wa)3.281 G(s).1 E +(also a)87 723 Q -.25(va)-.2 G(ilable to bounce ideas of).25 E 2.5(fo)-.25 G +(f.)227.38 723 Q EP +%%Page: 64 59 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-64 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(Man)112 96 Q +2.856 -.65(y, m)-.15 H(an).65 E 4.056(yp)-.15 G 1.556(eople contrib)172.212 96 +R 1.556(uted chunks of code and ideas to)-.2 F/F2 10/Times-Italic@0 SF +(sendmail)4.056 E F1 6.556(.I)C 4.056(th)418.476 96 S 1.557(as pro)430.312 96 R +-.15(ve)-.15 G 4.057(nt).15 G 4.057(ob)477.006 96 S 4.057(ea)491.063 96 S .464 +(group netw)87 108 R .464(ork ef)-.1 F 2.964(fort. V)-.25 F .464 +(ersion 8 in particular w)-1.11 F .463(as a group project.)-.1 F .463 +(The follo)5.463 F .463(wing people made notable)-.25 F(contrib)87 120 Q +(utions:)-.2 E(John Beck, He)127 136.2 Q(wlett-P)-.25 E(ackard)-.15 E -.25(Ke) +127 148.2 S(ith Bostic, CSRG, Uni).25 E -.15(ve)-.25 G +(rsity of California, Berk).15 E(ele)-.1 E(y)-.15 E(Andre)127 160.2 Q 2.5(wC) +-.25 G(heng, Sun Microsystems)168.13 160.2 Q(Michael J. Corrig)127 172.2 Q +(an, Uni)-.05 E -.15(ve)-.25 G(rsity of California, San Die).15 E(go)-.15 E +(Bryan Costales, International Computer Science Institute)127 184.2 Q -.15(Pa) +127 196.2 S -.5(..)132.298 190.2 S 2.5(r\()136.85 196.2 S(Pell\) Emanuelsson) +146.01 196.2 Q(Craig Ev)127 208.2 Q(erhart, T)-.15 E(ransarc Corporation)-.35 E +-.8(To)127 220.2 S 2.5(mI).8 G -.25(va)150.92 220.2 S 2.5(rH).25 G +(elbekkmo, Norwe)173.16 220.2 Q(gian School of Economics)-.15 E +(Allan E. Johannesen, WPI)127 232.2 Q(Jonathan Kamens, OpenV)127 244.2 Q +(ision T)-.6 E(echnologies, Inc.)-.7 E -.8(Ta)127 256.2 S +(kahiro Kanbe, Fuji Xerox Information Systems Co., Ltd.).8 E(Brian Kantor)127 +268.2 Q 2.5(,U)-.4 G(ni)191.31 268.2 Q -.15(ve)-.25 G +(rsity of California, San Die).15 E(go)-.15 E(Murray S. K)127 280.2 Q(uchera) +-.15 E(wy)-.15 E 2.5(,H)-.65 G(ookUp Communication Corp.)227.41 280.2 Q +(Bruce Lilly)127 292.2 Q 2.5(,S)-.65 G(on)182.74 292.2 Q 2.5(yU)-.15 G(.S.) +207.31 292.2 Q(Karl London)127 304.2 Q(Motonori Nakamura, Ritsumeikan Uni)127 +316.2 Q -.15(ve)-.25 G(rsity & K).15 E(yoto Uni)-.25 E -.15(ve)-.25 G(rsity).15 +E(John Gardiner Myers, Carne)127 328.2 Q(gie Mellon Uni)-.15 E -.15(ve)-.25 G +(rsity).15 E(Neil Rick)127 340.2 Q(ert, Northern Illinois Uni)-.1 E -.15(ve) +-.25 G(rsity).15 E(Eric Schnoebelen, Con)127 352.2 Q .3 -.15(vex C)-.4 H +(omputer Corp.).15 E(Eric W)127 364.2 Q(assenaar)-.8 E 2.5(,N)-.4 G +(ational Institute for Nuclear and High Ener)200.49 364.2 Q(gy Ph)-.18 E +(ysics, Amsterdam)-.05 E(Christophe W)127 376.2 Q(olfhugel, P)-.8 E +(asteur Institute & Herv)-.15 E 2.5(eS)-.15 G(chauer Consultants \(P)330.05 +376.2 Q(aris\))-.15 E 3.219(Ia)87 392.4 S .719(pologize for an)97.989 392.4 R +.719(yone I ha)-.15 F 1.019 -.15(ve o)-.2 H .719(mitted, misspelled, misattrib) +.15 F .719(uted, or otherwise missed.)-.2 F .72(At this point, I)5.72 F 1.093 +(suspect that at least a hundred people ha)87 404.4 R 1.393 -.15(ve c)-.2 H +(ontrib).15 E 1.093(uted code, and man)-.2 F 3.592(ym)-.15 G 1.092(ore ha) +393.524 404.4 R 1.392 -.15(ve c)-.2 H(ontrib).15 E 1.092(uted ideas,)-.2 F +1.533(comments, and encouragement.)87 416.4 R(I')6.534 E 1.834 -.15(ve t)-.5 H +1.534(ried to list them in the RELEASE_NO).15 F 1.534(TES in the distrib)-.4 F +(ution)-.2 E(directory)87 428.4 Q 5(.I)-.65 G(appreciate their contrib)135.78 +428.4 Q(ution as well.)-.2 E .743(Special thanks are reserv)112 444.6 R .743 +(ed for Michael Corrig)-.15 F .742(an and Christophe W)-.05 F .742 +(olfhugel, who besides being)-.8 F -.1(wo)87 456.6 S 5.714 +(nderful guinea pigs and contrib).1 F 5.714(utors ha)-.2 F 6.015 -.15(ve a)-.2 +H 5.715(lso consented to be added to the `).15 F(`send-)-.74 E(mail@CS.Berk)87 +468.6 Q(ele)-.1 E -.65(y.)-.15 G(EDU').65 E 3.335('l)-.74 G .835 +(ist and, by answering the b)199.005 468.6 R .835 +(ulk of the questions sent to that list, ha)-.2 F 1.134 -.15(ve f)-.2 H(reed) +.15 E(me up to do other w)87 480.6 Q(ork.)-.1 E EP +%%Page: 65 60 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 12/Times-Bold@0 SF 3(APPENDIX A)257.172 98.4 R(COMMAND LINE FLA)224.832 +141.6 Q(GS)-.66 E/F1 10/Times-Roman@0 SF(Ar)97 201 Q +(guments must be presented with \215ags before addresses.)-.18 E +(The \215ags are:)5 E<ad62>72 217.2 Q/F2 10/Times-Italic@0 SF(x)A F1 +(Set operation mode to)144 217.2 Q F2(x)2.5 E F1 5(.O)C(peration modes are:) +253.71 217.2 Q 12.22(mD)184 233.4 S(eli)211.22 233.4 Q -.15(ve)-.25 G 2.5(rm) +.15 G(ail \(def)243.87 233.4 Q(ault\))-.1 E 16.11(sS)184 245.4 S +(peak SMTP on input side)209.56 245.4 Q 8.06(a\207 `)184 257.4 R -.8(`A)-.74 G +(rpanet').8 E 2.5('m)-.74 G(ode \(get en)257.53 257.4 Q -.15(ve)-.4 G +(lope sender information from header\)).15 E 15(dR)184 269.4 S(un as a daemon) +210.67 269.4 Q 17.22(tR)184 281.4 S(un in test mode)210.67 281.4 Q 15(vJ)184 +293.4 S(ust v)207.89 293.4 Q(erify addresses, don')-.15 E 2.5(tc)-.18 G +(ollect or deli)319.48 293.4 Q -.15(ve)-.25 G(r).15 E 17.22(iI)184 305.4 S +(nitialize the alias database)207.33 305.4 Q 15(pP)184 317.4 S +(rint the mail queue)209.56 317.4 Q<ad42>72 337.8 Q F2(type)A F1 +(Indicate body type.)144 337.8 Q<ad43>72 354 Q F2(\214le)A F1 .946(Use a dif) +144 354 R .946(ferent con\214guration \214le.)-.25 F F2(Sendmail)5.946 E F1 +.946(runs as the in)3.446 F -.2(vo)-.4 G .946(king user \(rather than root\)).2 +F(when this \215ag is speci\214ed.)144 366 Q<ad64>72 382.2 Q F2(le)A(vel)-.15 E +F1(Set deb)144 382.2 Q(ugging le)-.2 E -.15(ve)-.25 G(l.).15 E<ad66>72 398.4 Q +F2(addr)2.5 E F1(The sender')144 398.4 Q 2.5(sm)-.55 G(achine address is)205.1 +398.4 Q F2(addr)2.5 E F1(.)A<ad46>72 414.6 Q F2(name)A F1 +(Sets the full name of this user to)144 414.6 Q F2(name)2.5 E F1(.)A<ad68>72 +430.8 Q F2(cnt)2.5 E F1 .726(Sets the \231hop count\232 to)144 430.8 R F2(cnt) +3.226 E F1 5.725(.T)C .725 +(his represents the number of times this message has been)269.455 430.8 R .02 +(processed by)144 442.8 R F2(sendmail)2.52 E F1 .02(\(to the e)2.52 F .02 +(xtent that it is supported by the underlying netw)-.15 F(orks\).)-.1 E F2(Cnt) +5.02 E F1 1.521 +(is incremented during processing, and if it reaches MAXHOP \(currently 30\)) +144 454.8 R F2(sendmail)4.02 E F1(thro)144 466.8 Q(ws a)-.25 E -.1(wa)-.15 G +2.5(yt).1 G(he message with an error)199.6 466.8 Q(.)-.55 E 58.86(\255n Don')72 +483 R 2.5(td)-.18 G 2.5(oa)174.65 483 S(liasing or forw)186.59 483 Q(arding.) +-.1 E<ad72>72 499.2 Q F2(addr)2.5 E F1(An obsolete form of)144 499.2 Q/F3 10 +/Times-Bold@0 SF<ad66>2.5 E F1(.)A<ad6f>72 515.4 Q F2 1.666(xv)C(alue)-1.666 E +F1(Set option)144 515.4 Q F2(x)2.5 E F1(to the speci\214ed)2.5 E F2(value)2.5 E +F1 5(.T)C(hese options are described in Section 5.6.)292.6 515.4 Q<ad4f>72 +531.6 Q F2(option)A F3(=)A F2(value)A F1(Set)6.22 E F2(option)5.173 E F1 2.674 +(to the speci\214ed)5.173 F F2(value)5.174 E F1 2.674 +(\(for long form option names\).)5.174 F 2.674(These options are)7.674 F +(described in Section 5.6.)144 543.6 Q<ad4d>72 559.8 Q F2 1.666(xv)C 27.204 +(alue Set)-1.666 F(macr)2.5 E 2.5(oxt)-.45 G 2.5(ot)196.04 559.8 S +(he speci\214ed value)206.32 559.8 Q(.)-.15 E F1<ad70>72 576 Q F2(pr)A(otocol) +-.45 E F1 .401(Set the sending protocol.)144 576 R .401 +(Programs are encouraged to set this.)5.401 F .4(The protocol \214eld can be) +5.401 F .114(in the form)144 588 R F2(pr)2.614 E(otocol)-.45 E F3(:)A F2(host)A +F1 .114(to set both the sending protocol and sending host.)2.614 F -.15(Fo) +5.115 G 2.615(re).15 G(xample,)472.06 588 Q 2.147(\231\255pUUCP:uunet\232 sets\ + the sending protocol to UUCP and the sending host to uunet.)144 600 R .973 +(\(Some e)144 612 R .974 +(xisting programs use \255oM to set the r and s macros; this is equi)-.15 F +-.25(va)-.25 G .974(lent to using).25 F(\255p.\))144 624 Q<ad71>72 640.2 Q F2 +(time)A F1 -.35(Tr)144 640.2 S 3.168(yt).35 G 3.167(op)164.038 640.2 S .667 +(rocess the queued up mail.)177.205 640.2 R .667(If the time is gi)5.667 F -.15 +(ve)-.25 G .667(n, a).15 F F2(sendmail)3.167 E F1 .667(will run through the) +3.167 F(queue at the speci\214ed interv)144 652.2 Q(al to deli)-.25 E -.15(ve) +-.25 G 2.5(rq).15 G(ueued mail; otherwise, it only runs once.)310.82 652.2 Q +<ad71>72 668.4 Q F2(Xstring)A F1 .312 +(Run the queue once, limiting the jobs to those matching)144 668.4 R F2 +(Xstring)2.813 E F1 5.313(.T)C .313(he k)416.325 668.4 R .613 -.15(ey l)-.1 H +(etter).15 E F2(X)2.813 E F1 .313(can be)2.813 F F3(I)144 680.4 Q F1 .671 +(to limit based on queue identi\214er)3.171 F(,)-.4 E F3(R)3.171 E F1 .67 +(to limit based on recipient, or)3.171 F F3(S)3.17 E F1 .67(to limit based on) +3.17 F .32 LW 76 690 72 690 DL 80 690 76 690 DL 84 690 80 690 DL 88 690 84 690 +DL 92 690 88 690 DL 96 690 92 690 DL 100 690 96 690 DL 104 690 100 690 DL 108 +690 104 690 DL 112 690 108 690 DL 116 690 112 690 DL 120 690 116 690 DL 124 690 +120 690 DL 128 690 124 690 DL 132 690 128 690 DL 136 690 132 690 DL 140 690 136 +690 DL 144 690 140 690 DL 148 690 144 690 DL 152 690 148 690 DL 156 690 152 690 +DL 160 690 156 690 DL 164 690 160 690 DL 168 690 164 690 DL 172 690 168 690 DL +176 690 172 690 DL 180 690 176 690 DL 184 690 180 690 DL 188 690 184 690 DL 192 +690 188 690 DL 196 690 192 690 DL 200 690 196 690 DL 204 690 200 690 DL 208 690 +204 690 DL 212 690 208 690 DL 216 690 212 690 DL/F4 8/Times-Roman@0 SF +(\207Deprecated.)93.6 702 Q F3(Sendmail Installation and Operation Guide)72 756 +Q(SMM:08-65)452.9 756 Q EP +%%Page: 66 61 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-66 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(sender)144 96 Q +6.053(.A)-.55 G 1.054 +(particular queued job is accepted if one of the corresponding addresses con-) +188.876 96 R(tains the indicated)144 108 Q/F2 10/Times-Italic@0 SF(string)2.5 E +F1(.)A 61.08(\255t Read)72 124.2 R .752(the header for \231T)3.252 F .752 +(o:\232, \231Cc:\232, and \231Bcc:\232 lines, and send to e)-.8 F -.15(ve)-.25 +G .752(ryone listed in those).15 F 2.539(lists. The)144 136.2 R .039 +(\231Bcc:\232 line will be deleted before sending.)2.539 F(An)5.039 E 2.539(ya) +-.15 G .04(ddresses in the ar)385.31 136.2 R .04(gument v)-.18 F(ec-)-.15 E +(tor will be deleted from the send list.)144 148.2 Q<ad58>72 164.4 Q F2(lo)3.18 +E(g\214le)-.1 E F1 .68(Log all traf)144.68 164.4 R .68(\214c in and out of)-.25 +F F2(sendmail)3.179 E F1 .679(in the indicated)3.179 F F2(lo)3.179 E(g\214le) +-.1 E F1 .679(for deb)3.179 F .679(ugging mailer prob-)-.2 F 2.5(lems. This)144 +176.4 R(produces a lot of data v)2.5 E +(ery quickly and should be used sparingly)-.15 E(.)-.65 E .637 +(There are a number of options that may be speci\214ed as primiti)97 192.6 R +.938 -.15(ve \215)-.25 H 3.138(ags. These).15 F .638(are the e, i, m, and v) +3.138 F 2.5(options. Also,)72 204.6 R(the f option may be speci\214ed as the) +2.5 E F0<ad73>2.5 E F1(\215ag.)2.5 E EP +%%Page: 67 62 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 12/Times-Bold@0 SF 3(APPENDIX B)250.002 98.4 R -.12(QU)220.29 141.6 S +(EUE FILE FORMA).12 E(TS)-1.14 E/F1 10/Times-Roman@0 SF .292 +(This appendix describes the format of the queue \214les.)97 201 R .292 +(These \214les li)5.292 F .592 -.15(ve i)-.25 H 2.792(nt).15 G .291 +(he directory de\214ned by the)395.636 201 R/F2 10/Times-Bold@0 SF(Q)72 213 Q +F1(option in the)2.5 E/F3 10/Times-Italic@0 SF(sendmail.cf)2.5 E F1 +(\214le, usually)2.5 E F3(/var/spool/mqueue)2.5 E F1(or)2.5 E F3 +(/usr/spool/mqueue)2.5 E F1(.)A .229(All queue \214les ha)97 229.2 R .529 -.15 +(ve t)-.2 H .229(he name).15 F F3(x)2.729 E F2(f)1.666 E F3(AAA99999)A F1 +(where)2.73 E F3(AAA99999)2.73 E F1 .23(is the)2.73 F F3(id)2.73 E F1 .23 +(for this message and the)2.73 F F3(x)2.73 E F1 .23(is a)2.73 F 3.601 +(type. The)72 241.2 R 1.101 +(\214rst letter of the id encodes the hour of the day that the message w)3.601 +F 1.101(as recei)-.1 F -.15(ve)-.25 G 3.601(db).15 G 3.601(yt)451.798 241.2 S +1.101(he system)463.179 241.2 R .551 +(\(with A being the hour between midnight and 1:00AM\).)72 253.2 R .552 +(All \214les with the same id collecti)5.552 F -.15(ve)-.25 G .552 +(ly de\214ne one).15 F(message.)72 265.2 Q(The types are:)97 281.4 Q 31(dT)72 +297.6 S(he data \214le.)114.11 297.6 Q(The message body \(e)5 E +(xcluding the header\) is k)-.15 E(ept in this \214le.)-.1 E 31(qT)72 313.8 S +(he queue control \214le.)114.11 313.8 Q +(This \214le contains the information necessary to process the job)5 E(.)-.4 E +33.22(tA)72 330 S .345(temporary \214le.)118.065 330 R .344 +(These are an image of the)5.345 F F2(qf)2.844 E F1 .344 +(\214le when it is being reb)2.844 F 2.844(uilt. It)-.2 F .344 +(should be renamed)2.844 F(to a)108 342 Q F2(qf)2.5 E F1(\214le v)2.5 E +(ery quickly)-.15 E(.)-.65 E 31(xA)72 358.2 S .566(transcript \214le, e)118.286 +358.2 R .567(xisting during the life of a session sho)-.15 F .567(wing e)-.25 F +-.15(ve)-.25 G .567(rything that happens during that).15 F(session.)108 370.2 Q +(The)97 386.4 Q F2(qf)3.334 E F1 .834 +(\214le is structured as a series of lines each be)3.334 F .833 +(ginning with a code letter)-.15 F 5.833(.T)-.55 G .833(he lines are as fol-) +427.358 386.4 R(lo)72 398.4 Q(ws:)-.25 E 28.78(VT)72 414.6 S .819(he v)114.11 +414.6 R .819(ersion number of the queue \214le format, used to allo)-.15 F 3.32 +(wn)-.25 G -.25(ew)359.35 414.6 S F3(sendmail)3.57 E F1 .82 +(binaries to read queue)3.32 F .004(\214les created by older v)108 426.6 R +2.504(ersions. Def)-.15 F .004(aults to v)-.1 F .004(ersion zero.)-.15 F .004 +(Must be the \214rst line of the \214le if present.)5.004 F 28.78(HA)72 442.8 S +.329(header de\214nition.)118.049 442.8 R .329(There may be an)5.329 F 2.829 +(yn)-.15 G .329(umber of these lines.)274.283 442.8 R .33 +(The order is important: the)5.33 F 2.83(yr)-.15 G(epre-)483.46 442.8 Q .046 +(sent the order in the \214nal message.)108 454.8 R .046 +(These use the same syntax as header de\214nitions in the con\214gu-)5.046 F +(ration \214le.)108 466.8 Q 29.33(CT)72 483 S .575(he controlling address.) +114.11 483 R .575(The syntax is \231localuser:aliasname\232.)5.575 F .575 +(Recipient addresses follo)5.575 F .575(wing this)-.25 F 2.814 +(line will be \215agged so that deli)108 495 R -.15(ve)-.25 G 2.814 +(ries will be run as the).15 F F3(localuser)5.314 E F1 2.814 +(\(a user name from the)5.314 F .561(/etc/passwd \214le\);)108 507 R F3 +(aliasname)3.061 E F1 .561(is the name of the alias that e)3.061 F .562 +(xpanded to this address \(used for print-)-.15 F(ing messages\).)108 519 Q +28.78(QT)72 535.2 S .798(he `)114.11 535.2 R .798(`original recipient')-.74 F +.798(', speci\214ed by the ORCPT= \214eld in an ESMTP transaction.)-.74 F .797 +(Used e)5.797 F(xclu-)-.15 E(si)108 547.2 Q -.15(ve)-.25 G(ly for Deli).15 E +-.15(ve)-.25 G(ry Status Noti\214cations.).15 E +(It applies only to the immediately follo)5 E(wing `R' line.)-.25 E 29.33(RA)72 +563.4 S .705(recipient address.)118.425 563.4 R .705 +(This will normally be completely aliased, b)5.705 F .705 +(ut is actually realiased when the)-.2 F .493(job is processed.)108 575.4 R +.492(There will be one line for each recipient.)5.493 F -1.11(Ve)5.492 G .492 +(rsion 1 qf \214les also include a lead-)1.11 F .689(ing colon-terminated list\ + of \215ags, which can be `S' to return a message on successful \214nal deli) +108 587.4 R(v-)-.25 E(ery)108 599.4 Q 3.328(,`)-.65 G .828 +(F' to return a message on f)129.278 599.4 R .828 +(ailure, `D' to return a message if the message is delayed, `B' to)-.1 F .94 +(indicate that the body should be returned, `N' to suppress returning the body) +108 611.4 R 3.441(,a)-.65 G .941(nd `P' to declare)434.807 611.4 R(this as a `) +108 623.4 Q(`primary')-.74 E 2.5('\()-.74 G +(command line or SMTP-session\) address.)192.05 623.4 Q 30.44(ST)72 639.6 S +(he sender address.)114.11 639.6 Q(There may only be one of these lines.)5 E +29.89(TT)72 655.8 S(he job creation time.)114.11 655.8 Q +(This is used to compute when to time out the job)5 E(.)-.4 E 30.44(PT)72 672 S +.114(he current message priority)114.11 672 R 5.114(.T)-.65 G .113 +(his is used to order the queue.)236.666 672 R .113(Higher numbers mean lo) +5.113 F .113(wer priori-)-.25 F 3.676(ties. The)108 684 R 1.176 +(priority changes as the message sits in the queue.)3.676 F 1.177 +(The initial priority depends on the)6.176 F +(message class and the size of the message.)108 696 Q 27.11(MA)72 712.2 S 2.704 +(message. This)117.924 712.2 R .204(line is printed by the)2.704 F F3(mailq) +2.704 E F1 .203(command, and is generally used to store status infor)2.704 F(-) +-.2 E 2.5(mation. It)108 724.2 R(can contain an)2.5 E 2.5(yt)-.15 G -.15(ex) +219.78 724.2 S(t.).15 E F2(Sendmail Installation and Operation Guide)72 756 Q +(SMM:08-67)452.9 756 Q EP +%%Page: 68 63 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 193.36(SMM:08-68 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 30.44(FF)72 96 S +.043(lag bits, represented as one letter per \215ag.)113.56 96 R .043 +(De\214ned \215ag bits are)5.043 F F0(r)2.543 E F1 .044 +(indicating that this is a response)2.544 F .143(message and)108 108 R F0(w) +2.643 E F1 .143(indicating that a w)2.643 F .142 +(arning message has been sent announcing that the mail has been)-.1 F(delayed.) +108 120 Q 28.78(NT)72 136.2 S(he total number of deli)114.11 136.2 Q -.15(ve) +-.25 G(ry attempts.).15 E 28.78(KT)72 152.4 S +(he time \(as seconds since January 1, 1970\) of the last deli)114.11 152.4 Q +-.15(ve)-.25 G(ry attempt.).15 E 32.67(IT)72 168.6 S .724 +(he i-number of the data \214le; this can be used to reco)114.11 168.6 R -.15 +(ve)-.15 G 3.225(ry).15 G .725(our mail queue after a disastrous disk)350.23 +168.6 R(crash.)108 180.6 Q 31($A)72 196.8 S .83(macro de\214nition.)118.55 +196.8 R .83(The v)5.83 F .829 +(alues of certain macros \(as of this writing, only)-.25 F F0($r)3.329 E F1 +(and)3.329 E F0($s)3.329 E F1 3.329(\)a)C .829(re passed)466.241 196.8 R +(through to the queue run phase.)108 208.8 Q 29.33(BT)72 225 S .924 +(he body type.)114.11 225 R .925(The remainder of the line is a te)5.924 F .925 +(xt string de\214ning the body type.)-.15 F .925(If this \214eld is)5.925 F +.009(missing, the body type is assumed to be \231unde\214ned\232 and no specia\ +l processing is attempted.)108 237 R(Le)5.008 E -.05(ga)-.15 G(l).05 E -.25(va) +108 249 S(lues are \2317BIT\232 and \2318BITMIME\232.).25 E 28.78(OT)72 265.2 S +(he original MTS v)114.11 265.2 Q(alue \(from the ESMTP transaction\).)-.25 E +-.15(Fo)5 G 2.5(rD).15 G(eli)359.52 265.2 Q -.15(ve)-.25 G 2.5(rS).15 G +(tatus Noti\214cations only)389.95 265.2 Q(.)-.65 E 29.89(ZT)72 281.4 S +(he original en)114.11 281.4 Q -.15(ve)-.4 G +(lope id \(from the ESMTP transaction\).).15 E -.15(Fo)5 G 2.5(rD).15 G(eli) +360.88 281.4 Q -.15(ve)-.25 G 2.5(rS).15 G(tatus Noti\214cations only)391.31 +281.4 Q(.)-.65 E 4.072(As an e)97 297.6 R 4.072(xample, the follo)-.15 F 4.073 +(wing is a queue \214le sent to \231eric@mammoth.Berk)-.25 F(ele)-.1 E -.65(y.) +-.15 G 4.073(EDU\232 and).65 F(\231bostic@ok)72 311.6 Q(eef)-.1 E(fe.CS.Berk) +-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU\232).65 E/F2 7/Times-Roman@0 SF(1)219.09 +307.6 Q F1(:)222.59 311.6 Q(P835771)112 327.8 Q(T404261372)112 339.8 Q(Seric) +112 351.8 Q(Ceric:sendmail@v)112 363.8 Q(angogh.CS.Berk)-.25 E(ele)-.1 E -.65 +(y.)-.15 G(EDU).65 E(Reric@mammoth.Berk)112 375.8 Q(ele)-.1 E -.65(y.)-.15 G +(EDU).65 E(Rbostic@ok)112 387.8 Q(eef)-.1 E(fe.CS.Berk)-.25 E(ele)-.1 E -.65 +(y.)-.15 G(EDU).65 E(H?P?return-path: <o)112 399.8 Q(wner)-.25 E(-sendmail@v) +-.2 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU>).65 E(Hrecei)112 +411.8 Q -.15(ve)-.25 G(d: by v).15 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.) +-.15 G(EDU \(5.108/2.7\) id AAA06703;).65 E(Fri, 17 Jul 92 00:28:55 -0700)132 +423.8 Q(Hrecei)112 435.8 Q -.15(ve)-.25 G(d: from mail.CS.Berk).15 E(ele)-.1 E +-.65(y.)-.15 G(EDU by v).65 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G +(EDU \(5.108/2.7\)).65 E(id AAA06698; Fri, 17 Jul 92 00:28:54 -0700)132 447.8 Q +(Hrecei)112 459.8 Q -.15(ve)-.25 G(d: from [128.32.31.21] by mail.CS.Berk).15 E +(ele)-.1 E -.65(y.)-.15 G(EDU \(5.96/2.5\)).65 E +(id AA22777; Fri, 17 Jul 92 03:29:14 -0400)132 471.8 Q(Hrecei)112 483.8 Q -.15 +(ve)-.25 G(d: by foo.bar).15 E(.baz.de \(5.57/Ultrix3.0-C\))-.55 E +(id AA22757; Fri, 17 Jul 92 09:31:25 GMT)132 495.8 Q(H?F?from: eric@foo.bar)112 +507.8 Q(.baz.de \(Eric Allman\))-.55 E(H?x?full-name: Eric Allman)112 519.8 Q +(Hmessage-id: <9207170931.AA22757@foo.bar)112 531.8 Q(.baz.de>)-.55 E(HT)112 +543.8 Q(o: sendmail@v)-.8 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU) +.65 E(Hsubject: this is an e)112 555.8 Q(xample message)-.15 E .657(This sho)72 +572 R .658(ws the person who sent the message, the submission time \(in second\ +s since January 1, 1970\), the)-.25 F(message priority)72 584 Q 2.5(,t)-.65 G +(he message class, the recipients, and the headers for the message.)145.51 584 +Q .32 LW 76 669.2 72 669.2 DL 80 669.2 76 669.2 DL 84 669.2 80 669.2 DL 88 +669.2 84 669.2 DL 92 669.2 88 669.2 DL 96 669.2 92 669.2 DL 100 669.2 96 669.2 +DL 104 669.2 100 669.2 DL 108 669.2 104 669.2 DL 112 669.2 108 669.2 DL 116 +669.2 112 669.2 DL 120 669.2 116 669.2 DL 124 669.2 120 669.2 DL 128 669.2 124 +669.2 DL 132 669.2 128 669.2 DL 136 669.2 132 669.2 DL 140 669.2 136 669.2 DL +144 669.2 140 669.2 DL 148 669.2 144 669.2 DL 152 669.2 148 669.2 DL 156 669.2 +152 669.2 DL 160 669.2 156 669.2 DL 164 669.2 160 669.2 DL 168 669.2 164 669.2 +DL 172 669.2 168 669.2 DL 176 669.2 172 669.2 DL 180 669.2 176 669.2 DL 184 +669.2 180 669.2 DL 188 669.2 184 669.2 DL 192 669.2 188 669.2 DL 196 669.2 192 +669.2 DL 200 669.2 196 669.2 DL 204 669.2 200 669.2 DL 208 669.2 204 669.2 DL +212 669.2 208 669.2 DL 216 669.2 212 669.2 DL/F3 5/Times-Roman@0 SF(1)93.6 +679.6 Q/F4 8/Times-Roman@0 SF .719(This e)3.2 J .719(xample is contri)-.12 F +-.12(ve)-.2 G 2.719(da).12 G .719(nd probably inaccurate for your en)186.968 +682.8 R 2.719(vironment. Glance)-.32 F -.12(ove)2.718 G 2.718(ri).12 G 2.718 +(tt)384.998 682.8 S 2.718(og)392.164 682.8 S .718 +(et an idea; nothing can replace)402.882 682.8 R(looking at what your o)72 +692.4 Q(wn system generates.)-.2 E EP +%%Page: 69 64 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 12/Times-Bold@0 SF 3(APPENDIX C)249.672 98.4 R(SUMMAR)198.282 141.6 Q 3(YO) +-.42 G 3(FS)274.182 141.6 S(UPPOR)291.186 141.6 Q 3(TF)-.48 G(ILES)350.37 141.6 +Q/F1 10/Times-Roman@0 SF 1.52(This is a summary of the support \214les that)97 +201 R/F2 10/Times-Italic@0 SF(sendmail)4.019 E F1 1.519(creates or generates.) +4.019 F(Man)6.519 E 4.019(yo)-.15 G 4.019(ft)444.743 201 S 1.519(hese can be) +454.872 201 R(changed by editing the sendmail.cf \214le; check there to \214nd\ + the actual pathnames.)72 213 Q(/usr/sbin/sendmail)72 229.2 Q(The binary of)144 +241.2 Q F2(sendmail)2.5 E F1(.)A(/usr/bin/ne)72 257.4 Q -.1(wa)-.25 G(liases).1 +E 3.734(Al)144 269.4 S 1.235 +(ink to /usr/sbin/sendmail; causes the alias database to be reb)157.734 269.4 R +3.735(uilt. Running)-.2 F 1.235(this pro-)3.735 F(gram is completely equi)144 +281.4 Q -.25(va)-.25 G(lent to gi).25 E(ving)-.25 E F2(sendmail)2.5 E F1(the) +2.5 E/F3 10/Times-Bold@0 SF(\255bi)2.5 E F1(\215ag.)2.5 E 13.38 +(/usr/bin/mailq Prints)72 297.6 R 3.703(al)3.703 G 1.203 +(isting of the mail queue.)181.966 297.6 R 1.202(This program is equi)6.203 F +-.25(va)-.25 G 1.202(lent to using the).25 F F3(\255bp)3.702 E F1 1.202 +(\215ag to)3.702 F F2(sendmail)144 309.6 Q F1(.)A 5.9(/etc/sendmail.cf The)72 +325.8 R(con\214guration \214le, in te)2.5 E(xtual form.)-.15 E +(/usr/lib/sendmail.hf)72 342 Q(The SMTP help \214le.)144 354 Q 7 +(/etc/sendmail.st A)72 370.2 R(statistics \214le; need not be present.)2.5 E +.89(/etc/sendmail.pid Created)72 386.4 R .318 +(in daemon mode; it contains the process id of the current SMTP daemon.)2.818 F +.318(If you)5.318 F .338(use this in scripts; use `)144 398.4 R .338 +(`head \2551')-.74 F 2.838('t)-.74 G 2.838(og)285.786 398.4 S .338 +(et just the \214rst line; later v)298.624 398.4 R .337(ersions of)-.15 F F2 +(sendmail)2.837 E F1(may)2.837 E(add information to subsequent lines.)144 410.4 +Q 25.62(/etc/aliases The)72 426.6 R(te)2.5 E(xtual v)-.15 E +(ersion of the alias \214le.)-.15 E(/etc/aliases.{pag,dir})72 442.8 Q +(The alias \214le in)144 454.8 Q F2(dbm)2.5 E F1(\(3\) format.)1.666 E(/v)72 +471 Q(ar/spool/mqueue)-.25 E +(The directory in which the mail queue and temporary \214les reside.)144 483 Q +(/v)72 499.2 Q(ar/spool/mqueue/qf*)-.25 E +(Control \(queue\) \214les for messages.)144 511.2 Q(/v)72 527.4 Q +(ar/spool/mqueue/df*)-.25 E(Data \214les.)144 539.4 Q(/v)72 555.6 Q +(ar/spool/mqueue/tf*)-.25 E -.7(Te)144 567.6 S(mporary v).7 E +(ersions of the qf \214les, used during queue \214le reb)-.15 E(uild.)-.2 E(/v) +72 583.8 Q(ar/spool/mqueue/xf*)-.25 E 2.5(At)144 595.8 S +(ranscript of the current session.)156.5 595.8 Q F3 +(Sendmail Installation and Operation Guide)72 756 Q(SMM:08-69)452.9 756 Q EP +%%Page: 2 65 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 198.36(SMM:08-2 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF +(This page intentionally left blank;)256.225 300 Q +(replace it with a blank sheet for double-sided output.)218.6 312 Q EP +%%Page: 3 66 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-3)457.9 60 Q/F1 12/Times-Roman@0 SF -1.116(TA)263.226 98.4 S +(BLE OF CONTENTS)1.116 E/F2 10/Times-Roman@0 SF 2.5(1. B)72 124.8 R(ASIC INST) +-.35 E(ALLA)-.93 E 1.18(TION .................................................\ +..............................................................)-1.11 F(7)499 +124.8 Q 2.5(1.1. Compiling)87 139.2 R .43(Sendmail ...........................\ +..............................................................................\ +.....)2.5 F(7)499 139.2 Q 2.5(1.1.1. T)102 153.6 R(weaking the Mak)-.8 E 1.64(\ +e\214le ......................................................................\ +...........................)-.1 F(7)499 153.6 Q 2.5(1.1.2. Compilation)102 168 +R(and installation)2.5 E 28.5(................................................\ +........................................ 8)4.6 F 2.5(1.2. Con\214guration)87 +182.4 R .99(Files ............................................................\ +....................................................)2.5 F(8)499 182.4 Q 2.5 +(1.3. Details)87 196.8 R(of Installation Files)2.5 E 28.5(....................\ +..............................................................................\ +. 9)4.89 F 2.5(1.3.1. /usr/sbin/sendmail)102 211.2 R 28.5(....................\ +..............................................................................\ +....... 9)2.66 F 2.5(1.3.2. /etc/sendmail.cf)102 225.6 R 28.5(................\ +..............................................................................\ +.............. 9)4.9 F 2.5(1.3.3. /usr/bin/ne)102 240 R -.1(wa)-.25 G 2.19(lia\ +ses ..........................................................................\ +.............................).1 F(10)494 240 Q 2.5(1.3.4. /v)102 254.4 R 1.81 +(ar/spool/mqueue .............................................................\ +...........................................)-.25 F(10)494 254.4 Q 2.5 +(1.3.5. /etc/aliases*)102 268.8 R 23.5(.......................................\ +........................................................................... 10) +4.62 F 2.5(1.3.6. /etc/rc)102 283.2 R 23.5(...................................\ +..............................................................................\ +........... 10)3.51 F 2.5(1.3.7. /usr/lib/sendmail.hf)102 297.6 R 23.5(.......\ +..............................................................................\ +.................. 11)2.94 F 2.5(1.3.8. /etc/sendmail.st)102 312 R 23.5(......\ +..............................................................................\ +......................... 11)3.5 F 2.5(1.3.9. /usr/bin/mailq)102 326.4 R 23.5(\ +..............................................................................\ +................................. 11)4.88 F 2.5(2. NORMAL)72 340.8 R(OPERA)2.5 +E 1.56(TIONS .................................................................\ +............................................)-1.11 F(11)494 340.8 Q 2.5 +(2.1. The)87 355.2 R(System Log)2.5 E 23.5(...................................\ +..............................................................................\ +... 11)4.89 F 2.5(2.1.1. F)102 369.6 R 2.26(ormat ............................\ +..............................................................................\ +................)-.15 F(11)494 369.6 Q 2.5(2.1.2. Le)102 384 R -.15(ve)-.25 G +2.24(ls ......................................................................\ +.....................................................).15 F(13)494 384 Q 2.5 +(2.2. Dumping)87 398.4 R .72(State ...........................................\ +............................................................................) +2.5 F(13)494 398.4 Q 2.5(2.3. The)87 412.8 R(Mail Queue)2.5 E 23.5(...........\ +..............................................................................\ +............................ 13)2.96 F 2.5(2.3.1. Printing)102 427.2 R +(the queue)2.5 E 23.5(........................................................\ +................................................. 14)2.67 F 2.5(2.3.2. F)102 +441.6 R(orcing the queue)-.15 E 23.5(.........................................\ +................................................................ 14)3.94 F 2.5 +(2.4. The)87 456 R(Service Switch)2.5 E 23.5(.................................\ +..............................................................................\ +. 14)2.68 F 2.5(2.5. The)87 470.4 R(Alias Database)2.5 E 23.5(................\ +..............................................................................\ +.................. 15)2.69 F 2.5(2.5.1. Reb)102 484.8 R +(uilding the alias database)-.2 E 23.5(.......................................\ +................................................ 16)4.27 F 2.5 +(2.5.2. Potential)102 499.2 R .72(problems ...................................\ +.....................................................................)2.5 F(16) +494 499.2 Q 2.5(2.5.3. List)102 513.6 R -.25(ow)2.5 G 1.81(ners ..............\ +..............................................................................\ +.......................).25 F(16)494 513.6 Q 2.5(2.6. User)87 528 R +(Information Database)2.5 E 23.5(.............................................\ +....................................................... 17)2.7 F 2.5(2.7. Per) +87 542.4 R(-User F)-.2 E(orw)-.15 E(arding \(.forw)-.1 E(ard Files\))-.1 E 23.5 +(.............................................................................\ +...... 17)4.09 F 2.5(2.8. Special)87 556.8 R(Header Lines)2.5 E 23.5(.........\ +..............................................................................\ +...................... 17)2.97 F 2.5(2.8.1. Errors-T)102 571.2 R 2.09(o: .....\ +..............................................................................\ +..................................)-.8 F(17)494 571.2 Q 2.5 +(2.8.2. Apparently-T)102 585.6 R 2.09(o: .....................................\ +........................................................................)-.8 F +(17)494 585.6 Q 2.5(2.8.3. Precedence)102 600 R 23.5(.........................\ +..............................................................................\ +............. 17)2.97 F 2.5(2.9. IDENT)87 614.4 R(Protocol Support)2.5 E 23.5(\ +..............................................................................\ +......................... 18)2.95 F 2.5(3. ARGUMENTS)72 628.8 R 23.5(.........\ +..............................................................................\ +........................................ 18)3.78 F 2.5(3.1. Queue)87 643.2 R +(Interv)2.5 E 1.55(al ........................................................\ +...............................................................)-.25 F(18)494 +643.2 Q 2.5(3.2. Daemon)87 657.6 R 1.29(Mode .................................\ +..............................................................................\ +........)2.5 F(18)494 657.6 Q 2.5(3.3. F)87 672 R(orcing the Queue)-.15 E 23.5 +(.............................................................................\ +.................................... 19)4.22 F 2.5(3.4. Deb)87 686.4 R 1.76(ug\ +ging .........................................................................\ +....................................................)-.2 F(19)494 686.4 Q 2.5 +(3.5. Changing)87 700.8 R(the V)2.5 E(alues of Options)-1.11 E 23.5(..........\ +..............................................................................\ +.... 19)3.23 F 2.5(3.6. T)87 715.2 R(rying a Dif)-.35 E +(ferent Con\214guration File)-.25 E 23.5(.....................................\ +.............................................. 20)4.67 F EP +%%Page: 4 67 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 198.36(SMM:08-4 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 2.5 +(3.7. Logging)87 96 R -.35(Tr)2.5 G(af).35 E .5(\214c ........................\ +..............................................................................\ +................)-.25 F(20)494 96 Q 2.5(3.8. T)87 110.4 R +(esting Con\214guration Files)-.7 E 23.5(.....................................\ +.............................................................. 20)4.19 F 2.5 +(4. TUNING)72 124.8 R 23.5(...................................................\ +..............................................................................\ +........ 21)2.68 F 2.5(4.1. T)87 139.2 R 1.07(imeouts ........................\ +..............................................................................\ +..........................)-.35 F(21)494 139.2 Q 2.5(4.1.1. Queue)102 153.6 R +(interv)2.5 E 2.1(al .........................................................\ +.....................................................)-.25 F(21)494 153.6 Q 2.5 +(4.1.2. Read)102 168 R 1(timeouts ............................................\ +...................................................................)2.5 F(21) +494 168 Q 2.5(4.1.3. Message)102 182.4 R 1.56(timeouts .......................\ +..............................................................................\ +....)2.5 F(22)494 182.4 Q 2.5(4.2. F)87 196.8 R(orking During Queue Runs)-.15 E +23.5(.........................................................................\ +........................ 23)4.49 F 2.5(4.3. Queue)87 211.2 R .73(Priorities ..\ +..............................................................................\ +.....................................)2.5 F(23)494 211.2 Q 2.5(4.4. Load)87 +225.6 R .44(Limiting .........................................................\ +...............................................................)2.5 F(24)494 +225.6 Q 2.5(4.5. Deli)87 240 R -.15(ve)-.25 G(ry Mode).15 E 23.5(.............\ +..............................................................................\ +............................ 24)3.08 F 2.5(4.6. Log)87 254.4 R(Le)2.5 E -.15 +(ve)-.25 G 2.52(l.).15 G 23.5(................................................\ +..............................................................................\ + 24)153 254.4 R 2.5(4.7. File)87 268.8 R .72(Modes ...........................\ +..............................................................................\ +....................)2.5 F(25)494 268.8 Q 2.5(4.7.1. T)102 283.2 R 2.5(os)-.8 G +(uid or not to suid?)146.2 283.2 Q 23.5(......................................\ +........................................................... 25)6.52 F 2.5 +(4.7.2. Should)102 297.6 R(my alias database be writable?)2.5 E 23.5 +(........................................................................ 25) +5.47 F 2.5(4.8. Connection)87 312 R 1.56(Caching .............................\ +..............................................................................\ +...)2.5 F(25)494 312 Q 2.5(4.9. Name)87 326.4 R(Serv)2.5 E(er Access)-.15 E +23.5(.........................................................................\ +..................................... 26)2.85 F 2.5(4.10. Mo)87 340.8 R +(ving the Per)-.15 E(-User F)-.2 E(orw)-.15 E(ard Files)-.1 E 23.5(...........\ +......................................................................... 27) +3.84 F 2.5(4.11. Free)87 355.2 R 1.85(Space ..................................\ +..............................................................................\ +...........)2.5 F(27)494 355.2 Q 2.5(4.12. Maximum)87 369.6 R(Message Size)2.5 +E 23.5(.......................................................................\ +.............................. 27)4.62 F 2.5(4.13. Pri)87 384 R -.25(va)-.25 G +.3 -.15(cy F).25 H 1.93(lags .................................................\ +......................................................................).15 F +(27)494 384 Q 2.5(4.14. Send)87 398.4 R(to Me T)2.5 E 2.08(oo ................\ +..............................................................................\ +.....................)-.8 F(27)494 398.4 Q 2.5(5. THE)72 412.8 R +(WHOLE SCOOP ON THE CONFIGURA)2.5 E(TION FILE)-1.11 E 23.5 +(........................................................ 28)4.64 F 2.5(5.1. R) +87 427.2 R(and S \212 Re)2.5 E(writing Rules)-.25 E 23.5(.....................\ +............................................................................. \ +28)4.3 F 2.5(5.1.1. The)102 441.6 R(left hand side)2.5 E 23.5(................\ +..............................................................................\ +........... 28)4.07 F 2.5(5.1.2. The)102 456 R(right hand side)2.5 E 23.5(....\ +..............................................................................\ +..................... 29)3.51 F 2.5(5.1.3. Semantics)102 470.4 R(of re)2.5 E +(writing rule sets)-.25 E 23.5(...............................................\ +.................................... 30)4.6 F 2.5(5.1.4. IPC)102 484.8 R 1(mai\ +lers .........................................................................\ +..........................................)2.5 F(31)494 484.8 Q 2.5(5.2. D)87 +499.2 R 2.5<8a44>2.5 G(e\214ne Macro)136.44 499.2 Q 23.5(.....................\ +..............................................................................\ +............. 31)3.52 F 2.5(5.3. C)87 513.6 R(and F \212 De\214ne Classes)2.5 E +23.5(.........................................................................\ +............................ 34)2.67 F 2.5(5.4. M)87 528 R 2.5<8a44>2.5 G +(e\214ne Mailer)138.11 528 Q 23.5(............................................\ +................................................................... 35)3.79 F +2.5(5.5. H)87 542.4 R 2.5<8a44>2.5 G(e\214ne Header)136.44 542.4 Q 23.5(......\ +..............................................................................\ +........................... 38)3.25 F 2.5(5.6. O)87 556.8 R 2.5<8a53>2.5 G +(et Option)134.78 556.8 Q 23.5(...............................................\ +...................................................................... 38)3.22 +F 2.5(5.7. P)87 571.2 R 2.5<8a50>2.5 G(recedence De\214nitions)133.12 571.2 Q +23.5(.........................................................................\ +......................... 46)2.96 F 2.5(5.8. V)87 585.6 R 2.5<8a43>2.5 G +(on\214guration V)135.89 585.6 Q(ersion Le)-1.11 E -.15(ve)-.25 G 2.8(l.).15 G +23.5(.........................................................................\ +............... 46)248 585.6 R 2.5(5.9. K)87 600 R 2.5<8a4b>2.5 G .3 -.15(ey F) +136.19 600 T(ile Declaration).15 E 23.5(......................................\ +............................................................... 47)2.81 F 2.5 +(5.10. The)87 614.4 R(User Database)2.5 E 23.5(...............................\ +..............................................................................\ +. 50)4.92 F 2.5(5.10.1. Structure)102 628.8 R(of the user database)2.5 E 23.5(\ +..............................................................................\ +....... 50)2.7 F 2.5(5.10.2. User)102 643.2 R(database semantics)2.5 E 23.5(..\ +..............................................................................\ +............. 51)3.25 F 2.5(5.10.3. Creating)102 659.6 R(the database)2.5 E/F2 +7/Times-Roman@0 SF(21)220.59 655.6 Q F1 23.5(.................................\ +.............................................................. 51)230.5 659.6 R +2.5(6. O)72 674 R(THER CONFIGURA)-.4 E 1.97(TION .............................\ +............................................................................) +-1.11 F(52)494 674 Q 2.5(6.1. P)87 688.4 R(arameters in src/Mak)-.15 E 1.55(e\ +\214le .......................................................................\ +.............................)-.1 F(52)494 688.4 Q 2.5(6.2. P)87 702.8 R +(arameters in src/conf.h)-.15 E 23.5(.........................................\ +............................................................... 52)4.23 F 2.5 +(6.3. Con\214guration)87 717.2 R(in src/conf.c)2.5 E 23.5(....................\ +..............................................................................\ +.. 55)3.51 F EP +%%Page: 5 68 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q +(SMM:08-5)457.9 60 Q/F1 10/Times-Roman@0 SF 2.5(6.3.1. Built-in)102 96 R +(Header Semantics)2.5 E 23.5(.................................................\ +.......................................... 55)4.9 F 2.5(6.3.2. Restricting)102 +110.4 R(Use of Email)2.5 E 23.5(..............................................\ +................................................ 56)4.34 F 2.5(6.3.3. Load)102 +124.8 R -1.17 -.74(Av e)2.5 H(rage Computation).74 E 23.5(....................\ +...................................................................... 57)2.74 +F 2.5(6.3.4. Ne)102 139.2 R 2.5(wD)-.25 G(atabase Map Classes)157.85 139.2 Q +23.5(.........................................................................\ +................ 57)4.89 F 2.5(6.3.5. Queueing)102 153.6 R 1.56(Function .....\ +..............................................................................\ +....................)2.5 F(58)494 153.6 Q 2.5(6.3.6. Refusing)102 168 R +(Incoming SMTP Connections)2.5 E 23.5 +(....................................................................... 58) +2.94 F 2.5(6.3.7. Load)102 182.4 R -1.17 -.74(Av e)2.5 H(rage Computation).74 E +23.5(.........................................................................\ +................. 58)2.74 F 2.5(6.4. Con\214guration)87 196.8 R +(in src/daemon.c)2.5 E 23.5(..................................................\ +............................................ 58)4.62 F 2.5(7. CHANGES)72 211.2 +R(IN VERSION 8)2.5 E 23.5(....................................................\ +...................................................... 59)4.9 F 2.5 +(7.1. Connection)87 225.6 R 1.56(Caching .....................................\ +.........................................................................)2.5 F +(59)494 225.6 Q 2.5(7.2. MX)87 240 R 2.39(Piggybacking .......................\ +..............................................................................\ +............)2.5 F(59)494 240 Q 2.5(7.3. RFC)87 254.4 R(1123 Compliance)2.5 E +23.5(.........................................................................\ +................................. 59)3.77 F 2.5(7.4. Extended)87 268.8 R +(SMTP Support)2.5 E 23.5(.....................................................\ +.................................................. 59)2.94 F 2.5 +(7.5. Eight-Bit)87 283.2 R .44(Clean .........................................\ +.............................................................................) +2.5 F(59)494 283.2 Q 2.5(7.6. User)87 297.6 R .47(Database ...................\ +..............................................................................\ +.......................)2.5 F(59)494 297.6 Q 2.5(7.7. Impro)87 312 R -.15(ve) +-.15 G 2.5(dB).15 G(IND Support)154.75 312 Q 23.5(............................\ +........................................................................... 60) +3.81 F 2.5(7.8. K)87 326.4 R -.15(ey)-.25 G(ed Files).15 E 23.5(..............\ +..............................................................................\ +................................ 60)3.35 F 2.5(7.9. Multi-W)87 340.8 R +(ord Classes)-.8 E 23.5(......................................................\ +......................................................... 60)3.47 F 2.5 +(7.10. Deferred)87 355.2 R(Macro Expansion)2.5 E 23.5(........................\ +......................................................................... 60) +4.65 F 2.5(7.11. IDENT)87 369.6 R(Protocol Support)2.5 E 23.5(................\ +..............................................................................\ +....... 60)2.95 F 2.5(7.12. P)87 384 R(arsing Bug Fix)-.15 E .46(es ..........\ +..............................................................................\ +........................)-.15 F(60)494 384 Q 2.5(7.13. Separate)87 398.4 R(En) +2.5 E -.15(ve)-.4 G(lope/Header Processing).15 E 23.5(........................\ +........................................................ 60)4.37 F 2.5 +(7.14. Owner)87 412.8 R(-List Propag)-.2 E(ates to En)-.05 E -.15(ve)-.4 G 1.27 +(lope ........................................................................\ +............).15 F(60)494 412.8 Q 2.5(7.15. Dynamic)87 427.2 R +(Header Allocation)2.5 E 23.5(................................................\ +................................................ 60)3.25 F 2.5(7.16. Ne)87 +441.6 R 2.5(wC)-.25 G(ommand Line Flags)139.8 441.6 Q 23.5(...................\ +..............................................................................\ +. 60)3.2 F 2.5(7.17. Enhanced)87 456 R(Command Line Flags)2.5 E 23.5(.........\ +..............................................................................\ +.. 61)4.9 F 2.5(7.18. Ne)87 470.4 R 2.5(wa)-.25 G +(nd Old Con\214guration Line T)137.57 470.4 Q .4(ypes ........................\ +......................................................)-.8 F(61)494 470.4 Q 2.5 +(7.19. Ne)87 484.8 R 2.5(wO)-.25 G .7(ptions .................................\ +..............................................................................\ +.........)140.35 484.8 R(61)494 484.8 Q 2.5(7.20. Extended)87 499.2 R 1.56(Opt\ +ions .........................................................................\ +.......................................)2.5 F(61)494 499.2 Q 2.5(7.21. Ne)87 +513.6 R 2.5(wM)-.25 G(ailer Flags)142.02 513.6 Q 23.5(........................\ +..............................................................................\ +.......... 61)4.04 F 2.5(7.22. Long)87 528 R(Option Names)2.5 E 23.5(.........\ +..............................................................................\ +..................... 62)4.34 F 2.5(7.23. Ne)87 542.4 R 2.5(wP)-.25 G +(re-De\214ned Macros)138.69 542.4 Q 23.5(.....................................\ +............................................................... 62)4.06 F 2.5 +(7.24. Ne)87 556.8 R 2.5(wL)-.25 G(HS T)139.24 556.8 Q(ok)-.8 E 1.33(en ......\ +..............................................................................\ +..............................)-.1 F(62)494 556.8 Q 2.5(7.25. Bigger)87 571.2 R +(Def)2.5 E(aults .............................................................\ +.......................................................)-.1 E(62)494 571.2 Q +2.5(7.26. Dif)87 585.6 R(ferent Def)-.25 E(ault T)-.1 E(uning P)-.45 E 1.99(ar\ +ameters ......................................................................\ +............)-.15 F(62)494 585.6 Q 2.5(7.27. Auto-Quoting)87 600 R +(in Addresses)2.5 E 23.5(.....................................................\ +............................................ 63)3.51 F 2.5(7.28. Symbolic)87 +614.4 R(Names On Error Mailer)2.5 E 23.5(.....................................\ +................................................. 63)4.91 F 2.5(7.29. SMTP)87 +628.8 R(VRFY Doesn')2.5 E 2.5(tE)-.18 G 1.18(xpand ...........................\ +.................................................................)209.88 628.8 +R(63)494 628.8 Q 2.5(7.30. [IPC])87 643.2 R(Mailers Allo)2.5 E 2.5(wM)-.25 G +(ultiple Hosts)205.91 643.2 Q 23.5(...........................................\ +........................................ 63)3.75 F 2.5(7.31. Aliases)87 657.6 R +1.29(Extended ................................................................\ +.................................................)2.5 F(63)494 657.6 Q 2.5 +(7.32. Portability)87 672 R(and Security Enhancements)2.5 E 23.5(.............\ +.................................................................. 63)2.68 F +2.5(7.33. Miscellaneous)87 686.4 R 1.29(Changes ..............................\ +.........................................................................)2.5 F +(63)494 686.4 Q 2.5(8. A)72 700.8 R(CKNO)-.4 E .1(WLEDGEMENTS ................\ +..............................................................................\ +..............)-.35 F(63)494 700.8 Q(Appendix A.)72 715.2 Q(COMMAND LINE FLA)5 +E 1.97(GS ....................................................................\ +.....................)-.4 F(65)494 715.2 Q EP +%%Page: 6 69 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Bold@0 SF 198.36(SMM:08-6 Sendmail)72 60 R +(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(Appendix B.)72 +96 Q -.1(QU)5 G(EUE FILE FORMA).1 E 1.38(TS ..................................\ +..........................................................)-1.11 F(67)494 96 Q +(Appendix C.)72 110.4 Q(SUMMAR)5 E 2.5(YO)-.65 G 2.5(FS)188.85 110.4 S(UPPOR) +202.47 110.4 Q 2.5(TF)-.6 G 1.12(ILES ........................................\ +......................................)248.27 110.4 R(69)494 110.4 Q EP +%%Trailer +end +%%EOF diff --git a/usr.sbin/sendmail/mail.local/Makefile b/usr.sbin/sendmail/mail.local/Makefile new file mode 100644 index 000000000000..e8556d8ea5c6 --- /dev/null +++ b/usr.sbin/sendmail/mail.local/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 7/19/93 + +PROG= mail.local +MAN8= mail.local.0 +BINOWN= root +BINMODE=4555 +INSTALLFLAGS=-fschg + +.include <bsd.prog.mk> diff --git a/usr.sbin/sendmail/mail.local/mail.local.8 b/usr.sbin/sendmail/mail.local/mail.local.8 new file mode 100644 index 000000000000..661615c462f8 --- /dev/null +++ b/usr.sbin/sendmail/mail.local/mail.local.8 @@ -0,0 +1,105 @@ +.\" Copyright (c) 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)mail.local.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt MAIL.LOCAL 8 +.Os +.Sh NAME +.Nm mail.local +.Nd store mail in a mailbox +.Sh SYNOPSIS +.Nm mail.local +.Op Fl f Ar from +.Ar user ... +.Sh DESCRIPTION +.Nm Mail.local +reads the standard input up to an end-of-file and appends it to each +.Ar user's +.Pa mail +file. +The +.Ar user +must be a valid user name. +.Pp +The options are as follows: +.Bl -tag -width xxxfrom +.It Fl f Ar from +Specify the sender's name. +.El +.Pp +Individual mail messages in the mailbox are delimited by an empty +line followed by a line beginning with the string ``From ''. +A line containing the string ``From '', the sender's name and a time stamp +is prepended to each delivered mail message. +A blank line is appended to each message. +A greater-than character (``>'') is prepended to any line in the message +which could be mistaken for a ``From '' delimiter line. +.Pp +The mail files are exclusively locked with +.Xr flock 2 +while mail is appended. +.Pp +If the ``biff'' service is returned by +.Xr getservbyname 3 , +the biff server is notified of delivered mail. +.Pp +The +.Nm mail.local +utility exits 0 on success, and >0 if an error occurs. +.Sh ENVIRONMENT +.Bl -tag -width indent +.It Ev TZ +Used to set the appropriate time zone on the timestamp. +.El +.Sh FILES +.Bl -tag -width /tmp/local.XXXXXX -compact +.It Pa /tmp/local.XXXXXX +temporary files +.It Pa /var/mail/user +user's mailbox directory +.El +.Sh SEE ALSO +.Xr mail 1 , +.Xr xsend 1 , +.Xr flock 2 , +.Xr getservbyname 3 , +.Xr comsat 8 , +.Xr sendmail 8 +.Sh HISTORY +A superset of +.Nm mail.local +(handling mailbox reading as well as mail delivery) +appeared in +.At v7 . +as the program +.Nm mail . diff --git a/usr.sbin/sendmail/mail.local/mail.local.c b/usr.sbin/sendmail/mail.local/mail.local.c new file mode 100644 index 000000000000..1ee4466c36b5 --- /dev/null +++ b/usr.sbin/sendmail/mail.local/mail.local.c @@ -0,0 +1,868 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1990, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)mail.local.c 8.22 (Berkeley) 6/21/95"; +#endif /* not lint */ + +/* + * This is not intended to compile on System V derived systems + * such as Solaris or HP-UX, since they use a totally different + * approach to mailboxes (essentially, they have a setgid program + * rather than setuid, and they rely on the ability to "give away" + * files to do their work). IT IS NOT A BUG that this doesn't + * compile on such architectures. + */ + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <errno.h> +#include <fcntl.h> +#include <netdb.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <syslog.h> +#include <time.h> +#include <unistd.h> +#include <ctype.h> + +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#ifndef LOCK_EX +# include <sys/file.h> +#endif + +#ifdef BSD4_4 +# include "pathnames.h" +#endif + +#ifndef __P +# ifdef __STDC__ +# define __P(protos) protos +# else +# define __P(protos) () +# define const +# endif +#endif +#ifndef __dead +# if defined(__GNUC__) && (__GNUC__ < 2 || __GNUC_MINOR__ < 5) && !defined(__STRICT_ANSI__) +# define __dead __volatile +# else +# define __dead +# endif +#endif + +#ifndef BSD4_4 +# define _BSD_VA_LIST_ va_list +extern char *strerror __P((int)); +extern int snprintf __P((char *, int, const char *, ...)); +#endif + +/* + * If you don't have setreuid, and you have saved uids, and you have + * a seteuid() call that doesn't try to emulate using setuid(), then + * you can try defining USE_SETEUID. + */ +#ifdef USE_SETEUID +# define setreuid(r, e) seteuid(e) +#endif + +#ifndef _PATH_LOCTMP +# define _PATH_LOCTMP "/tmp/local.XXXXXX" +#endif +#ifndef _PATH_MAILDIR +# define _PATH_MAILDIR "/var/spool/mail" +#endif + +#ifndef S_ISREG +# define S_ISREG(mode) (((mode) & _S_IFMT) == S_IFREG) +#endif + +int eval = EX_OK; /* sysexits.h error value. */ + +void deliver __P((int, char *)); +void e_to_sys __P((int)); +__dead void err __P((const char *, ...)); +void notifybiff __P((char *)); +int store __P((char *)); +void usage __P((void)); +void vwarn __P((const char *, _BSD_VA_LIST_)); +void warn __P((const char *, ...)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + struct passwd *pw; + int ch, fd; + uid_t uid; + char *from; + extern char *optarg; + extern int optind; + + /* make sure we have some open file descriptors */ + for (fd = 10; fd < 30; fd++) + (void) close(fd); + + /* use a reasonable umask */ + (void) umask(0077); + +#ifdef LOG_MAIL + openlog("mail.local", 0, LOG_MAIL); +#else + openlog("mail.local", 0); +#endif + + from = NULL; + while ((ch = getopt(argc, argv, "df:r:")) != EOF) + switch(ch) { + case 'd': /* Backward compatible. */ + break; + case 'f': + case 'r': /* Backward compatible. */ + if (from != NULL) { + warn("multiple -f options"); + usage(); + } + from = optarg; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (!*argv) + usage(); + + /* + * If from not specified, use the name from getlogin() if the + * uid matches, otherwise, use the name from the password file + * corresponding to the uid. + */ + uid = getuid(); + if (!from && (!(from = getlogin()) || + !(pw = getpwnam(from)) || pw->pw_uid != uid)) + from = (pw = getpwuid(uid)) ? pw->pw_name : "???"; + + /* + * There is no way to distinguish the error status of one delivery + * from the rest of the deliveries. So, if we failed hard on one + * or more deliveries, but had no failures on any of the others, we + * return a hard failure. If we failed temporarily on one or more + * deliveries, we return a temporary failure regardless of the other + * failures. This results in the delivery being reattempted later + * at the expense of repeated failures and multiple deliveries. + */ + for (fd = store(from); *argv; ++argv) + deliver(fd, *argv); + exit(eval); +} + +int +store(from) + char *from; +{ + FILE *fp; + time_t tval; + int fd, eline; + char line[2048]; + char tmpbuf[sizeof _PATH_LOCTMP + 1]; + + strcpy(tmpbuf, _PATH_LOCTMP); + if ((fd = mkstemp(tmpbuf)) == -1 || (fp = fdopen(fd, "w+")) == NULL) { + e_to_sys(errno); + err("unable to open temporary file"); + } + (void)unlink(tmpbuf); + + (void)time(&tval); + (void)fprintf(fp, "From %s %s", from, ctime(&tval)); + + line[0] = '\0'; + for (eline = 1; fgets(line, sizeof(line), stdin);) { + if (line[0] == '\n') + eline = 1; + else { + if (eline && line[0] == 'F' && + !memcmp(line, "From ", 5)) + (void)putc('>', fp); + eline = 0; + } + (void)fprintf(fp, "%s", line); + if (ferror(fp)) { + e_to_sys(errno); + err("temporary file write error"); + } + } + + /* If message not newline terminated, need an extra. */ + if (!strchr(line, '\n')) + (void)putc('\n', fp); + /* Output a newline; note, empty messages are allowed. */ + (void)putc('\n', fp); + + if (fflush(fp) == EOF || ferror(fp)) { + e_to_sys(errno); + err("temporary file write error"); + } + return (fd); +} + +void +deliver(fd, name) + int fd; + char *name; +{ + struct stat fsb, sb; + struct passwd *pw; + int mbfd, nr, nw, off; + char *p; + char biffmsg[100], buf[8*1024], path[MAXPATHLEN]; + off_t curoff; + + /* + * Disallow delivery to unknown names -- special mailboxes can be + * handled in the sendmail aliases file. + */ + if (!(pw = getpwnam(name))) { + if (eval != EX_TEMPFAIL) + eval = EX_UNAVAILABLE; + warn("unknown name: %s", name); + return; + } + endpwent(); + + /* + * Keep name reasonably short to avoid buffer overruns. + * This isn't necessary on BSD because of the proper + * definition of snprintf(), but it can cause problems + * on other systems. + * Also, clear out any bogus characters. + */ + + if (strlen(name) > 40) + name[40] = '\0'; + for (p = name; *p != '\0'; p++) + { + if (!isascii(*p)) + *p &= 0x7f; + else if (!isprint(*p)) + *p = '.'; + } + + (void)snprintf(path, sizeof(path), "%s/%s", _PATH_MAILDIR, name); + + /* + * If the mailbox is linked or a symlink, fail. There's an obvious + * race here, that the file was replaced with a symbolic link after + * the lstat returned, but before the open. We attempt to detect + * this by comparing the original stat information and information + * returned by an fstat of the file descriptor returned by the open. + * + * NB: this is a symptom of a larger problem, that the mail spooling + * directory is writeable by the wrong users. If that directory is + * writeable, system security is compromised for other reasons, and + * it cannot be fixed here. + * + * If we created the mailbox, set the owner/group. If that fails, + * just return. Another process may have already opened it, so we + * can't unlink it. Historically, binmail set the owner/group at + * each mail delivery. We no longer do this, assuming that if the + * ownership or permissions were changed there was a reason. + * + * XXX + * open(2) should support flock'ing the file. + */ +tryagain: + lockmbox(path); + if (lstat(path, &sb)) { + mbfd = open(path, + O_APPEND|O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR); + if (mbfd == -1) { + if (errno == EEXIST) + goto tryagain; + } else if (fchown(mbfd, pw->pw_uid, pw->pw_gid)) { + e_to_sys(errno); + warn("chown %u.%u: %s", pw->pw_uid, pw->pw_gid, name); + goto err1; + } + } else if (sb.st_nlink != 1 || !S_ISREG(sb.st_mode)) { + e_to_sys(errno); + warn("%s: irregular file", path); + goto err0; + } else if (sb.st_uid != pw->pw_uid) { + warn("%s: wrong ownership (%d)", path, sb.st_uid); + unlockmbox(); + return; + } else { + mbfd = open(path, O_APPEND|O_WRONLY, 0); + if (mbfd != -1 && + (fstat(mbfd, &fsb) || fsb.st_nlink != 1 || + !S_ISREG(fsb.st_mode) || sb.st_dev != fsb.st_dev || + sb.st_ino != fsb.st_ino || sb.st_uid != fsb.st_uid)) { + warn("%s: file changed after open", path); + goto err1; + } + } + + if (mbfd == -1) { + e_to_sys(errno); + warn("%s: %s", path, strerror(errno)); + goto err0; + } + + /* Wait until we can get a lock on the file. */ + if (flock(mbfd, LOCK_EX)) { + e_to_sys(errno); + warn("%s: %s", path, strerror(errno)); + goto err1; + } + + /* Get the starting offset of the new message for biff. */ + curoff = lseek(mbfd, (off_t)0, SEEK_END); + (void)snprintf(biffmsg, sizeof(biffmsg), + sizeof curoff > sizeof(long) ? "%s@%qd\n" : "%s@%ld\n", + name, curoff); + + /* Copy the message into the file. */ + if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { + e_to_sys(errno); + warn("temporary file: %s", strerror(errno)); + goto err1; + } + if (setreuid(0, pw->pw_uid) < 0) { + e_to_sys(errno); + warn("setreuid(0, %d): %s (r=%d, e=%d)", + pw->pw_uid, strerror(errno), getuid(), geteuid()); + goto err1; + } +#ifdef DEBUG + printf("new euid = %d\n", geteuid()); +#endif + while ((nr = read(fd, buf, sizeof(buf))) > 0) + for (off = 0; off < nr; off += nw) + if ((nw = write(mbfd, buf + off, nr - off)) < 0) { + e_to_sys(errno); + warn("%s: %s", path, strerror(errno)); + goto err3; + } + if (nr < 0) { + e_to_sys(errno); + warn("temporary file: %s", strerror(errno)); + goto err3; + } + + /* Flush to disk, don't wait for update. */ + if (fsync(mbfd)) { + e_to_sys(errno); + warn("%s: %s", path, strerror(errno)); +err3: + if (setreuid(0, 0) < 0) { + e_to_sys(errno); + warn("setreuid(0, 0): %s", strerror(errno)); + } +#ifdef DEBUG + printf("reset euid = %d\n", geteuid()); +#endif +err2: (void)ftruncate(mbfd, curoff); +err1: (void)close(mbfd); +err0: unlockmbox(); + return; + } + + /* Close and check -- NFS doesn't write until the close. */ + if (close(mbfd)) { + e_to_sys(errno); + warn("%s: %s", path, strerror(errno)); + unlockmbox(); + return; + } + + if (setreuid(0, 0) < 0) { + e_to_sys(errno); + warn("setreuid(0, 0): %s", strerror(errno)); + } +#ifdef DEBUG + printf("reset euid = %d\n", geteuid()); +#endif + unlockmbox(); + notifybiff(biffmsg); +} + +/* + * user.lock files are necessary for compatibility with other + * systems, e.g., when the mail spool file is NFS exported. + * Alas, mailbox locking is more than just a local matter. + * EPA 11/94. + */ + +char lockname[MAXPATHLEN]; +int locked = 0; + +lockmbox(path) + char *path; +{ + int statfailed = 0; + + if (locked) + return; + sprintf(lockname, "%s.lock", path); + for (;; sleep(5)) { + int fd; + struct stat st; + time_t now; + + fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT, 0); + if (fd >= 0) { + locked = 1; + close(fd); + return; + } + if (stat(lockname, &st) < 0) { + if (statfailed++ > 5) + return; + continue; + } + statfailed = 0; + time(&now); + if (now < st.st_ctime + 300) + continue; + unlink(lockname); + } +} + +unlockmbox() +{ + if (!locked) + return; + unlink(lockname); + locked = 0; +} + +void +notifybiff(msg) + char *msg; +{ + static struct sockaddr_in addr; + static int f = -1; + struct hostent *hp; + struct servent *sp; + int len; + + if (!addr.sin_family) { + /* Be silent if biff service not available. */ + if (!(sp = getservbyname("biff", "udp"))) + return; + if (!(hp = gethostbyname("localhost"))) { + warn("localhost: %s", strerror(errno)); + return; + } + addr.sin_family = hp->h_addrtype; + memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); + addr.sin_port = sp->s_port; + } + if (f < 0 && (f = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + warn("socket: %s", strerror(errno)); + return; + } + len = strlen(msg) + 1; + if (sendto(f, msg, len, 0, (struct sockaddr *)&addr, sizeof(addr)) + != len) + warn("sendto biff: %s", strerror(errno)); +} + +void +usage() +{ + eval = EX_USAGE; + err("usage: mail.local [-f from] user ..."); +} + +#if __STDC__ +void +err(const char *fmt, ...) +#else +void +err(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + vwarn(fmt, ap); + va_end(ap); + + exit(eval); +} + +void +#if __STDC__ +warn(const char *fmt, ...) +#else +warn(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + vwarn(fmt, ap); + va_end(ap); +} + +void +vwarn(fmt, ap) + const char *fmt; + _BSD_VA_LIST_ ap; +{ + /* + * Log the message to stderr. + * + * Don't use LOG_PERROR as an openlog() flag to do this, + * it's not portable enough. + */ + if (eval != EX_USAGE) + (void)fprintf(stderr, "mail.local: "); + (void)vfprintf(stderr, fmt, ap); + (void)fprintf(stderr, "\n"); + +#if !defined(ultrix) && !defined(__osf__) + /* Log the message to syslog. */ + vsyslog(LOG_ERR, fmt, ap); +#else + { + char fmtbuf[10240]; + + (void) sprintf(fmtbuf, fmt, ap); + syslog(LOG_ERR, "%s", fmtbuf); + } +#endif +} + +/* + * e_to_sys -- + * Guess which errno's are temporary. Gag me. + */ +void +e_to_sys(num) + int num; +{ + /* Temporary failures override hard errors. */ + if (eval == EX_TEMPFAIL) + return; + + switch(num) { /* Hopefully temporary errors. */ +#ifdef EAGAIN + case EAGAIN: /* Resource temporarily unavailable */ +#endif +#ifdef EDQUOT + case EDQUOT: /* Disc quota exceeded */ +#endif +#ifdef EBUSY + case EBUSY: /* Device busy */ +#endif +#ifdef EPROCLIM + case EPROCLIM: /* Too many processes */ +#endif +#ifdef EUSERS + case EUSERS: /* Too many users */ +#endif +#ifdef ECONNABORTED + case ECONNABORTED: /* Software caused connection abort */ +#endif +#ifdef ECONNREFUSED + case ECONNREFUSED: /* Connection refused */ +#endif +#ifdef ECONNRESET + case ECONNRESET: /* Connection reset by peer */ +#endif +#ifdef EDEADLK + case EDEADLK: /* Resource deadlock avoided */ +#endif +#ifdef EFBIG + case EFBIG: /* File too large */ +#endif +#ifdef EHOSTDOWN + case EHOSTDOWN: /* Host is down */ +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: /* No route to host */ +#endif +#ifdef EMFILE + case EMFILE: /* Too many open files */ +#endif +#ifdef ENETDOWN + case ENETDOWN: /* Network is down */ +#endif +#ifdef ENETRESET + case ENETRESET: /* Network dropped connection on reset */ +#endif +#ifdef ENETUNREACH + case ENETUNREACH: /* Network is unreachable */ +#endif +#ifdef ENFILE + case ENFILE: /* Too many open files in system */ +#endif +#ifdef ENOBUFS + case ENOBUFS: /* No buffer space available */ +#endif +#ifdef ENOMEM + case ENOMEM: /* Cannot allocate memory */ +#endif +#ifdef ENOSPC + case ENOSPC: /* No space left on device */ +#endif +#ifdef EROFS + case EROFS: /* Read-only file system */ +#endif +#ifdef ESTALE + case ESTALE: /* Stale NFS file handle */ +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: /* Connection timed out */ +#endif +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN && EWOULDBLOCK != EDEADLK + case EWOULDBLOCK: /* Operation would block. */ +#endif + eval = EX_TEMPFAIL; + break; + default: + eval = EX_UNAVAILABLE; + break; + } +} + +#ifndef BSD4_4 + +# ifndef __osf__ +char * +strerror(eno) + int eno; +{ + extern int sys_nerr; + extern char *sys_errlist[]; + static char ebuf[60]; + + if (eno >= 0 && eno <= sys_nerr) + return sys_errlist[eno]; + (void) sprintf(ebuf, "Error %d", eno); + return ebuf; +} +# endif + +# if __STDC__ +snprintf(char *buf, int bufsiz, const char *fmt, ...) +# else +snprintf(buf, bufsiz, fmt, va_alist) + char *buf; + int bufsiz; + const char *fmt; + va_dcl +# endif +{ + va_list ap; + +# if __STDC__ + va_start(ap, fmt); +# else + va_start(ap); +# endif + vsprintf(buf, fmt, ap); + va_end(ap); +} + +#endif + +#ifdef ultrix + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <ctype.h> + +static int _gettemp(); + +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd) ? fd : -1); +} + +/* +char * +mktemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); +} +*/ + +static +_gettemp(path, doopen) + char *path; + register int *doopen; +{ + extern int errno; + register char *start, *trv; + struct stat sbuf; + u_int pid; + + pid = getpid(); + for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + if (stat(path, &sbuf)) + return(0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return(0); + } + *trv = '/'; + break; + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return(1); + if (errno != EEXIST) + return(0); + } + else if (stat(path, &sbuf)) + return(errno == ENOENT ? 1 : 0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return(0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit(*trv)) + *trv = 'a'; + else + ++*trv; + break; + } + } + } + /*NOTREACHED*/ +} + +#endif diff --git a/usr.sbin/sendmail/mail.local/pathnames.h b/usr.sbin/sendmail/mail.local/pathnames.h new file mode 100644 index 000000000000..8e43925450f6 --- /dev/null +++ b/usr.sbin/sendmail/mail.local/pathnames.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/4/93 + */ +#include <paths.h> + +#define _PATH_LOCTMP "/tmp/local.XXXXXX" diff --git a/usr.sbin/sendmail/mailstats/mailstats.c b/usr.sbin/sendmail/mailstats/mailstats.c new file mode 100644 index 000000000000..97ec33be7e92 --- /dev/null +++ b/usr.sbin/sendmail/mailstats/mailstats.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 1983 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)mailstats.c 8.4 (Berkeley) 8/14/94"; +#endif /* not lint */ + +#include <sendmail.h> +#include <mailstats.h> +#include <pathnames.h> + +#define MNAMELEN 20 /* max length of mailer name */ + +main(argc, argv) + int argc; + char **argv; +{ + extern char *optarg; + extern int optind; + struct statistics stat; + register int i; + int mno; + int ch, fd; + char *sfile; + char *cfile; + FILE *cfp; + bool mnames; + long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0; + char mtable[MAXMAILERS][MNAMELEN+1]; + char sfilebuf[100]; + char buf[MAXLINE]; + extern char *ctime(); + + cfile = _PATH_SENDMAILCF; + sfile = NULL; + mnames = TRUE; + while ((ch = getopt(argc, argv, "C:f:o")) != EOF) + { + switch (ch) + { + case 'C': + cfile = optarg; + break; + + case 'f': + sfile = optarg; + break; + + case 'o': + mnames = FALSE; + break; + + case '?': + default: + usage: + fputs("usage: mailstats [-C cffile] [-f stfile]\n", stderr); + exit(EX_USAGE); + } + } + argc -= optind; + argv += optind; + + if (argc != 0) + goto usage; + + if ((cfp = fopen(cfile, "r")) == NULL) + { + fprintf(stderr, "mailstats: "); + perror(cfile); + exit(EX_NOINPUT); + } + + mno = 0; + (void) strcpy(mtable[mno++], "prog"); + (void) strcpy(mtable[mno++], "*file*"); + (void) strcpy(mtable[mno++], "*include*"); + + while (fgets(buf, sizeof(buf), cfp) != NULL) + { + register char *b; + char *s; + register char *m; + + b = buf; + switch (*b++) + { + case 'M': /* mailer definition */ + break; + + case 'O': /* option -- see if .st file */ + if (strncasecmp(b, " StatusFile", 11) == 0 && + !isalnum(b[11])) + { + /* new form -- find value */ + b = strchr(b, '='); + if (b == NULL) + continue; + while (isspace(*++b)) + continue; + } + else if (*b++ != 'S') + { + /* something else boring */ + continue; + } + + /* this is the S or StatusFile option -- save it */ + strcpy(sfilebuf, b); + b = strchr(sfilebuf, '#'); + if (b == NULL) + b = strchr(sfilebuf, '\n'); + if (b == NULL) + b = &sfilebuf[strlen(sfilebuf)]; + while (isspace(*--b)) + continue; + *++b = '\0'; + if (sfile == NULL) + sfile = sfilebuf; + + default: + continue; + } + + if (mno >= MAXMAILERS) + { + fprintf(stderr, + "Too many mailers defined, %d max.\n", + MAXMAILERS); + exit(EX_SOFTWARE); + } + m = mtable[mno]; + s = m + MNAMELEN; /* is [MNAMELEN+1] */ + while (*b != ',' && !isspace(*b) && *b != '\0' && m < s) + *m++ = *b++; + *m = '\0'; + for (i = 0; i < mno; i++) + { + if (strcmp(mtable[i], mtable[mno]) == 0) + break; + } + if (i == mno) + mno++; + } + (void) fclose(cfp); + for (; mno < MAXMAILERS; mno++) + mtable[mno][0]='\0'; + + if (sfile == NULL) + { + fprintf(stderr, "mailstats: no statistics file located\n"); + exit (EX_OSFILE); + } + + if ((fd = open(sfile, O_RDONLY)) < 0) { + fputs("mailstats: ", stderr); + perror(sfile); + exit(EX_NOINPUT); + } + if (read(fd, &stat, sizeof(stat)) != sizeof(stat) || + stat.stat_size != sizeof(stat)) + { + fputs("mailstats: file size changed.\n", stderr); + exit(EX_OSERR); + } + + printf("Statistics from %s", ctime(&stat.stat_itime)); + printf(" M msgsfr bytes_from msgsto bytes_to%s\n", + mnames ? " Mailer" : ""); + for (i = 0; i < MAXMAILERS; i++) + { + if (stat.stat_nf[i] || stat.stat_nt[i]) + { + printf("%2d %6ld %10ldK %6ld %10ldK", i, + stat.stat_nf[i], stat.stat_bf[i], + stat.stat_nt[i], stat.stat_bt[i]); + if (mnames) + printf(" %s", mtable[i]); + printf("\n"); + frmsgs += stat.stat_nf[i]; + frbytes += stat.stat_bf[i]; + tomsgs += stat.stat_nt[i]; + tobytes += stat.stat_bt[i]; + } + } + printf("========================================\n"); + printf(" T %6ld %10ldK %6ld %10ldK\n", + frmsgs, frbytes, tomsgs, tobytes); + exit(EX_OK); +} diff --git a/usr.sbin/sendmail/makemap/makemap.8 b/usr.sbin/sendmail/makemap/makemap.8 new file mode 100644 index 000000000000..23ac522a568f --- /dev/null +++ b/usr.sbin/sendmail/makemap/makemap.8 @@ -0,0 +1,134 @@ +.\" Copyright (c) 1988, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)makemap.8 8.3 (Berkeley) 7/24/94 +.\" +.Dd November 16, 1992 +.Dt MAKEMAP 8 +.Os BSD 4.4 +.Sh NAME +.Nm makemap +.Nd create database maps for sendmail +.Sh SYNOPSIS +.Nm +.Op Fl N +.Op Fl d +.Op Fl f +.Op Fl o +.Op Fl r +.Op Fl v +.Ar maptype +.Ar mapname +.Sh DESCRIPTION +.Nm +creates the database maps used by the keyed map lookups in +.Xr sendmail 8 . +It reads input from the standard input +and outputs them to the indicated +.Ar mapname . +.Pp +Depending on how it is compiled, +.Nm +handles up to three different database formats, +selected using the +.Ar maptype +parameter. +They may be +.Bl -tag -width Fl +.It Li dbm +DBM format maps. +This requires the +.Xr ndbm 3 +library. +.It Li btree +B-Tree format maps. +This requires the new Berkeley +.Xr db 3 +library. +.It Li hash +Hash format maps. +This also requires the +.Xr db 3 +library. +.El +.Pp +In all cases, +.Nm +reads lines from the standard input consisting of two +words separated by white space. +The first is the database key, +the second is the value. +The value may contain +``%\fIn\fP'' +strings to indicated parameter substitution. +Literal parentheses should be doubled +(``%%''). +Blank lines and lines beginning with ``#'' are ignored. +.Ss Flags +.Bl -tag -width Fl +.It Fl N +Include the null byte that terminates strings +in the map. +This must match the \-N flag in the sendmail.cf +``K'' line. +.It Fl d +Allow duplicate keys in the map. +This is only allowed on B-Tree format maps. +If two identical keys are read, +they will both be inserted into the map. +.It Fl f +Normally all upper case letters in the key +are folded to lower case. +This flag disables that behaviour. +This is intended to mesh with the +\-f flag in the +\fBK\fP +line in sendmail.cf. +The value is never case folded. +.It Fl o +Append to an old file. +This allows you to augment an existing file. +.It Fl r +Allow replacement of existing keys. +Normally +.Nm +complains if you repeat a key, +and does not do the insert. +.It Fl v +Verbosely print what it is doing. +.El +.Sh SEE ALSO +.Xr sendmail 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.4 . diff --git a/usr.sbin/sendmail/makemap/makemap.c b/usr.sbin/sendmail/makemap/makemap.c new file mode 100644 index 000000000000..371b229a2175 --- /dev/null +++ b/usr.sbin/sendmail/makemap/makemap.c @@ -0,0 +1,496 @@ +/* + * Copyright (c) 1992 Eric P. Allman. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)makemap.c 8.14 (Berkeley) 11/5/95"; +#endif /* not lint */ + +#include <stdio.h> +#include <sysexits.h> +#include <sys/types.h> +#include <ctype.h> +#include <string.h> +#include <sys/errno.h> +#ifndef ISC_UNIX +# include <sys/file.h> +#endif +#include "useful.h" +#include "conf.h" + +#ifdef NDBM +#include <ndbm.h> +#endif + +#ifdef NEWDB +#include <db.h> +#endif + +enum type { T_DBM, T_BTREE, T_HASH, T_ERR, T_UNKNOWN }; + +union dbent +{ +#ifdef NDBM + datum dbm; +#endif +#ifdef NEWDB + DBT db; +#endif + struct + { + char *data; + size_t size; + } xx; +}; + +#define BUFSIZE 1024 + +main(argc, argv) + int argc; + char **argv; +{ + char *progname; + bool inclnull = FALSE; + bool notrunc = FALSE; + bool allowreplace = FALSE; + bool allowdups = FALSE; + bool verbose = FALSE; + bool foldcase = TRUE; + int exitstat; + int opt; + char *typename; + char *mapname; + char *ext; + char *lext; + int lineno; + int st; + int mode; + enum type type; + int fd; + union + { +#ifdef NDBM + DBM *dbm; +#endif +#ifdef NEWDB + DB *db; +#endif + void *dbx; + } dbp; + union dbent key, val; +#ifdef NEWDB + BTREEINFO bti; +#endif + char ibuf[BUFSIZE]; + char fbuf[MAXNAME]; + char lbuf[MAXNAME]; + extern char *optarg; + extern int optind; + extern bool lockfile(); + + progname = argv[0]; + + while ((opt = getopt(argc, argv, "Ndforv")) != EOF) + { + switch (opt) + { + case 'N': + inclnull = TRUE; + break; + + case 'd': + allowdups = TRUE; + break; + + case 'f': + foldcase = FALSE; + break; + + case 'o': + notrunc = TRUE; + break; + + case 'r': + allowreplace = TRUE; + break; + + case 'v': + verbose = TRUE; + break; + + default: + type = T_ERR; + break; + } + } + + argc -= optind; + argv += optind; + if (argc != 2) + type = T_ERR; + else + { + typename = argv[0]; + mapname = argv[1]; + ext = NULL; + lext = NULL; + + if (strcmp(typename, "dbm") == 0) + { + type = T_DBM; + lext = ".dir"; + } + else if (strcmp(typename, "btree") == 0) + { + type = T_BTREE; + ext = ".db"; + } + else if (strcmp(typename, "hash") == 0) + { + type = T_HASH; + ext = ".db"; + } + else + type = T_UNKNOWN; + } + + switch (type) + { + case T_ERR: + fprintf(stderr, "Usage: %s [-N] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname); + exit(EX_USAGE); + + case T_UNKNOWN: + fprintf(stderr, "%s: Unknown database type %s\n", + progname, typename); + exit(EX_USAGE); + +#ifndef NDBM + case T_DBM: +#endif +#ifndef NEWDB + case T_BTREE: + case T_HASH: +#endif + fprintf(stderr, "%s: Type %s not supported in this version\n", + progname, typename); + exit(EX_UNAVAILABLE); + +#ifdef NEWDB + case T_BTREE: + bzero(&bti, sizeof bti); + if (allowdups) + bti.flags |= R_DUP; + break; + + case T_HASH: +#endif +#ifdef NDBM + case T_DBM: +#endif + if (allowdups) + { + fprintf(stderr, "%s: Type %s does not support -d (allow dups)\n", + progname, typename); + exit(EX_UNAVAILABLE); + } + break; + } + + /* + ** Adjust file names. + */ + + if (ext != NULL) + { + int el, fl; + + el = strlen(ext); + fl = strlen(mapname); + if (fl < el || strcmp(&mapname[fl - el], ext) != 0) + { + strcpy(fbuf, mapname); + strcat(fbuf, ext); + mapname = fbuf; + } + } + + strcpy(lbuf, mapname); + if (lext != NULL) + strcat(lbuf, lext); + + /* + ** Create the database. + */ + + mode = O_RDWR; + if (!notrunc) + mode |= O_CREAT|O_TRUNC; +#ifdef O_EXLOCK + mode |= O_EXLOCK; +#else + /* pre-lock the database */ + fd = open(lbuf, mode & ~O_TRUNC, 0644); + if (fd < 0) + { + fprintf(stderr, "%s: cannot create type %s map %s\n", + progname, typename, mapname); + exit(EX_CANTCREAT); + } + (void) lockfile(fd); +#endif + switch (type) + { +#ifdef NDBM + case T_DBM: + dbp.dbm = dbm_open(mapname, mode, 0644); + break; +#endif + +#ifdef NEWDB + case T_HASH: + dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL); + if (dbp.db != NULL) + { +# if OLD_NEWDB + (void) (*dbp.db->sync)(dbp.db); +# else + (void) (*dbp.db->sync)(dbp.db, 0); +# endif + } + break; + + case T_BTREE: + dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, &bti); + if (dbp.db != NULL) + { +# if OLD_NEWDB + (void) (*dbp.db->sync)(dbp.db); +# else + (void) (*dbp.db->sync)(dbp.db, 0); +# endif + } + break; +#endif + + default: + fprintf(stderr, "%s: internal error: type %d\n", progname, type); + exit(EX_SOFTWARE); + } + + if (dbp.dbx == NULL) + { + fprintf(stderr, "%s: cannot open type %s map %s\n", + progname, typename, mapname); + exit(EX_CANTCREAT); + } + + /* + ** Copy the data + */ + + lineno = 0; + exitstat = EX_OK; + while (fgets(ibuf, sizeof ibuf, stdin) != NULL) + { + register char *p; + + lineno++; + + /* + ** Parse the line. + */ + + p = strchr(ibuf, '\n'); + if (p != NULL) + *p = '\0'; + else if (!feof(stdin)) + { + fprintf(stderr, "%s: %s: line %d: line too long (%d bytes max)\n", + progname, mapname, lineno, sizeof ibuf); + continue; + } + + if (ibuf[0] == '\0' || ibuf[0] == '#') + continue; + if (isspace(ibuf[0])) + { + fprintf(stderr, "%s: %s: line %d: syntax error (leading space)\n", + progname, mapname, lineno); + continue; + } + key.xx.data = ibuf; + for (p = ibuf; *p != '\0' && !isspace(*p); p++) + { + if (foldcase && isupper(*p)) + *p = tolower(*p); + } + key.xx.size = p - key.xx.data; + if (inclnull) + key.xx.size++; + if (*p != '\0') + *p++ = '\0'; + while (isspace(*p)) + p++; + if (*p == '\0') + { + fprintf(stderr, "%s: %s: line %d: no RHS for LHS %s\n", + progname, mapname, lineno, key.xx.data); + continue; + } + val.xx.data = p; + val.xx.size = strlen(p); + if (inclnull) + val.xx.size++; + + /* + ** Do the database insert. + */ + + if (verbose) + { + printf("key=`%s', val=`%s'\n", key.xx.data, val.xx.data); + } + + switch (type) + { +#ifdef NDBM + case T_DBM: + st = dbm_store(dbp.dbm, key.dbm, val.dbm, + allowreplace ? DBM_REPLACE : DBM_INSERT); + break; +#endif + +#ifdef NEWDB + case T_BTREE: + case T_HASH: + st = (*dbp.db->put)(dbp.db, &key.db, &val.db, + allowreplace ? 0 : R_NOOVERWRITE); + break; +#endif + } + + if (st < 0) + { + fprintf(stderr, "%s: %s: line %d: key %s: put error\n", + progname, mapname, lineno, key.xx.data); + perror(mapname); + exitstat = EX_IOERR; + } + else if (st > 0) + { + fprintf(stderr, "%s: %s: line %d: key %s: duplicate key\n", + progname, mapname, lineno, key.xx.data); + } + } + + /* + ** Now close the database. + */ + + switch (type) + { +#ifdef NDBM + case T_DBM: + dbm_close(dbp.dbm); + break; +#endif + +#ifdef NEWDB + case T_HASH: + case T_BTREE: + if ((*dbp.db->close)(dbp.db) < 0) + { + fprintf(stderr, "%s: %s: error on close\n", + progname, mapname); + perror(mapname); + exitstat = EX_IOERR; + } +#endif + } + +#ifndef O_EXLOCK + /* release locks */ + close(fd); +#endif + + exit (exitstat); +} +/* +** LOCKFILE -- lock a file using flock or (shudder) fcntl locking +** +** Parameters: +** fd -- the file descriptor of the file. +** +** Returns: +** TRUE if the lock was acquired. +** FALSE otherwise. +*/ + +bool +lockfile(fd) + int fd; +{ +# if !HASFLOCK + int action; + struct flock lfd; + extern int errno; + + bzero(&lfd, sizeof lfd); + lfd.l_type = F_WRLCK; + action = F_SETLKW; + + if (fcntl(fd, action, &lfd) >= 0) + return TRUE; + + /* + ** On SunOS, if you are testing using -oQ/tmp/mqueue or + ** -oA/tmp/aliases or anything like that, and /tmp is mounted + ** as type "tmp" (that is, served from swap space), the + ** previous fcntl will fail with "Invalid argument" errors. + ** Since this is fairly common during testing, we will assume + ** that this indicates that the lock is successfully grabbed. + */ + + if (errno == EINVAL) + return TRUE; + +# else /* HASFLOCK */ + + if (flock(fd, LOCK_EX) >= 0) + return TRUE; + +# endif + + return FALSE; +} diff --git a/usr.sbin/sendmail/rmail/Makefile b/usr.sbin/sendmail/rmail/Makefile new file mode 100644 index 000000000000..eb2fb4800850 --- /dev/null +++ b/usr.sbin/sendmail/rmail/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 + +PROG= rmail +MAN8= rmail.0 + +.include <bsd.prog.mk> diff --git a/usr.sbin/sendmail/rmail/rmail.8 b/usr.sbin/sendmail/rmail/rmail.8 new file mode 100644 index 000000000000..2079d4e9f8a7 --- /dev/null +++ b/usr.sbin/sendmail/rmail/rmail.8 @@ -0,0 +1,71 @@ +.\" Copyright (c) 1983, 1990 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)rmail.8 6.10 (Berkeley) 4/29/93 +.\" +.Dd April 29, 1993 +.Dt RMAIL 8 +.Os BSD 4.2 +.Sh NAME +.Nm rmail +.Nd handle remote mail received via uucp +.Sh SYNOPSIS +.Nm rmail +.Ar user ... +.Sh DESCRIPTION +.Nm Rmail +interprets incoming mail received via +.Xr uucp 1 , +collapsing ``From'' lines in the form generated +by +.Xr mail.local 8 +into a single line of the form ``return-path!sender'', +and passing the processed mail on to +.Xr sendmail 8 . +.Pp +.Nm Rmail +is explicitly designed for use with +.Xr uucp +and +.Xr sendmail . +.Sh SEE ALSO +.Xr uucp 1 , +.Xr mail.local 8 , +.Xr sendmail 8 +.Sh HISTORY +The +.Nm rmail +program appeared in +.Bx 4.2 . +.Sh BUGS +.Nm Rmail +should not reside in +.Pa /bin . diff --git a/usr.sbin/sendmail/rmail/rmail.c b/usr.sbin/sendmail/rmail/rmail.c new file mode 100644 index 000000000000..29af02a90f6d --- /dev/null +++ b/usr.sbin/sendmail/rmail/rmail.c @@ -0,0 +1,373 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)rmail.c 8.3 (Berkeley) 5/15/95"; +#endif /* not lint */ + +/* + * RMAIL -- UUCP mail server. + * + * This program reads the >From ... remote from ... lines that UUCP is so + * fond of and turns them into something reasonable. It then execs sendmail + * with various options built from these lines. + * + * The expected syntax is: + * + * <user> := [-a-z0-9]+ + * <date> := ctime format + * <site> := [-a-z0-9!]+ + * <blank line> := "^\n$" + * <from> := "From" <space> <user> <space> <date> + * [<space> "remote from" <space> <site>] + * <forward> := ">" <from> + * msg := <from> <forward>* <blank-line> <body> + * + * The output of rmail(8) compresses the <forward> lines into a single + * from path. + * + * The err(3) routine is included here deliberately to make this code + * a bit more portable. + */ +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include <ctype.h> +#include <fcntl.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> + +#ifndef MAX +# define MAX(a, b) ((a) < (b) ? (b) : (a)) +#endif + +void err __P((int, const char *, ...)); +void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int errno, optind; + FILE *fp; + struct stat sb; + size_t fplen, fptlen, len; + off_t offset; + int ch, debug, i, pdes[2], pid, status; + char *addrp, *domain, *p, *t; + char *from_path, *from_sys, *from_user; + char *args[100], buf[2048], lbuf[2048]; + + debug = 0; + domain = "UUCP"; /* Default "domain". */ + while ((ch = getopt(argc, argv, "D:T")) != EOF) + switch (ch) { + case 'T': + debug = 1; + break; + case 'D': + domain = optarg; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc < 1) + usage(); + + from_path = from_sys = from_user = NULL; + for (offset = 0;;) { + + /* Get and nul-terminate the line. */ + if (fgets(lbuf, sizeof(lbuf), stdin) == NULL) + exit (EX_DATAERR); + if ((p = strchr(lbuf, '\n')) == NULL) + err(EX_DATAERR, "line too long"); + *p = '\0'; + + /* Parse lines until reach a non-"From" line. */ + if (!strncmp(lbuf, "From ", 5)) + addrp = lbuf + 5; + else if (!strncmp(lbuf, ">From ", 6)) + addrp = lbuf + 6; + else if (offset == 0) + err(EX_DATAERR, + "missing or empty From line: %s", lbuf); + else { + *p = '\n'; + break; + } + + if (*addrp == '\0') + err(EX_DATAERR, "corrupted From line: %s", lbuf); + + /* Use the "remote from" if it exists. */ + for (p = addrp; (p = strchr(p + 1, 'r')) != NULL;) + if (!strncmp(p, "remote from ", 12)) { + for (t = p += 12; *t && !isspace(*t); ++t); + *t = '\0'; + if (debug) + (void)fprintf(stderr, + "remote from: %s\n", p); + break; + } + + /* Else use the string up to the last bang. */ + if (p == NULL) + if (*addrp == '!') + err(EX_DATAERR, + "bang starts address: %s", addrp); + else if ((t = strrchr(addrp, '!')) != NULL) { + *t = '\0'; + p = addrp; + addrp = t + 1; + if (*addrp == '\0') + err(EX_DATAERR, + "corrupted From line: %s", lbuf); + if (debug) + (void)fprintf(stderr, "bang: %s\n", p); + } + + /* 'p' now points to any system string from this line. */ + if (p != NULL) { + /* Nul terminate it as necessary. */ + for (t = p; *t && !isspace(*t); ++t); + *t = '\0'; + + /* If the first system, copy to the from_sys string. */ + if (from_sys == NULL) { + if ((from_sys = strdup(p)) == NULL) + err(EX_TEMPFAIL, NULL); + if (debug) + (void)fprintf(stderr, + "from_sys: %s\n", from_sys); + } + + /* Concatenate to the path string. */ + len = t - p; + if (from_path == NULL) { + fplen = 0; + if ((from_path = malloc(fptlen = 256)) == NULL) + err(EX_TEMPFAIL, NULL); + } + if (fplen + len + 2 > fptlen) { + fptlen += MAX(fplen + len + 2, 256); + if ((from_path = + realloc(from_path, fptlen)) == NULL) + err(EX_TEMPFAIL, NULL); + } + memmove(from_path + fplen, p, len); + fplen += len; + from_path[fplen++] = '!'; + from_path[fplen] = '\0'; + } + + /* Save off from user's address; the last one wins. */ + for (p = addrp; *p && !isspace(*p); ++p); + *p = '\0'; + if (*addrp == '\0') + addrp = "<>"; + if (from_user != NULL) + free(from_user); + if ((from_user = strdup(addrp)) == NULL) + err(EX_TEMPFAIL, NULL); + + if (debug) { + if (from_path != NULL) + (void)fprintf(stderr, + "from_path: %s\n", from_path); + (void)fprintf(stderr, "from_user: %s\n", from_user); + } + + if (offset != -1) + offset = (off_t)ftell(stdin); + } + + i = 0; + args[i++] = _PATH_SENDMAIL; /* Build sendmail's argument list. */ + args[i++] = "-oee"; /* No errors, just status. */ + args[i++] = "-odq"; /* Queue it, don't try to deliver. */ + args[i++] = "-oi"; /* Ignore '.' on a line by itself. */ + + /* set from system and protocol used */ + if (from_sys == NULL) + (void)snprintf(buf, sizeof(buf), "-p%s", domain); + else if (strchr(from_sys, '.') == NULL) + (void)snprintf(buf, sizeof(buf), "-p%s:%s.%s", + domain, from_sys, domain); + else + (void)snprintf(buf, sizeof(buf), "-p%s:%s", domain, from_sys); + if ((args[i++] = strdup(buf)) == NULL) + err(EX_TEMPFAIL, NULL); + + /* Set name of ``from'' person. */ + (void)snprintf(buf, sizeof(buf), "-f%s%s", + from_path ? from_path : "", from_user); + if ((args[i++] = strdup(buf)) == NULL) + err(EX_TEMPFAIL, NULL); + + /* + * Don't copy arguments beginning with - as they will be + * passed to sendmail and could be interpreted as flags. + * To prevent confusion of sendmail wrap < and > around + * the address (helps to pass addrs like @gw1,@gw2:aa@bb) + */ + while (*argv) { + if (**argv == '-') + err(EX_USAGE, "dash precedes argument: %s", *argv); + if (strchr(*argv, ',') == NULL || strchr(*argv, '<') != NULL) + args[i++] = *argv; + else { + if ((args[i] = malloc(strlen(*argv) + 3)) == NULL) + err(EX_TEMPFAIL, "Cannot malloc"); + sprintf (args [i++], "<%s>", *argv); + } + argv++; + } + args[i] = 0; + + if (debug) { + (void)fprintf(stderr, "Sendmail arguments:\n"); + for (i = 0; args[i]; i++) + (void)fprintf(stderr, "\t%s\n", args[i]); + } + + /* + * If called with a regular file as standard input, seek to the right + * position in the file and just exec sendmail. Could probably skip + * skip the stat, but it's not unreasonable to believe that a failed + * seek will cause future reads to fail. + */ + if (!fstat(STDIN_FILENO, &sb) && S_ISREG(sb.st_mode)) { + if (lseek(STDIN_FILENO, offset, SEEK_SET) != offset) + err(EX_TEMPFAIL, "stdin seek"); + execv(_PATH_SENDMAIL, args); + err(EX_OSERR, "%s", _PATH_SENDMAIL); + } + + if (pipe(pdes) < 0) + err(EX_OSERR, NULL); + + switch (pid = vfork()) { + case -1: /* Err. */ + err(EX_OSERR, NULL); + case 0: /* Child. */ + if (pdes[0] != STDIN_FILENO) { + (void)dup2(pdes[0], STDIN_FILENO); + (void)close(pdes[0]); + } + (void)close(pdes[1]); + execv(_PATH_SENDMAIL, args); + _exit(127); + /* NOTREACHED */ + } + + if ((fp = fdopen(pdes[1], "w")) == NULL) + err(EX_OSERR, NULL); + (void)close(pdes[0]); + + /* Copy the file down the pipe. */ + do { + (void)fprintf(fp, "%s", lbuf); + } while (fgets(lbuf, sizeof(lbuf), stdin) != NULL); + + if (ferror(stdin)) + err(EX_TEMPFAIL, "stdin: %s", strerror(errno)); + + if (fclose(fp)) + err(EX_OSERR, NULL); + + if ((waitpid(pid, &status, 0)) == -1) + err(EX_OSERR, "%s", _PATH_SENDMAIL); + + if (!WIFEXITED(status)) + err(EX_OSERR, + "%s: did not terminate normally", _PATH_SENDMAIL); + + if (WEXITSTATUS(status)) + err(status, "%s: terminated with %d (non-zero) status", + _PATH_SENDMAIL, WEXITSTATUS(status)); + exit(EX_OK); +} + +void +usage() +{ + (void)fprintf(stderr, "usage: rmail [-T] [-D domain] user ...\n"); + exit(EX_USAGE); +} + +#ifdef __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +void +#ifdef __STDC__ +err(int eval, const char *fmt, ...) +#else +err(eval, fmt, va_alist) + int eval; + const char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "rmail: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + exit(eval); +} diff --git a/usr.sbin/sendmail/smrsh/Makefile b/usr.sbin/sendmail/smrsh/Makefile new file mode 100644 index 000000000000..f2629a8c1926 --- /dev/null +++ b/usr.sbin/sendmail/smrsh/Makefile @@ -0,0 +1,8 @@ +# @(#)Makefile 8.1 (Berkeley) 7/2/95 + +PROG= smrsh +MAN8= smrsh.0 +CFLAGS+=-I${.CURDIR}/../src -DNDBM -DNEWDB + +.include "../../Makefile.inc" +.include <bsd.prog.mk> diff --git a/usr.sbin/sendmail/smrsh/README b/usr.sbin/sendmail/smrsh/README new file mode 100644 index 000000000000..13f545c7e666 --- /dev/null +++ b/usr.sbin/sendmail/smrsh/README @@ -0,0 +1,144 @@ + + + +README smrsh - sendmail restricted shell. + + @(#)README 8.2 11/11/95 + + +This README file is provided as a courtesy of the CERT Coordination Center, +Software Engineering Institute, Carnegie Mellon University. This file is +intended as a supplement to the CERT advisory CA-93:16.sendmail.vulnerability, +and to the software, smrsh.c, written by Eric Allman. + + + +The smrsh(8) program is intended as a replacement for /bin/sh in the +program mailer definition of sendmail(8). This README file describes +the steps needed to compile and install smrsh. + +smrsh is a restricted shell utility that provides the ability to +specify, through a configuration, an explicit list of executable +programs. When used in conjunction with sendmail, smrsh effectively +limits sendmail's scope of program execution to only those programs +specified in smrsh's configuration. + +smrsh has been written with portability in mind, and uses traditional +Unix library utilities. As such, smrsh should compile on most +Unix C compilers. + + + +To compile smrsh.c, use the following command: + +host.domain% cc -o smrsh smrsh.c + +For machines that provide dynamic linking, it is advisable to compile +smrsh without dynamic linking. As an example with the Sun Microsystems +compiler, you should compile with the -Bstatic option. + +host.domain% cc -Bstatic -o smrsh smrsh.c + + +Choose a directory that smrsh will reside in. We will use the traditional +/usr/local/etc directory for the remainder of this document. + +As root, install smrsh in /usr/local/etc directory, with mode 511. + +host.domain# mv smrsh /usr/local/etc +host.domain# chmod 511 /usr/local/etc/smrsh + + + +Next, determine the list of commands that smrsh should allow sendmail +to run. This list of allowable commands can be determined by: + + 1. examining your /etc/aliases file, to indicate what commands + are being used by the system. + + 2. surveying your host's .forward files, to determine what + commands users have specified. + +See the man page for aliases(5) if you are unfamiliar with the format of +these specifications. Additionally, you should include in the list, +popular commands such as /usr/ucb/vacation. + +You should NOT include interpreter programs such as sh(1), csh(1), +perl(1), uudecode(1) or the stream editor sed(1) in your list of +acceptable commands. + + +You will next need to create the directory /usr/adm/sm.bin and populate +it with the programs that your site feels are allowable for sendmail +to execute. This directory is explicitly specified in the source +code for smrsh, so changing this directory must be accompanied with +a change in smrsh.c. + + +You will have to be root to make these modifications. + +After creating the /usr/adm/sm.bin directory, either copy the programs +to the directory, or establish links to the allowable programs from +/usr/adm/sm.bin. Change the file permissions, so that these programs +can not be modified by non-root users. If you use links, you should +ensure that the target programs are not modifiable. + +To allow the popular vacation(1) program by creating a link in the +/usr/adm/sm.bin directory, you should: + +host.domain# cd /usr/adm/sm.bin +host.domain# ln -s /usr/ucb/vacation vacation + + + + +After populating the /usr/adm/sm.bin directory, you can now configure +sendmail to use the restricted shell. Save the current sendmail.cf +file prior to modifying it, as a prudent precaution. + +Typically, the program mailer is defined by a single line in the +sendmail configuration file, sendmail.cf. This file is traditionally +found in the /etc, /usr/lib or /etc/mail directories, depending on +the UNIX vendor. + +If you are unsure of the location of the actual sendmail configuration +file, a search of the strings(1) output of the sendmail binary, will +help to locate it. + +In order to configure sendmail to use smrsh, you must modify the Mprog +definition in the sendmail.cf file, by replacing the /bin/sh specification +with /usr/local/etc/smrsh. + +As an example: + +In most Sun Microsystems' sendmail.cf files, the line is: +Mprog, P=/bin/sh, F=lsDFMeuP, S=10, R=20, A=sh -c $u + +which should be changed to: +Mprog, P=/usr/local/etc/smrsh, F=lsDFMeuP, S=10, R=20, A=sh -c $u + ^^^^^^^^^^^^^^^^^^^^ + +A more generic line may be: +Mprog, P=/bin/sh, F=lsDFM, A=sh -c $u + +and should be changed to; +Mprog, P=/usr/local/etc/smrsh, F=lsDFM, A=sh -c $u + + +After modifying the Mprog definition in the sendmail.cf file, if a frozen +configuration file is being used, it is essential to create a new one. +You can determine if you need a frozen configuration by discovering +if a sendmail.fc file currently exists in either the /etc/, /usr/lib, +or /etc/mail directories. The specific location can be determined using +a search of the strings(1) output of the sendmail binary. + +In order to create a new frozen configuration, if it is required: +host.domain# /usr/lib/sendmail -bz + +Now re-start the sendmail process. An example of how to do this on +a typical system follows: + +host.domain# /usr/bin/ps aux | /usr/bin/grep sendmail +root 130 0.0 0.0 168 0 ? IW Oct 2 0:10 /usr/lib/sendmail -bd -q +host.domain# /bin/kill -9 130 +host.domain# /usr/lib/sendmail -bd -q30m diff --git a/usr.sbin/sendmail/smrsh/smrsh.8 b/usr.sbin/sendmail/smrsh/smrsh.8 new file mode 100644 index 000000000000..3e547fcc892c --- /dev/null +++ b/usr.sbin/sendmail/smrsh/smrsh.8 @@ -0,0 +1,105 @@ +.\" Copyright (c) 1993 Eric P. Allman +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)smrsh.8 8.1 (Berkeley) 11/13/94 +.\" +.TH SMRSH 8 11/02/93 +.SH NAME +smrsh \- restricted shell for sendmail +.SH SYNOPSIS +.B smrsh +.B \-c +command +.SH DESCRIPTION +The +.I smrsh +program is intended as a replacement for +.I sh +for use in the ``prog'' mailer in +.IR sendmail (8) +configuration files. +It sharply limits the commands that can be run using the +``|program'' syntax of +.I sendmail +in order to improve the over all security of your system. +Briefly, even if a ``bad guy'' can get sendmail to run a program +without going through an alias or forward file, +.I smrsh +limits the set of programs that he or she can execute. +.PP +Briefly, +.I smrsh +limits programs to be in the directory +/usr/adm/sm.bin, +allowing the system administrator to choose the set of acceptable commands. +It also rejects any commands with the characters +`\`', `<', `>', `|', `;', `&', `$', `(', `)', `\r' (carriage return), +or `\n' (newline) +on the command line to prevent ``end run'' attacks. +.PP +Initial pathnames on programs are stripped, +so forwarding to ``/usr/ucb/vacation'', +``/usr/bin/vacation'', +``/home/server/mydir/bin/vacation'', +and +``vacation'' +all actually forward to +``/usr/adm/sm.bin/vacation''. +.PP +System administrators should be conservative about populating +/usr/adm/sm.bin. +Reasonable additions are +.IR vacation (1), +.IR procmail (1), +and the like. +No matter how brow-beaten you may be, +never include any shell or shell-like program +(such as +.IR perl (1)) +in the +sm.bin +directory. +Note that this does not restrict the use of shell or perl scripts +in the sm.bin directory (using the ``#!'' syntax); +it simply disallows execution of arbitrary programs. +.SH COMPILATION +Compilation should be trivial on most systems. +You may need to use \-DPATH=\e"\fIpath\fP\e" +to adjust the default search path +(defaults to ``/bin:/usr/bin:/usr/ucb'') +and/or \-DCMDBIN=\e"\fIdir\fP\e" +to change the default program directory +(defaults to ``/usr/adm/sm.bin''). +.SH FILES +/usr/adm/sm.bin \- directory for restricted programs +.SH SEE ALSO +sendmail(8) diff --git a/usr.sbin/sendmail/smrsh/smrsh.c b/usr.sbin/sendmail/smrsh/smrsh.c new file mode 100644 index 000000000000..662ec828302b --- /dev/null +++ b/usr.sbin/sendmail/smrsh/smrsh.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 1993 Eric P. Allman + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)smrsh.c 8.4 (Berkeley) 11/11/95"; +#endif /* not lint */ + +/* +** SMRSH -- sendmail restricted shell +** +** This is a patch to get around the prog mailer bugs in most +** versions of sendmail. +** +** Use this in place of /bin/sh in the "prog" mailer definition +** in your sendmail.cf file. You then create CMDDIR (owned by +** root, mode 755) and put links to any programs you want +** available to prog mailers in that directory. This should +** include things like "vacation" and "procmail", but not "sed" +** or "sh". +** +** Leading pathnames are stripped from program names so that +** existing .forward files that reference things like +** "/usr/ucb/vacation" will continue to work. +** +** The following characters are completely illegal: +** < > | ^ ; & $ ` ( ) \n \r +** This is more restrictive than strictly necessary. +** +** To use this, edit /etc/sendmail.cf, search for ^Mprog, and +** change P=/bin/sh to P=/usr/local/etc/smrsh, where this compiled +** binary is installed /usr/local/etc/smrsh. +** +** This can be used on any version of sendmail. +** +** In loving memory of RTM. 11/02/93. +*/ + +#include <unistd.h> +#include <stdio.h> +#include <sys/file.h> +#include <string.h> +#include <ctype.h> +#ifdef EX_OK +# undef EX_OK +#endif +#include <sysexits.h> +#include <syslog.h> + +/* directory in which all commands must reside */ +#ifndef CMDDIR +# define CMDDIR "/usr/adm/sm.bin" +#endif + +/* characters disallowed in the shell "-c" argument */ +#define SPECIALS "<|>^();&`$\r\n" + +/* default search path */ +#ifndef PATH +# define PATH "/bin:/usr/bin:/usr/ucb" +#endif + +main(argc, argv) + int argc; + char **argv; +{ + register char *p; + register char *q; + register char *cmd; + int i; + char *newenv[2]; + char cmdbuf[1000]; + char pathbuf[1000]; + +#ifndef LOG_MAIL + openlog("smrsh", 0); +#else + openlog("smrsh", LOG_ODELAY|LOG_CONS, LOG_MAIL); +#endif + + strcpy(pathbuf, "PATH="); + strcat(pathbuf, PATH); + newenv[0] = pathbuf; + newenv[1] = NULL; + + /* + ** Do basic argv usage checking + */ + + if (argc != 3 || strcmp(argv[1], "-c") != 0) + { + fprintf(stderr, "Usage: %s -c command\n", argv[0]); + syslog(LOG_ERR, "usage"); + exit(EX_USAGE); + } + + /* + ** Disallow special shell syntax. This is overly restrictive, + ** but it should shut down all attacks. + ** Be sure to include 8-bit versions, since many shells strip + ** the address to 7 bits before checking. + */ + + strcpy(cmdbuf, SPECIALS); + for (p = cmdbuf; *p != '\0'; p++) + *p |= '\200'; + strcat(cmdbuf, SPECIALS); + p = strpbrk(argv[2], cmdbuf); + if (p != NULL) + { + fprintf(stderr, "%s: cannot use %c in command\n", + argv[0], *p); + syslog(LOG_CRIT, "uid %d: attempt to use %c in command: %s", + getuid(), *p, argv[2]); + exit(EX_UNAVAILABLE); + } + + /* + ** Do a quick sanity check on command line length. + */ + + i = strlen(argv[2]); + if (i > (sizeof cmdbuf - sizeof CMDDIR - 2)) + { + fprintf(stderr, "%s: command too long: %s\n", argv[0], argv[2]); + syslog(LOG_WARNING, "command too long: %.40s", argv[2]); + exit(EX_UNAVAILABLE); + } + + /* + ** Strip off a leading pathname on the command name. For + ** example, change /usr/ucb/vacation to vacation. + */ + + /* strip leading spaces */ + for (q = argv[2]; *q != '\0' && isascii(*q) && isspace(*q); ) + q++; + + /* find the end of the command name */ + p = strpbrk(q, " \t"); + if (p == NULL) + cmd = &q[strlen(q)]; + else + { + *p = '\0'; + cmd = p; + } + + /* search backwards for last / (allow for 0200 bit) */ + while (cmd > q) + { + if ((*--cmd & 0177) == '/') + { + cmd++; + break; + } + } + + /* cmd now points at final component of path name */ + + /* + ** Check to see if the command name is legal. + */ + + (void) strcpy(cmdbuf, CMDDIR); + (void) strcat(cmdbuf, "/"); + (void) strcat(cmdbuf, cmd); +#ifdef DEBUG + printf("Trying %s\n", cmdbuf); +#endif + if (access(cmdbuf, X_OK) < 0) + { + /* oops.... crack attack possiblity */ + fprintf(stderr, "%s: %s not available for sendmail programs\n", + argv[0], cmd); + if (p != NULL) + *p = ' '; + syslog(LOG_CRIT, "uid %d: attempt to use %s", getuid(), cmd); + exit(EX_UNAVAILABLE); + } + if (p != NULL) + *p = ' '; + + /* + ** Create the actual shell input. + */ + + strcpy(cmdbuf, CMDDIR); + strcat(cmdbuf, "/"); + strcat(cmdbuf, cmd); + + /* + ** Now invoke the shell + */ + +#ifdef DEBUG + printf("%s\n", cmdbuf); +#endif + execle("/bin/sh", "/bin/sh", "-c", cmdbuf, NULL, newenv); + syslog(LOG_CRIT, "Cannot exec /bin/sh: %m"); + perror("/bin/sh"); + exit(EX_OSFILE); +} diff --git a/usr.sbin/sendmail/src/Makefile b/usr.sbin/sendmail/src/Makefile new file mode 100644 index 000000000000..57a7df0b3911 --- /dev/null +++ b/usr.sbin/sendmail/src/Makefile @@ -0,0 +1,47 @@ +# @(#)Makefile 8.7 (Berkeley) 10/31/95 + +######################################################################### +# This Makefile is for 4.4BSD only!!! For all other systems, use # +# the "makesendmail" script. # +######################################################################### + +PROG= sendmail + +# define the database format to use for aliases et al. Can be -DNEWDB (for +# the new BSD database package -- this is preferred) or -DNDBM for the NDBM +# database package. The old putrescent V7 DBM package is no longer +# supported. +# You can define both NEWDB and NDBM during a transition period; old +# databases are read, but the new format will be used on any rebuilds. On +# really gnarly systems, you can set this to null; it will crawl like a high +# spiral snail, but it will work. +DBMDEF= -DNEWDB + +CFLAGS+=-I${.CURDIR} ${DBMDEF} -DNETISO + +SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \ + deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \ + mci.c mime.c parseaddr.c queue.c readcf.c recipient.c savemail.c \ + srvrsmtp.c stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \ + util.c version.c +DPADD= +LDADD= +MAN1= mailq.0 newaliases.0 +MAN5= aliases.0 +MAN8= sendmail.0 +LINKS= /usr/sbin/sendmail /usr/bin/newaliases \ + /usr/sbin/sendmail /usr/bin/mailq +BINDIR= /usr/sbin +BINOWN= root +BINGRP= kmem +BINMODE=6555 + +beforeinstall: +# install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ +# ${DESTDIR}/etc/sendmail.fc + install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ + ${DESTDIR}/var/log/sendmail.st + install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \ + ${DESTDIR}/usr/share/misc + +.include <bsd.prog.mk> diff --git a/usr.sbin/sendmail/src/READ_ME b/usr.sbin/sendmail/src/READ_ME new file mode 100644 index 000000000000..82889ff53389 --- /dev/null +++ b/usr.sbin/sendmail/src/READ_ME @@ -0,0 +1,1183 @@ +# Copyright (c) 1983, 1995 Eric P. Allman +# Copyright (c) 1988 The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# @(#)READ_ME 8.112 (Berkeley) 11/18/95 +# + +This directory contains the source files for sendmail. + +********************* +!! DO NOT USE MAKE !! to compile sendmail -- instead, use the +********************* "makesendmail" script located in the src +directory. It will find an appropriate Makefile, and create an +appropriate obj.* subdirectory so that multiplatform support +works easily. + +The Makefile is for the new (4.4BSD) Berkeley make and uses syntax +that is not recognized by older makes. It also has assumptions +about the 4.4 file system layout built in. See below for details +about other Makefiles. + +If you are porting to a new architecture for which there is no existing +Makefile, you might start with Makefile.dist. This works on the old +traditional make, but isn't customized for any particular architecture. + + ************************************************** + ** Read below for more details of Makefiles. ** + ************************************************** + +************************************************************************** +** IMPORTANT: DO NOT USE OPTIMIZATION (``-O'') IF YOU ARE RUNNING ** +** GCC 2.4.x or 2.5.x. THERE IS A BUG IN THE GCC OPTIMIZER THAT ** +** CAUSES SENDMAIL COMPILES TO FAIL MISERABLY. ** +************************************************************************** + +Jim Wilson of Cygnus believes he has found the problem -- it will +probably be fixed in GCC 2.5.6 -- but until this is verified, be +very suspicious of gcc -O. + +This problem is reported to have been fixed in gcc 2.6. + +************************************************************************** +** IMPORTANT: Read the appropriate paragraphs in the section on ** +** ``Operating System and Compile Quirks''. ** +************************************************************************** + +For detailed instructions, please read the document ../doc/op.me: + + eqn ../doc/op.me | pic | ditroff -me + + ++-----------+ +| MAKEFILES | ++-----------+ + +By far, the easiest way to compile sendmail is to use the "makesendmail" +script: + + sh makesendmail + +This uses the "uname" command to figure out what architecture you are +on and selects a proper Makefile accordingly. It also creates a +subdirectory per object format, so that multiarchitecture support is +easy. In general this should be all you need. However, if for some +reason this doesn't work (e.g., NeXT systems don't have the "uname" +command) you may have to set up your compile environment by hand. + +The "Makefile"s in these directories are from 4.4 BSD, and hence +really only work properly if you are on a 4.4 system. In particular, +they use new syntax that will not be recognized on old make programs, +and some of them do things like ``.include ../../Makefile.inc'' to +pick up some system defines. If you are getting sendmail separately, +these files won't be included in the distribution, as they are +outside of the sendmail tree. + +Instead, you should use one of the other Makefiles, such as +Makefile.SunOS for a SunOS system, and so forth. These should +work with the version of make that is appropriate for that +system. All other Makefiles are in the "src/Makefiles" subdirectory. +They use the version of make that is native for that system. These +are the Makefiles that I use, and they have "Berkeley quirks" in them. +I can't guarantee that they will work unmodified in your environment. +In particular, Many of them include -I/usr/sww/include/db and +-L/usr/sww/lib -- these are Berkeley's locations in the ``Software +Warehouse'' for the new database libraries, described below. You don't +have to remove these definitions if you don't have these directories, +but you may have to remove -DNEWDB from the DBMDEF definition. + +Please look for an appropriate Makefile before you start trying to +compile with Makefile or Makefile.dist. + +If you want to port the new Berkeley make, you can get it from +ftp.uu.net in the directory /systems/unix/bsd-sources/usr.bin/make. +Diffs and instructions for building this version of make under +SunOS 4.1.x are available on ftp.css.itd.umich.edu in +/pub/systems/sun/Net2-make-sun4.diff.Z. Diffs and instructions +for building this version of make under IBM AIX 3.2.4 are available +on ftp.uni-stuttgart.de in /sw/src/patches/bsd-make-rus-patches. +For Ultrix, try ftp.vix.com:~ftp/pub/patches/pmake-for-ultrix.Z. +Paul Southworth <pauls@umich.edu> published a description of porting +this make in comp.unix.bsd. + +The complete text of the Makefile.inc that is in the parent of the +sendmail directory is: + + # @(#)Makefile.inc 8.1 (Berkeley) 6/6/93 + + BINDIR?= /usr/sbin + + ++----------------------+ +| DATABASE DEFINITIONS | ++----------------------+ + +There are several database formats that can be used for the alias files +and for general maps. When used for alias files they interact in an +attempt to be back compatible. + +The three options are NEWDB (the new Berkeley DB package), NDBM (the +older DBM implementation -- the very old V7 implementation is no +longer supported), and NIS (Network Information Services). Used alone +these just include the support they indicate. [If you are using NEWDB, +get the latest version from FTP.CS.Berkeley.EDU in /ucb/4bsd/db.tar.Z +(or db.tar.gz). DO NOT use the version from the Net2 distribution! +However, if you are on BSD/386 or 386BSD-based systems, use the one +that already exists on your system. You may need to #define OLD_NEWDB +1 to do this.] + +[NOTE WELL: it is CRITICAL that you remove ndbm.o from libdb.a and +ndbm.h from the appropriate include directories if you want to get +ndbm support. These files OVERRIDE calls to ndbm routines -- in +particular, if you leave ndbm.h in, you can find yourself using +the new db package even if you don't define NEWDB.] + +If NEWDB and NDBM are defined (but not NIS), then sendmail will read +NDBM format alias files, but the next time a newaliases is run the +format will be converted to NEWDB; that format will be used forever +more. This is intended as a transition feature. [Note however that +the NEWDB library also catches and maps NDBM calls; you will have to +back out this feature to get this to work. See ``Quirks'' section +below for details.] + +If all three are defined and the name of the file includes the string +"/yp/", sendmail will rebuild BOTH the NEWDB and NDBM format alias +files. However, it will only read the NEWDB file; the NDBM format file +is used only by the NIS subsystem. + +If NDBM and NIS are defined (regardless of the definition of NEWDB), +and the filename includes the string "/yp/", sendmail adds the special +tokens "YP_LAST_MODIFIED" and "YP_MASTER_NAME", both of which are +required if the NDBM file is to be used as an NIS map. + +There is also preliminary support for NIS+ (-DNISPLUS), Hesiod +(-DHESIOD), and NetInfo (-DNETINFO). These have not been well +tested. + +All of -DNEWDB, -DNDBM, -DNIS, -DNISPLUS, -DHESIOD, and -DNETINFO are +normally defined in the DBMDEF line in the Makefile. + +If you define NEWDB or HESIOD you get the User Database (USERDB) +automatically. Generally you do want to have NEWDB for it to do +anything interesting. See above for getting the Berkeley "db" +package (i.e., NEWDB). There is no separate "user database" +package -- don't bother searching for it on the net. + + ++---------------+ +| COMPILE FLAGS | ++---------------+ + +Whereever possible, I try to make sendmail pull in the correct +compilation options needed to compile on various environments based on +automatically defined symbols. Some machines don't seem to have useful +symbols available, requiring that a compilation flag be defined in +the Makefile; see the Makefiles subdirectory for the supported +architectures. + +If you are a system to which sendmail has already been ported you +should not have to touch the following symbols. But if you are porting, +you may have to tweak the following compilation flags in conf.h in order +to get it to compile and link properly: + +SYSTEM5 Adjust for System V (not necessarily Release 4). +SYS5SIGNALS Use System V signal semantics -- the signal handler + is automatically dropped when the signal is caught. + If this is not set, use POSIX/BSD semantics, where the + signal handler stays in force until an exec or an + explicit delete. Implied by SYSTEM5. +SYS5SETPGRP Use System V setpgrp() semantics. Implied by SYSTEM5. +HASFCHMOD Define this to one if you have the fchmod(2) system call. + This improves security. +HASFLOCK Set this if you prefer to use the flock(2) system call + rather than using fcntl-based locking. Fcntl locking + has some semantic gotchas, but many vendor systems + also interface it to lockd(8) to do NFS-style locking. + Unfortunately, may vendors implementations of fcntl locking + is just plain broken (e.g., locks are never released, + causing your sendmail to deadlock; when the kernel runs + out of locks your system crashes). For this reason, I + recommend always defining this unless you are absolutely + certain that your fcntl locking implementation really works. +HASUNAME Set if you have the "uname" system call. Implied by + SYSTEM5. +HASUNSETENV Define this if your system library has the "unsetenv" + subroutine. +HASSETSID Define this if you have the setsid(2) system call. This + is implied if your system appears to be POSIX compliant. +HASINITGROUPS Define this if you have the initgroups(3) routine. +HASSETVBUF Define this if you have the setvbuf(3) library call. + If you don't, setlinebuf will be used instead. This + defaults on if your compiler defines __STDC__. +HASSETREUID Define this if you have setreuid(2) ***AND*** root can + use setreuid to change to an arbitrary user. This second + condition is not satisfied on AIX 3.x. You may find that + your system has setresuid(2), (for example, on HP-UX) in + which case you will also have to #define setreuid(r, e) + to be the appropriate call. Some systems (such as Solaris) + have a compatibility routine that doesn't work properly, + but may have "saved user ids" properly implemented so you + can ``#define setreuid(r, e) seteuid(e)'' and have it work. + The important thing is that you have a call that will set + the effective uid independently of the real or saved uid + and be able to set the effective uid back again when done. + There's a test program in ../test/t_setreuid.c that will + try things on your system. Setting this improves the + security, since sendmail doesn't have to read .forward + and :include: files as root. There are certain attacks + that may be unpreventable without this call. +USESETEUID Define this to 1 if you have seteuid(2) if you have a seteuid + system call that will allow root to set only the effective + user id to an arbitrary value ***AND*** you have saved user + ids. This is preferable to HASSETREUID if these conditions + are fulfilled. These are the semantics of the to-be-released + revision of Posix.1. The test program ../test/t_seteuid.c + will try this out on your system. If you define both + HASSETREUID and USESETEUID, the former is ignored. +HASLSTAT Define this if you have symbolic links (and thus the + lstat(2) system call). This improves security. Unlike + most other options, this one is on by default, so you + need to #undef it in conf.h if you don't have symbolic + links (these days everyone does). +HASSETRLIMIT Define this to 1 if you have the setrlimit(2) syscall. + You can define it to 0 to force it off. It is assumed + if you are running a BSD-like system. +HASULIMIT Define this if you have the ulimit(2) syscall (System V + style systems). HASSETRLIMIT overrides, as it is more + general. +HASWAITPID Define this if you have the waitpid(2) syscall. +HASGETDTABLESIZE + Define this if you have the getdtablesize(2) syscall. +NEEDGETOPT Define this if you need a reimplementation of getopt(3). + On some systems, getopt does very odd things if called + to scan the arguments twice. This flag will ask sendmail + to compile in a local version of getopt that works + properly. +NEEDSTRTOL Define this if your standard C library does not define + strtol(3). This will compile in a local version. +NEEDVPRINTF Define this if your standard C library does not define + vprintf(3). Note that the resulting fake implementation + is not very elegant and may not even work on some + architectures. +NEEDFSYNC Define this if your standard C library does not define + fsync(2). This will try to simulate the operation using + fcntl(2); if that is not available it does nothing, which + isn't great, but at least it compiles and runs. +HASGETUSERSHELL Define this to 1 if you have getusershell(3) in your + standard C library. If this is not defined, or is defined + to be 0, sendmail will scan the /etc/shells file (no + NIS-style support, defaults to /bin/sh and /bin/csh if + that file does not exist) to get a list of unrestricted + user shells. This is used to determine whether users + are allowed to forward their mail to a program or a file. +NEEDPUTENV Define this if your system needs am emulation of the + putenv(3) call. Define to 1 to implement it in terms + of setenv(3) or to 2 to do it in terms of primitives. +NOFTRUNCATE Define this if you don't have the ftruncate(2) syscall. + If you don't have this system call, there is an unavoidable + race condition that occurs when creating alias databases. +GIDSET_T The type of entries in a gidset passed as the second + argument to getgroups(2). Historically this has been an + int, so this is the default, but some systems (such as + IRIX) pass it as a gid_t, which is an unsigned short. + This will make a difference, so it is important to get + this right! However, it is only an issue if you have + group sets. +SLEEP_T The type returned by the system sleep() function. + Defaults to "unsigned int". Don't worry about this + if you don't have compilation problems. +ARBPTR_T The type of an arbitrary pointer -- defaults to "void *". + If you are an very old compiler you may need to define + this to be "char *". +LA_TYPE The type of load average your kernel supports. These + can be one of: + LA_ZERO (1) -- it always returns the load average as + "zero" (and does so on all architectures). + LA_INT (2) to read /dev/kmem for the symbol avenrun and + interpret as a long integer. + LA_FLOAT (3) same, but interpret the result as a floating + point number. + LA_SHORT (6) to interpret as a short integer. + LA_SUBR (4) if you have the getloadavg(3) routine in your + system library. + LA_MACH (5) to use MACH-style load averages (calls + processor_set_info()), + LA_PROCSTR (7) to read /proc/loadavg and interpret it + as a string representing a floating-point + number (Linux-style). + LA_READKSYM (8) is an implementation suitable for some + versions of SVr4 that uses the MIOC_READKSYM ioctl + call to read /dev/kmem. + LA_DGUX (9) is a special implementation for DG/UX that uses + the dg_sys_info system call. + LA_HPUX (10) is an HP-UX specific version that uses the + pstat_getdynamic system call. + LA_INT, LA_SHORT, LA_FLOAT, and LA_READKSYM have several + other parameters that they try to divine: the name of your + kernel, the name of the variable in the kernel to examine, + the number of bits of precision in a fixed point load average, + and so forth. + In desperation, use LA_ZERO. The actual code is in + conf.c -- it can be tweaked if you are brave. +FSHIFT For LA_INT, LA_SHORT, and LA_READKSYM, this is the number + of bits of load average after the binary point -- i.e., + the number of bits to shift right in order to scale the + integer to get the true integer load average. Defaults to 8. +_PATH_UNIX The path to your kernel. Needed only for LA_INT, LA_SHORT, + and LA_FLOAT. Defaults to "/unix" on System V, "/vmunix" + everywhere else. +LA_AVENRUN For LA_INT, LA_SHORT, and LA_FLOAT, the name of the kernel + variable that holds the load average. Defaults to "avenrun" + on System V, "_avenrun" everywhere else. +SFS_TYPE Encodes how your kernel can locate the amount of free + space on a disk partition. This can be set to SFS_NONE + (0) if you have no way of getting this information, + SFS_USTAT (1) if you have the ustat(2) system call, + SFS_4ARGS (2) if you have a four-argument statfs(2) + system call (and the include file is <sys/statfs.h>), + SFS_VFS (3), SFS_MOUNT (4), SFS_STATFS (5) if you have + the two-argument statfs(2) system call with includes in + <sys/vfs.h>, <sys/mount.h>, or <sys/statfs.h> respectively, + or SFS_STATVFS (6) if you have the two-argument statvfs(2) + call. The default if nothing is defined is SFS_NONE. +SFS_BAVAIL with SFS_4ARGS hou can also set SFS_BAVAIL to the field name + in the statfs structure that holds the useful information; + this defaults to f_bavail. +SPT_TYPE Encodes how your system can display what a process is doing + on a ps(1) command (SPT stands for Set Process Title). Can + be set to: + SPT_NONE (0) -- Don't try to set the process title at all. + SPT_REUSEARGV (1) -- Pad out your argv with the information; + this is the default if none specified. + SPT_BUILTIN (2) -- The system library has setproctitle. + SPT_PSTAT (3) -- Use the PSTAT_SETCMD option to pstat(2) + to set the process title; this is used by HP-UX. + SPT_PSSTRINGS (4) -- Use the magic PS_STRINGS pointer (4.4BSD). +SPT_PADCHAR Character used to pad the process title; if undefined, + the space character (0x20) is used. This is ignored if + SPT_TYPE != SPT_REUSEARGV +ERRLIST_PREDEFINED + If set, assumes that some header file defines sys_errlist. + This may be needed if you get type conflicts on this + variable -- otherwise don't worry about it. +WAITUNION The wait(2) routine takes a "union wait" argument instead + of an integer argument. This is for compatibility with + old versions of BSD. +SCANF You can set this to extend the F command to accept a + scanf string -- this gives you a primitive parser for + class definitions -- BUT it can make you vulnerable to + core dumps if the target file is poorly formed. +SYSLOG_BUFSIZE You can define this to be the size of the buffer that + syslog accepts. If it is not defined, it assumes a + 1024-byte buffer. If the buffer is very small (under + 256 bytes) the log message format changes -- each + e-mail message will log many more messages, since it + will log each piece of information as a separate line + in syslog. +BROKEN_RES_SEARCH + On Ultrix (and maybe other systems?) if you use the + res_search routine with an unknown host name, it returns + -1 but sets h_errno to 0 instead of HOST_NOT_FOUND. If + you set this, sendmail considers 0 to be the same as + HOST_NOT_FOUND. +NAMELISTMASK If defined, values returned by nlist(3) are masked + against this value before use -- a common value is + 0x7fffffff to strip off the top bit. +BSD4_4_SOCKADDR If defined, socket addresses have an sa_len field that + defines the length of this address. + + + ++-----------------------+ +| COMPILE-TIME FEATURES | ++-----------------------+ + +There are a bunch of features that you can decide to compile in, such +as selecting various database packages and special protocol support. +Several are assumed based on other compilation flags -- if you want to +"un-assume" something, you probably need to edit conf.h. Compilation +flags that add support for special features include: + +NDBM Include support for "new" DBM library for aliases and maps. + Normally defined in the Makefile. +NEWDB Include support for Berkeley "db" package (hash & btree) + for aliases and maps. Normally defined in the Makefile. +OLD_NEWDB If non-zero, the version of NEWDB you have is the old + one that does not include the "fd" call. This call was + added in version 1.5 of the Berkeley DB code. If you + use -DOLD_NEWDB=0 it forces you to use the new interface. +NIS Define this to get NIS (YP) support for aliases and maps. + Normally defined in the Makefile. +NISPLUS Define this to get NIS+ support for aliases and maps. + Normally defined in the Makefile. +HESIOD Define this to get Hesiod support for aliases and maps. + Normally defined in the Makefile. +NETINFO Define this to get NeXT NetInfo support for aliases and maps. + Normally defined in the Makefile. +USERDB Define this to 1 to include support for the User Information + Database. Implied by NEWDB or HESIOD. You can use + -DUSERDB=0 to explicitly turn it off. +IDENTPROTO Define this as 1 to get IDENT (RFC 1413) protocol support. + This is assumed unless you are running on Ultrix or + HP-UX, both of which have a problem in the UDP + implementation. You can define it to be 0 to explicitly + turn off IDENT protocol support. If defined off, the code + is actually still compiled in, but it defaults off; you + can turn it on by setting the IDENT timeout to 30s in the + configuration file. +IP_SRCROUTE Define this to 1 to get IP source routing information + displayed in the Received: header. This is assumed on + most systems, but some (e.g., Ultrix) apparently have a + broken version of getsockopt that doesn't properly + support the IP_OPTIONS call. You probably want this if + your OS can cope with it. Symptoms of failure will be that + it won't compile properly (that is, no support for fetching + IP_OPTIONs), or it compiles but source-routed TCP connections + either refuse to open or open and hang for no apparent reason. + Ultrix and AIX are known to fail this way. +LOG Set this to get syslog(3) support. Defined by default + in conf.h. You want this if at all possible. +NETINET Set this to get TCP/IP support. Defined by default + in conf.h. You probably want this. +NETISO Define this to get ISO networking support. +NETUNIX Define this to get Unix domain networking support. Defined + by default. A few bizarre systems (SCO, ISC, Altos) don't + support this networking domain. +SMTP Define this to get the SMTP code. Implied by NETINET + or NETISO. +NAMED_BIND If non-zero, include DNS (name daemon) support, including + MX support. The specs say you must use this if you run + SMTP. You don't have to be running a name server daemon + on your machine to need this -- any use of the DNS resolver, + including remote access to another machine, requires this + option. Defined by default in conf.h. Define it to zero + ONLY on machines that do not use DNS in any way. +QUEUE Define this to get queueing code. Implied by NETINET + or NETISO; required by SMTP. This gives you other good + stuff -- it should be on. +DAEMON Define this to get general network support. Implied by + NETINET or NETISO. Defined by default in conf.h. You + almost certainly want it on. +MATCHGECOS Permit fuzzy matching of user names against the full + name (GECOS) field in the /etc/passwd file. This should + probably be on, since you can disable it from the config + file if you want to. Defined by default in conf.h. +MIME8TO7 If non-zero, include 8 to 7 bit MIME conversions. This + also controls advertisement of 8BITMIME in the ESMTP + startup dialogue. +MIME7TO8 If non-zero, include 7 to 8 bit MIME conversions. Not yet + implemented. +HES_GETMAILHOST Define this to 1 if you are using Hesiod with the + hes_getmailhost() routine. This is included with the MIT + Hesiod distribution, but not with the DEC Hesiod distribution. +XDEBUG Do additional internal checking. These don't cost too + much; you might as well leave this on. + + ++---------------------+ +| DNS/RESOLVER ISSUES | ++---------------------+ + +Many systems have old versions of the resolver library. At a minimum, +you should be running BIND 4.8.3; older versions may compile, but they +have known bugs that should give you pause. + +Common problems in old versions include "undefined" errors for +dn_skipname. + +Some people have had a problem with BIND 4.9; it uses some routines +that it expects to be externally defined such as strerror(). It may +help to link with "-l44bsd" to solve this problem. + +!PLEASE! be sure to link with the same version of the resolver as +the header files you used -- some people have used the 4.9 headers +and linked with BIND 4.8 or vice versa, and it doesn't work. +Unfortunately, it doesn't fail in an obvious way -- things just +subtly don't work. + +WILDCARD MX RECORDS ARE A BAD IDEA! The only situation in which they +work reliably is if you have two versions of DNS, one in the real world +which has a wildcard pointing to your firewall, and a completely +different version of the database internally that does not include +wildcard MX records that match your domain. ANYTHING ELSE WILL GIVE +YOU HEADACHES! + + ++-------------------------------------+ +| OPERATING SYSTEM AND COMPILE QUIRKS | ++-------------------------------------+ + +GCC 2.5.x problems *** IMPORTANT *** + Date: Mon, 29 Nov 93 19:08:44 PST + From: wilson@cygnus.com (Jim Wilson) + Message-Id: <9311300308.AA04608@cygnus.com> + To: kenner@vlsi1.ultra.nyu.edu + Subject: [cattelan@thebarn.com: gcc 2.5.4-2.5.5 -O bug] + Cc: cattelan@thebarn.com, rms@gnu.ai.mit.edu, sendmail@cs.berkeley.edu + + This fixes a problem that occurs when gcc 2.5.5 is used to compile + sendmail 8.6.4 with optimization on a sparc. + + Mon Nov 29 19:00:14 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * reload.c (find_reloads_toplev): Replace obsolete reference to + BYTE_LOADS_*_EXTEND with LOAD_EXTEND_OP. + + *** clean-ss-931128/reload.c Sun Nov 14 16:20:01 1993 + --- ss-931128/reload.c Mon Nov 29 18:52:55 1993 + *************** find_reloads_toplev (x, opnum, type, ind + *** 3888,3894 **** + force a reload in that case. So we should not do anything here. */ + + else if (regno >= FIRST_PSEUDO_REGISTER + ! #if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND) + && (GET_MODE_SIZE (GET_MODE (x)) + <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) + #endif + --- 3888,3894 ---- + force a reload in that case. So we should not do anything here. */ + + else if (regno >= FIRST_PSEUDO_REGISTER + ! #ifdef LOAD_EXTEND_OP + && (GET_MODE_SIZE (GET_MODE (x)) + <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) + #endif + +GCC 2.7.x problems + Apparently GCC 2.7.0 on the Pentium processor has optimization + problems. I recommend against using -O on that architecture. This + has been seen on FreeBSD 2.0.5 RELEASE. + + +SunOS 4.x (Solaris 1.x) + You may have to use -lresolv on SunOS. However, beware that + this links in a new version of gethostbyname that does not + understand NIS, so you must have all of your hosts in DNS. + + Some people have reported problems with the SunOS version of + -lresolv and/or in.named, and suggest that you get a newer + version. The symptoms are delays when you connect to the + SMTP server on a SunOS machine or having your domain added to + addresses inappropriately. There is a version of BIND + version 4.9 on gatekeeper.DEC.COM in pub/BSD/bind/4.9. + + There is substantial disagreement about whether you can make + this work with resolv+, which allows you to specify a search-path + of services. Some people report that it works fine, others + claim it doesn't work at all (including causing sendmail to + drop core when it tries to do multiple resolv+ lookups for a + single job). I haven't tried resolv+, as we use DNS exclusively. + + Should you want to try resolv+, it is on ftp.uu.net in + /networking/ip/dns. + + Apparently getservbyname() can fail under moderate to high + load under some circumstances. This will exhibit itself as + the message ``554 makeconnection: service "smtp" unknown''. + The problem has been traced to one or more blank lines in + /etc/services on the NIS server machine. Delete these + and it should work. This info is thanks to Brian Bartholomew + <bb@math.ufl.edu> of I-Kinetics, Inc. + +SunOS 4.0.2 (Sun 386i) + Date: Fri, 25 Aug 1995 11:13:58 +0200 (MET DST) + From: teus@oce.nl + + Sendmail 8.7.Beta.12 compiles and runs nearly out of the box with the + following changes: + * Don't use /usr/5bin in your PATH, but make /usr/5bin/uname + available as "uname" command. + * Use the defines "-DBSD4_3 -DNAMED_BIND=0" in the + Makefile.SunOS.4.0, which is selected via the "uname" command. + I recommend to make available the db-library on the system first + (and change the Makefile to use this library). + Note that the sendmail.cf and aliases files are found in /etc. + +SunOS 4.1.3_U1 + Sendmail causes crashes on SunOS 4.1.3_U1. According to Sun + bug number 1077939: + + If an application does a getsockopt() on a SOCK_STREAM (TCP) socket + after the other side of the connection has sent a TCP RESET for + the stream, the kernel gets a Bus Trap in the tcp_ctloutput() or + ip_ctloutput() routine. + + This is fixed in patch 101790-01 (SunOS 4.1.3_U1: TCP socket and + reset problems). + +Solaris 2.x (SunOS 5.x) + To compile for Solaris, be sure you use -DSOLARIS. + + To the best of my knowledge, Solaris does not have the + gethostbyname problem described above. However, it does + have another one: + + From a correspondent: + + For solaris 2.2, I have + + hosts: files dns + + in /etc/nsswitch.conf and /etc/hosts has to have the fully + qualified host name. I think "files" has to be before "dns" + in /etc/nsswitch.conf during bootup. + + From another correspondent: + + When running sendmail under Solaris, the gethostbyname() + hack in conf.c which should perform proper canonicalization + of host names could fail. Result: the host name is not + canonicalized despite the hack, and you'll have to define $j + and $m in sendmail.cf somewhere. + + The reason could be that /etc/nsswitch.conf is improperly + configured (at least from sendmail's point of view). For + example, the line + + hosts: files nisplus dns + + will make gethostbyname() look in /etc/hosts first, then ask + nisplus, then dns. However, if /etc/hosts does not contain + the full canonicalized hostname, then no amount of + gethostbyname()s will work. + + Solution (or rather, a workaround): Ask nisplus first, then + dns, then local files: + + hosts: nisplus dns [NOTFOUND=return] files + + The Solaris "syslog" function is apparently limited to something + about 90 characters because of a kernel limitation. If you have + source code, you can probably up this number. You can get patches + that fix this problem: the patch ids are: + + Solaris 2.1 100834 + Solaris 2.2 100999 + Solaris 2.3 101318 + + Be sure you have the appropriate patch installed or you won't + see system logging. + +Solaris 2.4 (SunOS 5.4) + If you include /usr/lib at the end of your LD_LIBRARY_PATH you run + the risk of getting the wrong libraries under some circumstances. + This is because of a new feature in Solaris 2.4, described by + Rod.Evans@Eng.Sun.COM: + + >> Prior to SunOS 5.4, any LD_LIBRARY_PATH setting was ignored by the + >> runtime linker if the application was setxid (secure), thus your + >> applications search path would be: + >> + >> /usr/local/lib LD_LIBRARY_PATH component - IGNORED + >> /usr/lib LD_LIBRARY_PATH component - IGNORED + >> /usr/local/lib RPATH - honored + >> /usr/lib RPATH - honored + >> + >> the effect is that path 3 would be the first used, and this would + >> satisfy your resolv.so lookup. + >> + >> In SunOS 5.4 we made the LD_LIBRARY_PATH a little more flexible. + >> People who developed setxid applications wanted to be able to alter + >> the library search path to some degree to allow for their own + >> testing and debugging mechanisms. It was decided that the only + >> secure way to do this was to allow a `trusted' path to be used in + >> LD_LIBRARY_PATH. The only trusted directory we presently define + >> is /usr/lib. Thus a setuid root developer could play with some + >> alternative shared object implementations and place them in + >> /usr/lib (being root we assume they'ed have access to write in this + >> directory). This change was made as part of 1155380 - after a + >> *huge* amount of discussion regarding the security aspect of things. + >> + >> So, in SunOS 5.4 your applications search path would be: + >> + >> /usr/local/lib from LD_LIBRARY_PATH - IGNORED (untrustworthy) + >> /usr/lib from LD_LIBRARY_PATH - honored (trustworthy) + >> /usr/local/lib from RPATH - honored + >> /usr/lib from RPATH - honored + >> + >> here, path 2 would be the first used. + +Ultrix + By default, the IDENT protocol is turned off on Ultrix. If you + are running Ultrix 4.4 or later, or if you have included patch + CXO-8919 for Ultrix 4.2 or 4.3 to fix the TCP problem, you can turn + IDENT on in the configuration file by setting the "ident" timeout + to 30 seconds. + +OSF/1 + If you are compiling on OSF/1 (DEC Alpha), you must use + -L/usr/shlib (otherwise it core dumps on startup). You may also + need -mld to get the nlist() function, although some versions + apparently don't need this. + + Also, the enclosed makefile removed /usr/sbin/smtpd; if you need + it, just create the link to the sendmail binary. + +IRIX + The header files on SGI IRIX are completely prototyped, and as + a result you can sometimes get some warning messages during + compilation. These can be ignored. There are two errors in + deliver only if you are using gcc, both of the form ``warning: + passing arg N of `execve' from incompatible pointer type''. + Also, if you compile with -DNIS, you will get a complaint + about a declaration of struct dom_binding in a prototype + when compiling map.c; this is not important because the + function being prototyped is not used in that file. + + In order to compile sendmail you will have had to install + the developers' option in order to get the necessary include + files. + +NeXT or NEXTSTEP + NEXTSTEP 3.3 and earlier ship with the old DBM library. You will + need to acquire the new Berkeley DB from ftp.cs.berkeley.edu. + Install it in /usr/local/{lib,include}. + + If you are compiling on NEXTSTEP, you will have to create an + empty file "unistd.h" and create a file "dirent.h" containing: + + #include <sys/dir.h> + #define dirent direct + + (The Makefile.NeXT should try to do both of these for you.) + + Apparently, there is a bug in getservbyname on Nextstep 3.0 + that causes it to fail under some circumstances with the + message "SYSERR: service "smtp" unknown" logged. You should + be able to work around this by including the line: + + OOPort=25 + + in your .cf file. + + You may have to use -DNeXT. + +BSDI (BSD/386) 1.0, NetBSD 0.9, FreeBSD 1.0 + The "m4" from BSDI won't handle the config files properly. + I haven't had a chance to test this myself. + + The M4 shipped in FreeBSD and NetBSD 0.9 don't handle the config + files properly. One must use either GNU m4 1.1 or the PD-M4 + recently posted in comp.os.386bsd.bugs (and maybe others). + NetBSD-current includes the PD-M4 (as stated in the NetBSD file + CHANGES). + + FreeBSD 1.0 RELEASE has uname(2) now. Use -DUSEUNAME in order to + use it (look into Makefile.FreeBSD). NetBSD-current may have + it too but it has not been verified. + + You cannot port the latest version of the Berkeley db library + and use it with sendmail without recompiling the world. This + is because C library routines use the older version which have + incompatible header files -- the result is that it can't read + other system files, such as /etc/passwd, unless you use the + new db format throughout your system. You should normally just + use the version of db supplied in your release. You may need + to use -DOLD_NEWDB=1 to make this work -- this turns off some + new interface calls (for file locking) that are not in older + versions of db. You'll get compile errors if you need this + flag and don't have it set. + +4.3BSD + If you are running a "virgin" version of 4.3BSD, you'll have + a very old resolver and be missing some header files. The + header files are simple -- create empty versions and everything + will work fine. For the resolver you should really port a new + version (4.8.3 or later) of the resolver; 4.9 is available on + gatekeeper.DEC.COM in pub/BSD/bind/4.9. If you are really + determined to continue to use your old, buggy version (or as + a shortcut to get sendmail working -- I'm sure you have the + best intentions to port a modern version of BIND), you can + copy ../contrib/oldbind.compat.c into src and add + oldbind.compat.o to OBJADD in the Makefile. + +A/UX + Date: Tue, 12 Oct 1993 18:28:28 -0400 (EDT) + From: "Eric C. Hagberg" <hagberg@med.cornell.edu> + Subject: Fix for A/UX ndbm + + I guess this isn't really a sendmail bug, however, it is something + that A/UX users should be aware of when compiling sendmail 8.6. + + Apparently, the calls that sendmail is using to the ndbm routines + in A/UX 3.0.x contain calls to "broken" routines, in that the + aliases database will break when it gets "just a little big" + (sorry I don't have exact numbers here, but it broke somewhere + around 20-25 aliases for me.), making all aliases non-functional + after exceeding this point. + + What I did was to get the gnu-dbm-1.6 package, compile it, and + then re-compile sendmail with "-lgdbm", "-DNDBM", and using the + ndbm.h header file that comes with the gnu-package. This makes + things behave properly. + + I suppose porting the New Berkeley db package is another route, + however, I made a quick attempt at it, and found it difficult + (not easy at least); the gnu-dbm package "configured" and + compiled easily. + +SCO Unix + From: Thomas Essebier <tom@stallion.oz.au> + Organisation: Stallion Technologies Pty Ltd. + + It will probably help those who are trying to configure sendmail 8.6.9 + to know that if they are on SCO, they had better set + OI-dnsrch + or they will core dump as soon as they try to use the resolver. + ie. although SCO has _res.dnsrch defined, and is kinda BIND 4.8.3, it + does not inititialise it, nor does it understand 'search' in + /etc/named.boot. + - sigh - + +DG/UX + Doug Anderson <dlander@afterlife.ncsc.mil> has successfully run + V8 on the DG/UX 5.4.2 and 5.4R3.x platforms under heavy usage. + Originally, the DG /bin/mail program wasn't compatible with + the V8 sendmail, since the DG /bin/mail requires the environment + variable "_FORCE_MAIL_LOCAL_=yes" be set. Version 8.7 now includes + this in the environment before invoking the local mailer. Some + have used procmail to avoid this problem in the past. It works + but some have experienced file locking problems with their DG/UX + ports of procmail. + +Apollo DomainOS + If you are compiling on Apollo, you will have to create an empty + file "unistd.h" and create a file "dirent.h" containing: + + #include <sys/dir.h> + #define dirent direct + + (The Makefile.DomainOS will attempt to do both of these for you.) + +HP-UX 8.00 + Date: Mon, 24 Jan 1994 13:25:45 +0200 + From: Kimmo Suominen <Kimmo.Suominen@lut.fi> + Subject: 8.6.5 w/ HP-UX 8.00 on s300 + + Just compiled and fought with sendmail 8.6.5 on a HP9000/360 (ie. a + series 300 machine) running HP-UX 8.00. + + I was getting segmentation fault when delivering to a local user. + With debugging I saw it was faulting when doing _free@libc... *sigh* + It seems the new implementation of malloc on s300 is buggy as of 8.0, + so I tried out the one in -lmalloc (malloc(3X)). With that it seems + to work just dandy. + + When linking, you will get the following error: + + ld: multiply defined symbol _freespace in file /usr/lib/libmalloc.a + + but you can just ignore it. You might want to add this info to the + README file for the future... + +Linux + Something broke between versions 0.99.13 and 0.99.14 of Linux: + the flock() system call gives errors. If you are running .14, + you must not use flock. You can do this with -DHASFLOCK=0. + + Around the inclusion of bind-4.9.3 & linux libc-4.6.20, the + initialization of the _res structure changed. If /etc/hosts.conf + was configured as "hosts, bind" the resolver code could return + "Name server failure" errors. This is supposedly fixed in + later versions of libc (>= 4.6.29?), and later versions of + sendmail (> 8.6.10) try to work around the problem. + + Some older versions (< 4.6.20?) of the libc/include files conflict + with sendmail's version of cdefs.h. Deleting sendmail's version + on those systems should be non-harmful, and new versions don't care. + + Sendmail assumes that libc has snprintf, which has been true since + libc 4.7.0. If you are running an older version, you will need to + use -DHASSNPRINTF=0 in the Makefile. If may be able to use -lbsd + (which includes snprintf) instead of turning this off on versions + of libc between 4.4.4 and 4.7.0 (snprintf improves security, so + you want to use this if at all possible). + +AIX + This version of sendmail does not support MB, MG, and MR resource + records, which are supported by AIX sendmail. + + Several people have reported that the IBM-supplied named returns + fairly random results -- the named should be replaced. It is not + necessary to replace the resolver, which will simplify installation. + A new BIND resolver can be found at http://www.isc.org/isc/. + +RISC/os + RISC/os from MIPS is a merged AT&T/Berkeley system. When you + compile on that platform you will get duplicate definitions + on many files. You can ignore these. + +System V Release 4 Based Systems + There is a single Makefile that is intended for all SVR4-based + systems (called Makefile.SVR4). It defines __svr4__, which is + predefined by some compilers. If your compiler already defines + this compile variable, you can delete the definition from the + Makefile. + + It's been tested on Dell Issue 2.2. + +DELL SVR4 + Date: Mon, 06 Dec 1993 10:42:29 EST + From: "Kimmo Suominen" <kim@grendel.lut.fi> + Message-ID: <2d0352f9.lento29@lento29.UUCP> + To: eric@cs.berkeley.edu + Cc: sendmail@cs.berkeley.edu + Subject: Notes for DELL SVR4 + + Eric, + + Here are some notes for compiling Sendmail 8.6.4 on DELL SVR4. I ran + across these things when helping out some people who contacted me by + e-mail. + + 1) Use gcc 2.4.5 (or later?). Dell distributes gcc 2.1 with their + Issue 2.2 Unix. It is too old, and gives you problems with + clock.c, because sigset_t won't get defined in <sys/signal.h>. + This is due to a problematic protection rule in there, and is + fixed with gcc 2.4.5. + + 2) If you don't use the new Berkeley DB (-DNEWDB), then you need + to add "-lc -lucb" to the libraries to link with. This is because + the -ldbm distributed by Dell needs the bcopy, bcmp and bzero + functions. It is important that you specify both libraries in + the given order to be sure you only get the BSTRING functions + from the UCB library (and not the signal routines etc.). + + 3) Don't leave out "-lelf" even if compiling with "-lc -lucb". + The UCB library also has another copy of the nlist routines, + but we do want the ones from "-lelf". + + If anyone needs a compiled gcc 2.4.5 and/or a ported DB library, they + can use anonymous ftp to fetch them from lut.fi in the /kim directory. + They are copies of what I use on grendel.lut.fi, and offering them + does not imply that I would also support them. I have sent the DB + port for SVR4 back to Keith Bostic for inclusion in the official + distribution, but I haven't heard anything from him as of today. + + - gcc-2.4.5-svr4.tar.gz (gcc 2.4.5 and the corresponding libg++) + - db-1.72.tar.gz (with source, objects and a installed copy) + + Cheers + + Kim + -- + * Kimmo.Suominen@lut.fi * SysVr4 enthusiast at GRENDEL.LUT.FI * + * KIM@FINFILES.BITNET * Postmaster and Hostmaster at LUT.FI * + * + 358 200 865 718 * Unix area moderator at NIC.FUNET.FI * + +ConvexOS 10.1 and below + In order to use the name server, you must create the file + /etc/use_nameserver. If this file does not exist, the call + to res_init() will fail and you will have absolutely no + access to DNS, including MX records. + +Amdahl UTS 2.1.5 + In order to get UTS to work, you will have to port BIND 4.9. + The vendor's BIND is reported to be ``totally inadequate.'' + See sendmail/contrib/AmdahlUTS.patch for the patches necessary + to get BIND 4.9 compiled for UTS. + +UnixWare 2.0 + According to Alexander Kolbasov <sasha@unitech.gamma.ru>, + the m4 on UnixWare 2.0 (still in Beta) will core dump on the + config files. GNU m4 and the m4 from UnixWare 1.x both work. + +UNICOS 8.0.3.4 + Some people have reported that the -O flag on UNICOS can cause + problems. You may want to turn this off if you have problems + running sendmail. Reported by Jerry G. DeLapp <jgd@acl.lanl.gov>. + +Non-DNS based sites + This version of sendmail always tries to connect to the Domain + Name System (DNS) to resolve names, regardless of the setting + of the `I' option. On most systems that are not running DNS, + this will fail quickly and sendmail will continue, but on some + systems it has a long timeout. If you have this problem, you + will have to recompile without NAMED_BIND. Some people have + claimed that they have successfully used "OI+USEVC" to force + sendmail to use a virtual circuit -- this will always time out + quickly, but also tells sendmail that a failed connection + should requeue the message (probably not what you intended). + A future release of sendmail will correct this problem. + +Both NEWDB and NDBM + If you use both -DNDBM and -DNEWDB, you must delete the module + ndbm.o from libdb.a and delete the file "ndbm.h" from the files + that get installed (that is, use the OLD ndbm.h, not the new + ndbm.h). This compatibility module maps ndbm calls into DB + calls, and breaks things rather badly. + +GNU getopt + I'm told that GNU getopt has a problem in that it gets confused + by the double call. Use the version in conf.c instead. + +BIND 4.9.2 and Ultrix + If you are running on Ultrix, be sure you read conf/Info.Ultrix + in the BIND distribution very carefully -- there is information + in there that you need to know in order to avoid errors of the + form: + + /lib/libc.a(gethostent.o): sethostent: multiply defined + /lib/libc.a(gethostent.o): endhostent: multiply defined + /lib/libc.a(gethostent.o): gethostbyname: multiply defined + /lib/libc.a(gethostent.o): gethostbyaddr: multiply defined + + during the link stage. + +strtoul + Some compilers (notably gcc) claim to be ANSI C but do not + include the ANSI-required routine "strtoul". If your compiler + has this problem, you will get an error in srvrsmtp.c on the + code: + + # ifdef defined(__STDC__) && !defined(BROKEN_ANSI_LIBRARY) + e->e_msgsize = strtoul(vp, (char **) NULL, 10); + # else + e->e_msgsize = strtol(vp, (char **) NULL, 10); + # endif + + You can use -DBROKEN_ANSI_LIBRARY to get around this problem. + +Listproc 6.0c + Date: 23 Sep 1995 23:56:07 GMT + Message-ID: <95925101334.~INN-AUMa00187.comp-news@dl.ac.uk> + From: alansz@mellers1.psych.berkeley.edu (Alan Schwartz) + Subject: Listproc 6.0c + Sendmail 8.7 [Helpful hint] + + Just upgraded to sendmail 8.7, and discovered that listproc 6.0c + breaks, because it, by default, sends a blank "HELO" rather than + a "HELO hostname" when using the 'system' or 'telnet' mailmethod. + + The fix is to include -DZMAILER in the compilation, which will + cause it to use "HELO hostname" (which Z-mail apparently requires + as well. :) + + + ++--------------+ +| MANUAL PAGES | ++--------------+ + +The manual pages have been written against the -mandoc macros +instead of the -man macros. The latest version of groff has them +included. You can also get a copy from FTP.UU.NET in directory +/systems/unix/bsd-sources/share/tmac. + + ++-----------------+ +| DEBUGGING HOOKS | ++-----------------+ + +As of 8.6.5, sendmail daemons will catch a SIGUSR1 signal and log +some debugging output (logged at LOG_DEBUG severity). The +information dumped is: + + * The value of the $j macro. + * A warning if $j is not in the set $=w. + * A list of the open file descriptors. + * The contents of the connection cache. + * If ruleset 89 is defined, it is evaluated and the results printed. + +This allows you to get information regarding the runtime state of the +daemon on the fly. This should not be done too frequently, since +the process of rewriting may lose memory which will not be recovered. +Also, ruleset 89 may call non-reentrant routines, so there is a small +non-zero probability that this will cause other problems. It is +really only for debugging serious problems. + +A typical formulation of ruleset 89 would be: + + R$* $@ $>0 some test address + + ++-----------------------------+ +| DESCRIPTION OF SOURCE FILES | ++-----------------------------+ + +The following list describes the files in this directory: + +Makefile The makefile used here; this version only works with + the new Berkeley make. +Makefile.dist A trimmed down version of the makefile that works with + the old make. +READ_ME This file. +TRACEFLAGS My own personal list of the trace flags -- not guaranteed + to be particularly up to date. +alias.c Does name aliasing in all forms. +arpadate.c A subroutine which creates ARPANET standard dates. +clock.c Routines to implement real-time oriented functions + in sendmail -- e.g., timeouts. +collect.c The routine that actually reads the mail into a temp + file. It also does a certain amount of parsing of + the header, etc. +conf.c The configuration file. This contains information + that is presumed to be quite static and non- + controversial, or code compiled in for efficiency + reasons. Most of the configuration is in sendmail.cf. +conf.h Configuration that must be known everywhere. +convtime.c A routine to sanely process times. +daemon.c Routines to implement daemon mode. This version is + specifically for Berkeley 4.1 IPC. +deliver.c Routines to deliver mail. +domain.c Routines that interface with DNS (the Domain Name + System). +err.c Routines to print error messages. +envelope.c Routines to manipulate the envelope structure. +headers.c Routines to process message headers. +macro.c The macro expander. This is used internally to + insert information from the configuration file. +main.c The main routine to sendmail. This file also + contains some miscellaneous routines. +map.c Support for database maps. +mci.c Routines that handle mail connection information caching. +parseaddr.c The routines which do address parsing. +queue.c Routines to implement message queueing. +readcf.c The routine that reads the configuration file and + translates it to internal form. +recipient.c Routines that manipulate the recipient list. +savemail.c Routines which save the letter on processing errors. +sendmail.h Main header file for sendmail. +srvrsmtp.c Routines to implement server SMTP. +stab.c Routines to manage the symbol table. +stats.c Routines to collect and post the statistics. +sysexits.c List of error messages associated with error codes + in sysexits.h. +trace.c The trace package. These routines allow setting and + testing of trace flags with a high granularity. +udb.c The user database interface module. +usersmtp.c Routines to implement user SMTP. +util.c Some general purpose routines used by sendmail. +version.c The version number and information about this + version of sendmail. Theoretically, this gets + modified on every change. + +Eric Allman + +(Version 8.112, last update 11/18/95 08:44:31) diff --git a/usr.sbin/sendmail/src/TRACEFLAGS b/usr.sbin/sendmail/src/TRACEFLAGS new file mode 100644 index 000000000000..f2499aac0913 --- /dev/null +++ b/usr.sbin/sendmail/src/TRACEFLAGS @@ -0,0 +1,71 @@ +0, 1 main.c main skip background fork +0, 4 main.c main canonical name, UUCP node name, a.k.a.s +0, 15 main.c main print configuration +0, 44 util.c printav print address of each string +1 main.c main print from person +2 main.c finis +3 conf.c getla, shouldqueue +4 conf.c enoughspace +5 clock.c setevent, clrevent, tick +6 savemail.c savemail, returntosender +7 queue.c queuename +8 domain.c getmxrr, getcanonname +9 daemon.c getauthinfo IDENT protocol +9 daemon.c maphostname +10 deliver.c deliver +11 deliver.c openmailer, mailfile +12 parseaddr.c remotename +13 deliver.c sendall, sendenvelope +14 headers.c commaize +15 daemon.c getrequests +16 daemon.c makeconnection +17 deliver.c hostsignature +17 domain.c mxrand +18 usersmtp.c reply, smtpmessage, smtpinit, smtpmailfrom +19 srvrsmtp.c smtp +20 parseaddr.c parseaddr +21 parseaddr.c rewrite +22 parseaddr.c prescan +24 parseaddr.c buildaddr, allocaddr +25 recipient.c sendtolist +26 recipient.c recipient +27 alias.c alias +27 alias.c readaliases +27 alias.c forward +27 recipient.c include +28 udb.c udbexpand, udbsender +29 parseaddr.c maplocaluser +29 recipient.c recipient (local users), finduser +30 collect.c collect +30 collect.c eatfrom +31 headers.c chompheader +32 headers.c eatheader +33 headers.c crackaddr +34 headers.c putheader +35 macro.c expand, define +36 stab.c stab +37 readcf.c (many) +38 map.c initmaps +39 map.c map_rewrite +40 queue.c queueup, orderq, dowork +41 queue.c orderq +42 mci.c mci_get +43 mime.c mime8to7 +44 recipient.c writeable +44 util.c safefile +45 envelope.c setsender +46 envelope.c openxscript +49 conf.c checkcompat +50 envelope.c dropenvelope +51 queue.c unlockqueue +52 main.c disconnect +53 util.c xfclose +54 err.c putoutmsg +55 conf.c lockfile +59 Extended Load Average implementation from Christophe Wolfhugel +60 map.c +61 conf.c sm_gethostbyname +80 content length +81 sun remote mode +91 mci.c syslogging of MCI cache information +99 main.c avoid backgrounding (no printed output) diff --git a/usr.sbin/sendmail/src/alias.c b/usr.sbin/sendmail/src/alias.c new file mode 100644 index 000000000000..2bc4487d4a36 --- /dev/null +++ b/usr.sbin/sendmail/src/alias.c @@ -0,0 +1,835 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +# include "sendmail.h" + +#ifndef lint +static char sccsid[] = "@(#)alias.c 8.52 (Berkeley) 10/28/95"; +#endif /* not lint */ + + +MAP *AliasFileMap = NULL; /* the actual aliases.files map */ +int NAliasFileMaps; /* the number of entries in AliasFileMap */ +/* +** ALIAS -- Compute aliases. +** +** Scans the alias file for an alias for the given address. +** If found, it arranges to deliver to the alias list instead. +** Uses libdbm database if -DDBM. +** +** Parameters: +** a -- address to alias. +** sendq -- a pointer to the head of the send queue +** to put the aliases in. +** aliaslevel -- the current alias nesting depth. +** e -- the current envelope. +** +** Returns: +** none +** +** Side Effects: +** Aliases found are expanded. +** +** Deficiencies: +** It should complain about names that are aliased to +** nothing. +*/ + +void +alias(a, sendq, aliaslevel, e) + register ADDRESS *a; + ADDRESS **sendq; + int aliaslevel; + register ENVELOPE *e; +{ + register char *p; + int naliases; + char *owner; + auto int stat = EX_OK; + char obuf[MAXNAME + 6]; + extern char *aliaslookup(); + + if (tTd(27, 1)) + printf("alias(%s)\n", a->q_user); + + /* don't realias already aliased names */ + if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags)) + return; + + if (NoAlias) + return; + + e->e_to = a->q_paddr; + + /* + ** Look up this name. + ** + ** If the map was unavailable, we will queue this message + ** until the map becomes available; otherwise, we could + ** bounce messages inappropriately. + */ + + p = aliaslookup(a->q_user, &stat, e); + if (stat == EX_TEMPFAIL || stat == EX_UNAVAILABLE) + { + a->q_flags |= QQUEUEUP; + if (e->e_message == NULL) + e->e_message = "alias database unavailable"; + return; + } + if (p == NULL) + return; + + /* + ** Match on Alias. + ** Deliver to the target list. + */ + + if (tTd(27, 1)) + printf("%s (%s, %s) aliased to %s\n", + a->q_paddr, a->q_host, a->q_user, p); + if (bitset(EF_VRFYONLY, e->e_flags)) + { + a->q_flags |= QVERIFIED; + return; + } + message("aliased to %s", shortenstring(p, 203)); +#ifdef LOG + if (LogLevel > 9) + syslog(LOG_INFO, "%s: alias %.100s => %s", + e->e_id == NULL ? "NOQUEUE" : e->e_id, + a->q_paddr, shortenstring(p, 203)); +#endif + a->q_flags &= ~QSELFREF; + if (tTd(27, 5)) + { + printf("alias: QDONTSEND "); + printaddr(a, FALSE); + } + a->q_flags |= QDONTSEND; + naliases = sendtolist(p, a, sendq, aliaslevel + 1, e); + if (bitset(QSELFREF, a->q_flags)) + a->q_flags &= ~QDONTSEND; + + /* + ** Look for owner of alias + */ + + (void) strcpy(obuf, "owner-"); + if (strncmp(a->q_user, "owner-", 6) == 0) + (void) strcat(obuf, "owner"); + else + (void) strcat(obuf, a->q_user); + if (!bitnset(M_USR_UPPER, a->q_mailer->m_flags)) + makelower(obuf); + owner = aliaslookup(obuf, &stat, e); + if (owner == NULL) + return; + + /* reflect owner into envelope sender */ + if (strpbrk(owner, ",:/|\"") != NULL) + owner = obuf; + a->q_owner = newstr(owner); + + /* announce delivery to this alias; NORECEIPT bit set later */ + if (e->e_xfp != NULL) + fprintf(e->e_xfp, "Message delivered to mailing list %s\n", + a->q_paddr); + e->e_flags |= EF_SENDRECEIPT; + a->q_flags |= QDELIVERED|QEXPANDED; +} +/* +** ALIASLOOKUP -- look up a name in the alias file. +** +** Parameters: +** name -- the name to look up. +** pstat -- a pointer to a place to put the status. +** e -- the current envelope. +** +** Returns: +** the value of name. +** NULL if unknown. +** +** Side Effects: +** none. +** +** Warnings: +** The return value will be trashed across calls. +*/ + +char * +aliaslookup(name, pstat, e) + char *name; + int *pstat; + ENVELOPE *e; +{ + static MAP *map = NULL; + + if (map == NULL) + { + STAB *s = stab("aliases", ST_MAP, ST_FIND); + + if (s == NULL) + return NULL; + map = &s->s_map; + } + if (!bitset(MF_OPEN, map->map_mflags)) + return NULL; + return (*map->map_class->map_lookup)(map, name, NULL, pstat); +} +/* +** SETALIAS -- set up an alias map +** +** Called when reading configuration file. +** +** Parameters: +** spec -- the alias specification +** +** Returns: +** none. +*/ + +void +setalias(spec) + char *spec; +{ + register char *p; + register MAP *map; + char *class; + STAB *s; + + if (tTd(27, 8)) + printf("setalias(%s)\n", spec); + + for (p = spec; p != NULL; ) + { + char buf[50]; + + while (isspace(*p)) + p++; + if (*p == '\0') + break; + spec = p; + + if (NAliasFileMaps >= MAXMAPSTACK) + { + syserr("Too many alias databases defined, %d max", + MAXMAPSTACK); + return; + } + if (AliasFileMap == NULL) + { + strcpy(buf, "aliases.files sequence"); + AliasFileMap = makemapentry(buf); + if (AliasFileMap == NULL) + { + syserr("setalias: cannot create aliases.files map"); + return; + } + } + (void) sprintf(buf, "Alias%d", NAliasFileMaps); + s = stab(buf, ST_MAP, ST_ENTER); + map = &s->s_map; + bzero(map, sizeof *map); + map->map_mname = s->s_name; + + p = strpbrk(p, " ,/:"); + if (p != NULL && *p == ':') + { + /* map name */ + *p++ = '\0'; + class = spec; + spec = p; + } + else + { + class = "implicit"; + map->map_mflags = MF_OPTIONAL|MF_INCLNULL; + } + + /* find end of spec */ + if (p != NULL) + p = strchr(p, ','); + if (p != NULL) + *p++ = '\0'; + + if (tTd(27, 20)) + printf(" map %s:%s %s\n", class, s->s_name, spec); + + /* look up class */ + s = stab(class, ST_MAPCLASS, ST_FIND); + if (s == NULL) + { + if (tTd(27, 1)) + printf("Unknown alias class %s\n", class); + } + else if (!bitset(MCF_ALIASOK, s->s_mapclass.map_cflags)) + { + syserr("setalias: map class %s can't handle aliases", + class); + } + else + { + map->map_class = &s->s_mapclass; + if (map->map_class->map_parse(map, spec)) + { + map->map_mflags |= MF_VALID|MF_ALIAS; + AliasFileMap->map_stack[NAliasFileMaps++] = map; + } + } + } +} +/* +** ALIASWAIT -- wait for distinguished @:@ token to appear. +** +** This can decide to reopen or rebuild the alias file +** +** Parameters: +** map -- a pointer to the map descriptor for this alias file. +** ext -- the filename extension (e.g., ".db") for the +** database file. +** isopen -- if set, the database is already open, and we +** should check for validity; otherwise, we are +** just checking to see if it should be created. +** +** Returns: +** TRUE -- if the database is open when we return. +** FALSE -- if the database is closed when we return. +*/ + +bool +aliaswait(map, ext, isopen) + MAP *map; + char *ext; + int isopen; +{ + bool attimeout = FALSE; + time_t mtime; + struct stat stb; + char buf[MAXNAME + 1]; + + if (tTd(27, 3)) + printf("aliaswait(%s:%s)\n", + map->map_class->map_cname, map->map_file); + if (bitset(MF_ALIASWAIT, map->map_mflags)) + return isopen; + map->map_mflags |= MF_ALIASWAIT; + + if (SafeAlias > 0) + { + auto int st; + time_t toolong = curtime() + SafeAlias; + unsigned int sleeptime = 2; + + while (isopen && + map->map_class->map_lookup(map, "@", NULL, &st) == NULL) + { + if (curtime() > toolong) + { + /* we timed out */ + attimeout = TRUE; + break; + } + + /* + ** Close and re-open the alias database in case + ** the one is mv'ed instead of cp'ed in. + */ + + if (tTd(27, 2)) + printf("aliaswait: sleeping for %d seconds\n", + sleeptime); + + map->map_class->map_close(map); + map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); + sleep(sleeptime); + sleeptime *= 2; + if (sleeptime > 60) + sleeptime = 60; + isopen = map->map_class->map_open(map, O_RDONLY); + } + } + + /* see if we need to go into auto-rebuild mode */ + if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) + { + if (tTd(27, 3)) + printf("aliaswait: not rebuildable\n"); + map->map_mflags &= ~MF_ALIASWAIT; + return isopen; + } + if (stat(map->map_file, &stb) < 0) + { + if (tTd(27, 3)) + printf("aliaswait: no source file\n"); + map->map_mflags &= ~MF_ALIASWAIT; + return isopen; + } + mtime = stb.st_mtime; + (void) strcpy(buf, map->map_file); + if (ext != NULL) + (void) strcat(buf, ext); + if (stat(buf, &stb) < 0 || stb.st_mtime < mtime || attimeout) + { + /* database is out of date */ + if (AutoRebuild && stb.st_ino != 0 && stb.st_uid == geteuid()) + { + bool oldSuprErrs; + + message("auto-rebuilding alias database %s", buf); + oldSuprErrs = SuprErrs; + SuprErrs = TRUE; + if (isopen) + { + map->map_class->map_close(map); + map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); + } + rebuildaliases(map, TRUE); + isopen = map->map_class->map_open(map, O_RDONLY); + SuprErrs = oldSuprErrs; + } + else + { +#ifdef LOG + if (LogLevel > 3) + syslog(LOG_INFO, "alias database %s out of date", + buf); +#endif /* LOG */ + message("Warning: alias database %s out of date", buf); + } + } + map->map_mflags &= ~MF_ALIASWAIT; + return isopen; +} +/* +** REBUILDALIASES -- rebuild the alias database. +** +** Parameters: +** map -- the database to rebuild. +** automatic -- set if this was automatically generated. +** +** Returns: +** none. +** +** Side Effects: +** Reads the text version of the database, builds the +** DBM or DB version. +*/ + +void +rebuildaliases(map, automatic) + register MAP *map; + bool automatic; +{ + FILE *af; + bool nolock = FALSE; + sigfunc_t oldsigint, oldsigquit; +#ifdef SIGTSTP + sigfunc_t oldsigtstp; +#endif + + if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) + return; + + /* try to lock the source file */ + if ((af = fopen(map->map_file, "r+")) == NULL) + { + struct stat stb; + + if ((errno != EACCES && errno != EROFS) || automatic || + (af = fopen(map->map_file, "r")) == NULL) + { + int saveerr = errno; + + if (tTd(27, 1)) + printf("Can't open %s: %s\n", + map->map_file, errstring(saveerr)); + if (!automatic && !bitset(MF_OPTIONAL, map->map_mflags)) + message("newaliases: cannot open %s: %s", + map->map_file, errstring(saveerr)); + errno = 0; + return; + } + nolock = TRUE; + if (tTd(27, 1) || + fstat(fileno(af), &stb) < 0 || + bitset(S_IWUSR|S_IWGRP|S_IWOTH, stb.st_mode)) + message("warning: cannot lock %s: %s", + map->map_file, errstring(errno)); + } + + /* see if someone else is rebuilding the alias file */ + if (!nolock && + !lockfile(fileno(af), map->map_file, NULL, LOCK_EX|LOCK_NB)) + { + /* yes, they are -- wait until done */ + message("Alias file %s is already being rebuilt", + map->map_file); + if (OpMode != MD_INITALIAS) + { + /* wait for other rebuild to complete */ + (void) lockfile(fileno(af), map->map_file, NULL, + LOCK_EX); + } + (void) xfclose(af, "rebuildaliases1", map->map_file); + errno = 0; + return; + } + + /* avoid denial-of-service attacks */ + resetlimits(); + oldsigint = setsignal(SIGINT, SIG_IGN); + oldsigquit = setsignal(SIGQUIT, SIG_IGN); +#ifdef SIGTSTP + oldsigtstp = setsignal(SIGTSTP, SIG_IGN); +#endif + + if (map->map_class->map_open(map, O_RDWR)) + { +#ifdef LOG + if (LogLevel > 7) + { + syslog(LOG_NOTICE, "alias database %s %srebuilt by %s", + map->map_file, automatic ? "auto" : "", + username()); + } +#endif /* LOG */ + map->map_mflags |= MF_OPEN|MF_WRITABLE; + readaliases(map, af, !automatic, TRUE); + } + else + { + if (tTd(27, 1)) + printf("Can't create database for %s: %s\n", + map->map_file, errstring(errno)); + if (!automatic) + syserr("Cannot create database for alias file %s", + map->map_file); + } + + /* close the file, thus releasing locks */ + xfclose(af, "rebuildaliases2", map->map_file); + + /* add distinguished entries and close the database */ + if (bitset(MF_OPEN, map->map_mflags)) + { + map->map_class->map_close(map); + map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); + } + + /* restore the old signals */ + (void) setsignal(SIGINT, oldsigint); + (void) setsignal(SIGQUIT, oldsigquit); +#ifdef SIGTSTP + (void) setsignal(SIGTSTP, oldsigtstp); +#endif +} +/* +** READALIASES -- read and process the alias file. +** +** This routine implements the part of initaliases that occurs +** when we are not going to use the DBM stuff. +** +** Parameters: +** map -- the alias database descriptor. +** af -- file to read the aliases from. +** announcestats -- anounce statistics regarding number of +** aliases, longest alias, etc. +** logstats -- lot the same info. +** +** Returns: +** none. +** +** Side Effects: +** Reads aliasfile into the symbol table. +** Optionally, builds the .dir & .pag files. +*/ + +void +readaliases(map, af, announcestats, logstats) + register MAP *map; + FILE *af; + bool announcestats; + bool logstats; +{ + register char *p; + char *rhs; + bool skipping; + long naliases, bytes, longest; + ADDRESS al, bl; + char line[BUFSIZ]; + + /* + ** Read and interpret lines + */ + + FileName = map->map_file; + LineNumber = 0; + naliases = bytes = longest = 0; + skipping = FALSE; + while (fgets(line, sizeof (line), af) != NULL) + { + int lhssize, rhssize; + + LineNumber++; + p = strchr(line, '\n'); + if (p != NULL) + *p = '\0'; + switch (line[0]) + { + case '#': + case '\0': + skipping = FALSE; + continue; + + case ' ': + case '\t': + if (!skipping) + syserr("554 Non-continuation line starts with space"); + skipping = TRUE; + continue; + } + skipping = FALSE; + + /* + ** Process the LHS + ** Find the colon separator, and parse the address. + ** It should resolve to a local name -- this will + ** be checked later (we want to optionally do + ** parsing of the RHS first to maximize error + ** detection). + */ + + for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++) + continue; + if (*p++ != ':') + { + syserr("554 missing colon"); + continue; + } + if (parseaddr(line, &al, RF_COPYALL, ':', NULL, CurEnv) == NULL) + { + syserr("554 %.40s... illegal alias name", line); + continue; + } + + /* + ** Process the RHS. + ** 'al' is the internal form of the LHS address. + ** 'p' points to the text of the RHS. + */ + + while (isascii(*p) && isspace(*p)) + p++; + rhs = p; + for (;;) + { + register char c; + register char *nlp; + + nlp = &p[strlen(p)]; + if (nlp[-1] == '\n') + *--nlp = '\0'; + + if (CheckAliases) + { + /* do parsing & compression of addresses */ + while (*p != '\0') + { + auto char *delimptr; + + while ((isascii(*p) && isspace(*p)) || + *p == ',') + p++; + if (*p == '\0') + break; + if (parseaddr(p, &bl, RF_COPYNONE, ',', + &delimptr, CurEnv) == NULL) + usrerr("553 %s... bad address", p); + p = delimptr; + } + } + else + { + p = nlp; + } + + /* see if there should be a continuation line */ + c = getc(af); + if (!feof(af)) + (void) ungetc(c, af); + if (c != ' ' && c != '\t') + break; + + /* read continuation line */ + if (fgets(p, sizeof line - (p - line), af) == NULL) + break; + LineNumber++; + + /* check for line overflow */ + if (strchr(p, '\n') == NULL) + { + usrerr("554 alias too long"); + break; + } + } + if (!bitnset(M_ALIASABLE, al.q_mailer->m_flags)) + { + syserr("554 %s... cannot alias non-local names", + al.q_paddr); + continue; + } + + /* + ** Insert alias into symbol table or DBM file + */ + + if (!bitnset(M_USR_UPPER, al.q_mailer->m_flags)) + makelower(al.q_user); + + lhssize = strlen(al.q_user); + rhssize = strlen(rhs); + map->map_class->map_store(map, al.q_user, rhs); + + if (al.q_paddr != NULL) + free(al.q_paddr); + if (al.q_host != NULL) + free(al.q_host); + if (al.q_user != NULL) + free(al.q_user); + + /* statistics */ + naliases++; + bytes += lhssize + rhssize; + if (rhssize > longest) + longest = rhssize; + } + + CurEnv->e_to = NULL; + FileName = NULL; + if (Verbose || announcestats) + message("%s: %d aliases, longest %d bytes, %d bytes total", + map->map_file, naliases, longest, bytes); +# ifdef LOG + if (LogLevel > 7 && logstats) + syslog(LOG_INFO, "%s: %d aliases, longest %d bytes, %d bytes total", + map->map_file, naliases, longest, bytes); +# endif /* LOG */ +} +/* +** FORWARD -- Try to forward mail +** +** This is similar but not identical to aliasing. +** +** Parameters: +** user -- the name of the user who's mail we would like +** to forward to. It must have been verified -- +** i.e., the q_home field must have been filled +** in. +** sendq -- a pointer to the head of the send queue to +** put this user's aliases in. +** aliaslevel -- the current alias nesting depth. +** e -- the current envelope. +** +** Returns: +** none. +** +** Side Effects: +** New names are added to send queues. +*/ + +void +forward(user, sendq, aliaslevel, e) + ADDRESS *user; + ADDRESS **sendq; + int aliaslevel; + register ENVELOPE *e; +{ + char *pp; + char *ep; + + if (tTd(27, 1)) + printf("forward(%s)\n", user->q_paddr); + + if (!bitnset(M_HASPWENT, user->q_mailer->m_flags) || + bitset(QBADADDR, user->q_flags)) + return; + if (user->q_home == NULL) + { + syserr("554 forward: no home"); + user->q_home = "/nosuchdirectory"; + } + + /* good address -- look for .forward file in home */ + define('z', user->q_home, e); + define('u', user->q_user, e); + define('h', user->q_host, e); + if (ForwardPath == NULL) + ForwardPath = newstr("\201z/.forward"); + + for (pp = ForwardPath; pp != NULL; pp = ep) + { + int err; + char buf[MAXPATHLEN+1]; + extern int include(); + + ep = strchr(pp, ':'); + if (ep != NULL) + *ep = '\0'; + expand(pp, buf, sizeof buf, e); + if (ep != NULL) + *ep++ = ':'; + if (tTd(27, 3)) + printf("forward: trying %s\n", buf); + + err = include(buf, TRUE, user, sendq, aliaslevel, e); + if (err == 0) + break; + else if (transienterror(err)) + { + /* we have to suspend this message */ + if (tTd(27, 2)) + printf("forward: transient error on %s\n", buf); +#ifdef LOG + if (LogLevel > 2) + syslog(LOG_ERR, "%s: forward %s: transient error: %s", + e->e_id == NULL ? "NOQUEUE" : e->e_id, + buf, errstring(err)); +#endif + message("%s: %s: message queued", buf, errstring(err)); + user->q_flags |= QQUEUEUP; + return; + } + } +} diff --git a/usr.sbin/sendmail/src/arpadate.c b/usr.sbin/sendmail/src/arpadate.c new file mode 100644 index 000000000000..f6764704db07 --- /dev/null +++ b/usr.sbin/sendmail/src/arpadate.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)arpadate.c 8.4 (Berkeley) 4/21/95"; +#endif /* not lint */ + +# include "sendmail.h" + +/* +** ARPADATE -- Create date in ARPANET format +** +** Parameters: +** ud -- unix style date string. if NULL, one is created. +** +** Returns: +** pointer to an ARPANET date field +** +** Side Effects: +** none +** +** WARNING: +** date is stored in a local buffer -- subsequent +** calls will overwrite. +** +** Bugs: +** Timezone is computed from local time, rather than +** from whereever (and whenever) the message was sent. +** To do better is very hard. +** +** Some sites are now inserting the timezone into the +** local date. This routine should figure out what +** the format is and work appropriately. +*/ + +#ifndef TZNAME_MAX +# define TZNAME_MAX 50 /* max size of timezone */ +#endif + +/* values for TZ_TYPE */ +#define TZ_NONE 0 /* no character timezone support */ +#define TZ_TM_NAME 1 /* use tm->tm_name */ +#define TZ_TM_ZONE 2 /* use tm->tm_zone */ +#define TZ_TZNAME 3 /* use tzname[] */ +#define TZ_TIMEZONE 4 /* use timezone() */ + +char * +arpadate(ud) + register char *ud; +{ + register char *p; + register char *q; + register int off; + register int i; + register struct tm *lt; + time_t t; + struct tm gmt; + char *tz; + static char b[43 + TZNAME_MAX]; + + /* + ** Get current time. + ** This will be used if a null argument is passed and + ** to resolve the timezone. + */ + + (void) time(&t); + if (ud == NULL) + ud = ctime(&t); + + /* + ** Crack the UNIX date line in a singularly unoriginal way. + */ + + q = b; + + p = &ud[0]; /* Mon */ + *q++ = *p++; + *q++ = *p++; + *q++ = *p++; + *q++ = ','; + *q++ = ' '; + + p = &ud[8]; /* 16 */ + if (*p == ' ') + p++; + else + *q++ = *p++; + *q++ = *p++; + *q++ = ' '; + + p = &ud[4]; /* Sep */ + *q++ = *p++; + *q++ = *p++; + *q++ = *p++; + *q++ = ' '; + + p = &ud[20]; /* 1979 */ + *q++ = *p++; + *q++ = *p++; + *q++ = *p++; + *q++ = *p++; + *q++ = ' '; + + p = &ud[11]; /* 01:03:52 */ + for (i = 8; i > 0; i--) + *q++ = *p++; + + /* + * should really get the timezone from the time in "ud" (which + * is only different if a non-null arg was passed which is different + * from the current time), but for all practical purposes, returning + * the current local zone will do (its all that is ever needed). + */ + gmt = *gmtime(&t); + lt = localtime(&t); + + off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; + + /* assume that offset isn't more than a day ... */ + if (lt->tm_year < gmt.tm_year) + off -= 24 * 60; + else if (lt->tm_year > gmt.tm_year) + off += 24 * 60; + else if (lt->tm_yday < gmt.tm_yday) + off -= 24 * 60; + else if (lt->tm_yday > gmt.tm_yday) + off += 24 * 60; + + *q++ = ' '; + if (off == 0) + { + *q++ = 'G'; + *q++ = 'M'; + *q++ = 'T'; + } + else + { + tz = NULL; +#if TZ_TYPE == TZ_TM_NAME + tz = lt->tm_name; +#endif +#if TZ_TYPE == TZ_TM_ZONE + tz = lt->tm_zone; +#endif +#if TZ_TYPE == TZ_TZNAME + { + extern char *tzname[]; + + tz = tzname[lt->tm_isdst]; + } +#endif +#if TZ_TYPE == TZ_TIMEZONE + { + extern char *timezone(); + + tz = timezone(off, lt->tm_isdst); + } +#endif + if (off < 0) + { + off = -off; + *q++ = '-'; + } + else + *q++ = '+'; + + if (off >= 24*60) /* should be impossible */ + off = 23*60+59; /* if not, insert silly value */ + + *q++ = (off / 600) + '0'; + *q++ = (off / 60) % 10 + '0'; + off %= 60; + *q++ = (off / 10) + '0'; + *q++ = (off % 10) + '0'; + if (tz != NULL && *tz != '\0') + { + *q++ = ' '; + *q++ = '('; + while (*tz != '\0') + *q++ = *tz++; + *q++ = ')'; + } + } + *q = '\0'; + + return (b); +} diff --git a/usr.sbin/sendmail/src/clock.c b/usr.sbin/sendmail/src/clock.c new file mode 100644 index 000000000000..1490137170e2 --- /dev/null +++ b/usr.sbin/sendmail/src/clock.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)clock.c 8.12 (Berkeley) 5/23/95"; +#endif /* not lint */ + +# include "sendmail.h" + +# ifndef sigmask +# define sigmask(s) (1 << ((s) - 1)) +# endif + +/* +** SETEVENT -- set an event to happen at a specific time. +** +** Events are stored in a sorted list for fast processing. +** An event only applies to the process that set it. +** +** Parameters: +** intvl -- intvl until next event occurs. +** func -- function to call on event. +** arg -- argument to func on event. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +static void tick __P((int)); + +EVENT * +setevent(intvl, func, arg) + time_t intvl; + void (*func)(); + int arg; +{ + register EVENT **evp; + register EVENT *ev; + auto time_t now; + + if (intvl <= 0) + { + syserr("554 setevent: intvl=%ld\n", intvl); + return (NULL); + } + + (void) setsignal(SIGALRM, SIG_IGN); + (void) time(&now); + + /* search event queue for correct position */ + for (evp = &EventQueue; (ev = *evp) != NULL; evp = &ev->ev_link) + { + if (ev->ev_time >= now + intvl) + break; + } + + /* insert new event */ + ev = (EVENT *) xalloc(sizeof *ev); + ev->ev_time = now + intvl; + ev->ev_func = func; + ev->ev_arg = arg; + ev->ev_pid = getpid(); + ev->ev_link = *evp; + *evp = ev; + + if (tTd(5, 5)) + printf("setevent: intvl=%ld, for=%ld, func=%x, arg=%d, ev=%x\n", + intvl, now + intvl, func, arg, ev); + + tick(0); + return (ev); +} +/* +** CLREVENT -- remove an event from the event queue. +** +** Parameters: +** ev -- pointer to event to remove. +** +** Returns: +** none. +** +** Side Effects: +** arranges for event ev to not happen. +*/ + +void +clrevent(ev) + register EVENT *ev; +{ + register EVENT **evp; + + if (tTd(5, 5)) + printf("clrevent: ev=%x\n", ev); + if (ev == NULL) + return; + + /* find the parent event */ + (void) setsignal(SIGALRM, SIG_IGN); + for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link) + { + if (*evp == ev) + break; + } + + /* now remove it */ + if (*evp != NULL) + { + *evp = ev->ev_link; + free((char *) ev); + } + + /* restore clocks and pick up anything spare */ + tick(0); +} +/* +** TICK -- take a clock tick +** +** Called by the alarm clock. This routine runs events as needed. +** +** Parameters: +** One that is ignored; for compatibility with signal handlers. +** +** Returns: +** none. +** +** Side Effects: +** calls the next function in EventQueue. +*/ + +static void +tick(arg) + int arg; +{ + register time_t now; + register EVENT *ev; + int mypid = getpid(); + int olderrno = errno; +#ifdef SIG_UNBLOCK + sigset_t ss; +#endif + + (void) setsignal(SIGALRM, SIG_IGN); + (void) alarm(0); + now = curtime(); + + if (tTd(5, 4)) + printf("tick: now=%ld\n", now); + + while ((ev = EventQueue) != NULL && + (ev->ev_time <= now || ev->ev_pid != mypid)) + { + void (*f)(); + int arg; + int pid; + + /* process the event on the top of the queue */ + ev = EventQueue; + EventQueue = EventQueue->ev_link; + if (tTd(5, 6)) + printf("tick: ev=%x, func=%x, arg=%d, pid=%d\n", ev, + ev->ev_func, ev->ev_arg, ev->ev_pid); + + /* we must be careful in here because ev_func may not return */ + f = ev->ev_func; + arg = ev->ev_arg; + pid = ev->ev_pid; + free((char *) ev); + if (pid != getpid()) + continue; + if (EventQueue != NULL) + { + if (EventQueue->ev_time > now) + (void) alarm((unsigned) (EventQueue->ev_time - now)); + else + (void) alarm(3); + } + + /* restore signals so that we can take ticks while in ev_func */ + (void) setsignal(SIGALRM, tick); +#ifdef SIG_UNBLOCK + /* unblock SIGALRM signal */ + sigemptyset(&ss); + sigaddset(&ss, SIGALRM); + sigprocmask(SIG_UNBLOCK, &ss, NULL); +#else +#if HASSIGSETMASK + /* reset 4.2bsd signal mask to allow future alarms */ + (void) sigsetmask(sigblock(0) & ~sigmask(SIGALRM)); +#endif /* HASSIGSETMASK */ +#endif /* SIG_UNBLOCK */ + + /* call ev_func */ + errno = olderrno; + (*f)(arg); + (void) alarm(0); + now = curtime(); + } + (void) setsignal(SIGALRM, tick); + if (EventQueue != NULL) + (void) alarm((unsigned) (EventQueue->ev_time - now)); + errno = olderrno; +} +/* +** SLEEP -- a version of sleep that works with this stuff +** +** Because sleep uses the alarm facility, I must reimplement +** it here. +** +** Parameters: +** intvl -- time to sleep. +** +** Returns: +** none. +** +** Side Effects: +** waits for intvl time. However, other events can +** be run during that interval. +*/ + +static bool SleepDone; +static void endsleep(); + +#ifndef SLEEP_T +# define SLEEP_T unsigned int +#endif + +SLEEP_T +sleep(intvl) + unsigned int intvl; +{ + if (intvl == 0) + return (SLEEP_T) 0; + SleepDone = FALSE; + (void) setevent((time_t) intvl, endsleep, 0); + while (!SleepDone) + pause(); + return (SLEEP_T) 0; +} + +static void +endsleep() +{ + SleepDone = TRUE; +} diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c new file mode 100644 index 000000000000..7e43c5f5ffa2 --- /dev/null +++ b/usr.sbin/sendmail/src/collect.c @@ -0,0 +1,743 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)collect.c 8.49 (Berkeley) 10/29/95"; +#endif /* not lint */ + +# include <errno.h> +# include "sendmail.h" + +/* +** COLLECT -- read & parse message header & make temp file. +** +** Creates a temporary file name and copies the standard +** input to that file. Leading UNIX-style "From" lines are +** stripped off (after important information is extracted). +** +** Parameters: +** fp -- file to read. +** smtpmode -- if set, we are running SMTP: give an RFC821 +** style message to say we are ready to collect +** input, and never ignore a single dot to mean +** end of message. +** requeueflag -- this message will be requeued later, so +** don't do final processing on it. +** hdrp -- the location to stash the header. +** e -- the current envelope. +** +** Returns: +** none. +** +** Side Effects: +** Temp file is created and filled. +** The from person may be set. +*/ + +static jmp_buf CtxCollectTimeout; +static void collecttimeout(); +static bool CollectProgress; +static EVENT *CollectTimeout; + +/* values for input state machine */ +#define IS_NORM 0 /* middle of line */ +#define IS_BOL 1 /* beginning of line */ +#define IS_DOT 2 /* read a dot at beginning of line */ +#define IS_DOTCR 3 /* read ".\r" at beginning of line */ +#define IS_CR 4 /* read a carriage return */ + +/* values for message state machine */ +#define MS_UFROM 0 /* reading Unix from line */ +#define MS_HEADER 1 /* reading message header */ +#define MS_BODY 2 /* reading message body */ + +void +collect(fp, smtpmode, requeueflag, hdrp, e) + FILE *fp; + bool smtpmode; + bool requeueflag; + HDR **hdrp; + register ENVELOPE *e; +{ + register FILE *tf; + bool ignrdot = smtpmode ? FALSE : IgnrDot; + time_t dbto = smtpmode ? TimeOuts.to_datablock : 0; + register char *bp; + int c = '\0'; + bool inputerr = FALSE; + bool headeronly; + char *buf; + int buflen; + int istate; + int mstate; + char *pbp; + char peekbuf[8]; + char dfname[20]; + char bufbuf[MAXLINE]; + extern bool isheader(); + extern void eatheader(); + extern void tferror(); + + headeronly = hdrp != NULL; + + /* + ** Create the temp file name and create the file. + */ + + if (!headeronly) + { + struct stat stbuf; + + strcpy(dfname, queuename(e, 'd')); + if ((tf = dfopen(dfname, O_WRONLY|O_CREAT|O_TRUNC, FileMode)) == NULL) + { + syserr("Cannot create %s", dfname); + e->e_flags |= EF_NO_BODY_RETN; + finis(); + } + if (fstat(fileno(tf), &stbuf) < 0) + e->e_dfino = -1; + else + { + e->e_dfdev = stbuf.st_dev; + e->e_dfino = stbuf.st_ino; + } + HasEightBits = FALSE; + e->e_msgsize = 0; + e->e_flags |= EF_HAS_DF; + } + + /* + ** Tell ARPANET to go ahead. + */ + + if (smtpmode) + message("354 Enter mail, end with \".\" on a line by itself"); + + if (tTd(30, 2)) + printf("collect\n"); + + /* + ** Read the message. + ** + ** This is done using two interleaved state machines. + ** The input state machine is looking for things like + ** hidden dots; the message state machine is handling + ** the larger picture (e.g., header versus body). + */ + + buf = bp = bufbuf; + buflen = sizeof bufbuf; + pbp = peekbuf; + istate = IS_BOL; + mstate = SaveFrom ? MS_HEADER : MS_UFROM; + CollectProgress = FALSE; + + if (dbto != 0) + { + /* handle possible input timeout */ + if (setjmp(CtxCollectTimeout) != 0) + { +#ifdef LOG + syslog(LOG_NOTICE, + "timeout waiting for input from %s during message collect", + CurHostName ? CurHostName : "<local machine>"); +#endif + errno = 0; + usrerr("451 timeout waiting for input during message collect"); + goto readerr; + } + CollectTimeout = setevent(dbto, collecttimeout, dbto); + } + + for (;;) + { + if (tTd(30, 35)) + printf("top, istate=%d, mstate=%d\n", istate, mstate); + for (;;) + { + if (pbp > peekbuf) + c = *--pbp; + else + { + while (!feof(fp) && !ferror(fp)) + { + errno = 0; + c = getc(fp); + if (errno != EINTR) + break; + clearerr(fp); + } + CollectProgress = TRUE; + if (TrafficLogFile != NULL && !headeronly) + { + if (istate == IS_BOL) + fprintf(TrafficLogFile, "%05d <<< ", + getpid()); + if (c == EOF) + fprintf(TrafficLogFile, "[EOF]\n"); + else + putc(c, TrafficLogFile); + } + if (c == EOF) + goto readerr; + if (SevenBitInput) + c &= 0x7f; + else + HasEightBits |= bitset(0x80, c); + if (!headeronly) + e->e_msgsize++; + } + if (tTd(30, 94)) + printf("istate=%d, c=%c (0x%x)\n", + istate, c, c); + switch (istate) + { + case IS_BOL: + if (c == '.') + { + istate = IS_DOT; + continue; + } + break; + + case IS_DOT: + if (c == '\n' && !ignrdot && + !bitset(EF_NL_NOT_EOL, e->e_flags)) + goto readerr; + else if (c == '\r' && + !bitset(EF_CRLF_NOT_EOL, e->e_flags)) + { + istate = IS_DOTCR; + continue; + } + else if (c != '.' || + (OpMode != MD_SMTP && + OpMode != MD_DAEMON && + OpMode != MD_ARPAFTP)) + { + *pbp++ = c; + c = '.'; + } + break; + + case IS_DOTCR: + if (c == '\n') + goto readerr; + else + { + /* push back the ".\rx" */ + *pbp++ = c; + *pbp++ = '\r'; + c = '.'; + } + break; + + case IS_CR: + if (c == '\n') + istate = IS_BOL; + else + { + ungetc(c, fp); + c = '\r'; + istate = IS_NORM; + } + goto bufferchar; + } + + if (c == '\r' && !bitset(EF_CRLF_NOT_EOL, e->e_flags)) + { + istate = IS_CR; + continue; + } + else if (c == '\n' && !bitset(EF_NL_NOT_EOL, e->e_flags)) + istate = IS_BOL; + else + istate = IS_NORM; + +bufferchar: + if (mstate == MS_BODY) + { + /* just put the character out */ + if (MaxMessageSize <= 0 || + e->e_msgsize <= MaxMessageSize) + putc(c, tf); + continue; + } + + /* header -- buffer up */ + if (bp >= &buf[buflen - 2]) + { + char *obuf; + + if (mstate != MS_HEADER) + break; + + /* out of space for header */ + obuf = buf; + if (buflen < MEMCHUNKSIZE) + buflen *= 2; + else + buflen += MEMCHUNKSIZE; + buf = xalloc(buflen); + bcopy(obuf, buf, bp - obuf); + bp = &buf[bp - obuf]; + if (obuf != bufbuf) + free(obuf); + } + if (c != '\0') + *bp++ = c; + if (istate == IS_BOL) + break; + } + *bp = '\0'; + +nextstate: + if (tTd(30, 35)) + printf("nextstate, istate=%d, mstate=%d, line = \"%s\"\n", + istate, mstate, buf); + switch (mstate) + { + extern int chompheader(); + + case MS_UFROM: + mstate = MS_HEADER; +#ifndef NOTUNIX + if (strncmp(buf, "From ", 5) == 0) + { + extern void eatfrom(); + + bp = buf; + eatfrom(buf, e); + continue; + } +#endif + /* fall through */ + + case MS_HEADER: + if (!isheader(buf)) + { + mstate = MS_BODY; + goto nextstate; + } + + /* check for possible continuation line */ + do + { + clearerr(fp); + errno = 0; + c = getc(fp); + } while (errno == EINTR); + if (c != EOF) + ungetc(c, fp); + if (c == ' ' || c == '\t') + { + /* yep -- defer this */ + continue; + } + + /* trim off trailing CRLF or NL */ + if (*--bp != '\n' || *--bp != '\r') + bp++; + *bp = '\0'; + if (bitset(H_EOH, chompheader(buf, FALSE, hdrp, e))) + mstate = MS_BODY; + break; + + case MS_BODY: + if (tTd(30, 1)) + printf("EOH\n"); + if (headeronly) + goto readerr; + bp = buf; + + /* toss blank line */ + if ((!bitset(EF_CRLF_NOT_EOL, e->e_flags) && + bp[0] == '\r' && bp[1] == '\n') || + (!bitset(EF_NL_NOT_EOL, e->e_flags) && + bp[0] == '\n')) + { + break; + } + + /* if not a blank separator, write it out */ + if (MaxMessageSize <= 0 || + e->e_msgsize <= MaxMessageSize) + { + while (*bp != '\0') + putc(*bp++, tf); + } + break; + } + bp = buf; + } + +readerr: + if ((feof(fp) && smtpmode) || ferror(fp)) + { + const char *errmsg = errstring(errno); + + if (tTd(30, 1)) + printf("collect: premature EOM: %s\n", errmsg); +#ifdef LOG + if (LogLevel >= 2) + syslog(LOG_WARNING, "collect: premature EOM: %s", errmsg); +#endif + inputerr = TRUE; + } + + /* reset global timer */ + clrevent(CollectTimeout); + + if (headeronly) + return; + + if (tf != NULL && + (fflush(tf) != 0 || ferror(tf) || fsync(fileno(tf)) < 0 || + fclose(tf) < 0)) + { + tferror(tf, e); + flush_errors(TRUE); + finis(); + } + + /* An EOF when running SMTP is an error */ + if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON)) + { + char *host; + char *problem; + + host = RealHostName; + if (host == NULL) + host = "localhost"; + + if (feof(fp)) + problem = "unexpected close"; + else if (ferror(fp)) + problem = "I/O error"; + else + problem = "read timeout"; +# ifdef LOG + if (LogLevel > 0 && feof(fp)) + syslog(LOG_NOTICE, + "collect: %s on connection from %.100s, sender=%s: %s", + problem, host, + shortenstring(e->e_from.q_paddr, 203), + errstring(errno)); +# endif + if (feof(fp)) + usrerr("451 collect: %s on connection from %s, from=%s", + problem, host, + shortenstring(e->e_from.q_paddr, 203)); + else + syserr("451 collect: %s on connection from %s, from=%s", + problem, host, + shortenstring(e->e_from.q_paddr, 203)); + + /* don't return an error indication */ + e->e_to = NULL; + e->e_flags &= ~EF_FATALERRS; + e->e_flags |= EF_CLRQUEUE; + + /* and don't try to deliver the partial message either */ + if (InChild) + ExitStat = EX_QUIT; + finis(); + } + + /* + ** Find out some information from the headers. + ** Examples are who is the from person & the date. + */ + + eatheader(e, !requeueflag); + + if (GrabTo && e->e_sendqueue == NULL) + usrerr("No recipient addresses found in header"); + + /* collect statistics */ + if (OpMode != MD_VERIFY) + { + extern void markstats(); + + markstats(e, (ADDRESS *) NULL); + } + + /* + ** Add an Apparently-To: line if we have no recipient lines. + */ + + if (hvalue("to", e->e_header) != NULL || + hvalue("cc", e->e_header) != NULL || + hvalue("apparently-to", e->e_header) != NULL) + { + /* have a valid recipient header -- delete Bcc: headers */ + e->e_flags |= EF_DELETE_BCC; + } + else if (hvalue("bcc", e->e_header) == NULL) + { + /* no valid recipient headers */ + register ADDRESS *q; + char *hdr = NULL; + extern void addheader(); + + /* create an Apparently-To: field */ + /* that or reject the message.... */ + switch (NoRecipientAction) + { + case NRA_ADD_APPARENTLY_TO: + hdr = "Apparently-To"; + break; + + case NRA_ADD_TO: + hdr = "To"; + break; + + case NRA_ADD_BCC: + addheader("Bcc", "", &e->e_header); + break; + + case NRA_ADD_TO_UNDISCLOSED: + addheader("To", "undisclosed-recipients:;", &e->e_header); + break; + } + + if (hdr != NULL) + { + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (q->q_alias != NULL) + continue; + if (tTd(30, 3)) + printf("Adding %s: %s\n", + hdr, q->q_paddr); + addheader(hdr, q->q_paddr, &e->e_header); + } + } + } + + /* check for message too large */ + if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize) + { + e->e_status = "5.2.3"; + usrerr("552 Message exceeds maximum fixed size (%ld)", + MaxMessageSize); +# ifdef LOG + if (LogLevel > 6) + syslog(LOG_NOTICE, "%s: message size (%ld) exceeds maximum (%ld)", + e->e_id, e->e_msgsize, MaxMessageSize); +# endif + } + + /* check for illegal 8-bit data */ + if (HasEightBits) + { + e->e_flags |= EF_HAS8BIT; + if (!bitset(MM_PASS8BIT|MM_MIME8BIT, MimeMode)) + { + e->e_status = "5.6.1"; + usrerr("554 Eight bit data not allowed"); + } + } + else + { + /* if it claimed to be 8 bits, well, it lied.... */ + if (e->e_bodytype != NULL && + strcasecmp(e->e_bodytype, "8BITMIME") == 0) + e->e_bodytype = "7BIT"; + } + + if ((e->e_dfp = fopen(dfname, "r")) == NULL) + { + /* we haven't acked receipt yet, so just chuck this */ + syserr("Cannot reopen %s", dfname); + finis(); + } +} + + +static void +collecttimeout(timeout) + time_t timeout; +{ + /* if no progress was made, die now */ + if (!CollectProgress) + longjmp(CtxCollectTimeout, 1); + + /* otherwise reset the timeout */ + CollectTimeout = setevent(timeout, collecttimeout, timeout); + CollectProgress = FALSE; +} +/* +** TFERROR -- signal error on writing the temporary file. +** +** Parameters: +** tf -- the file pointer for the temporary file. +** e -- the current envelope. +** +** Returns: +** none. +** +** Side Effects: +** Gives an error message. +** Arranges for following output to go elsewhere. +*/ + +void +tferror(tf, e) + FILE *tf; + register ENVELOPE *e; +{ + setstat(EX_IOERR); + if (errno == ENOSPC) + { + struct stat st; + long avail; + long bsize; + + e->e_flags |= EF_NO_BODY_RETN; + if (fstat(fileno(tf), &st) < 0) + st.st_size = 0; + (void) freopen(queuename(e, 'd'), "w", tf); + if (st.st_size <= 0) + fprintf(tf, "\n*** Mail could not be accepted"); + else if (sizeof st.st_size > sizeof (long)) + fprintf(tf, "\n*** Mail of at least %qd bytes could not be accepted\n", + st.st_size); + else + fprintf(tf, "\n*** Mail of at least %ld bytes could not be accepted\n", + st.st_size); + fprintf(tf, "*** at %s due to lack of disk space for temp file.\n", + MyHostName); + avail = freediskspace(QueueDir, &bsize); + if (avail > 0) + { + if (bsize > 1024) + avail *= bsize / 1024; + else if (bsize < 1024) + avail /= 1024 / bsize; + fprintf(tf, "*** Currently, %ld kilobytes are available for mail temp files.\n", + avail); + } + e->e_status = "4.3.1"; + usrerr("452 Out of disk space for temp file"); + } + else + syserr("collect: Cannot write tf%s", e->e_id); + (void) freopen("/dev/null", "w", tf); +} +/* +** EATFROM -- chew up a UNIX style from line and process +** +** This does indeed make some assumptions about the format +** of UNIX messages. +** +** Parameters: +** fm -- the from line. +** +** Returns: +** none. +** +** Side Effects: +** extracts what information it can from the header, +** such as the date. +*/ + +# ifndef NOTUNIX + +char *DowList[] = +{ + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL +}; + +char *MonthList[] = +{ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + NULL +}; + +void +eatfrom(fm, e) + char *fm; + register ENVELOPE *e; +{ + register char *p; + register char **dt; + + if (tTd(30, 2)) + printf("eatfrom(%s)\n", fm); + + /* find the date part */ + p = fm; + while (*p != '\0') + { + /* skip a word */ + while (*p != '\0' && *p != ' ') + p++; + while (*p == ' ') + p++; + if (!(isascii(*p) && isupper(*p)) || + p[3] != ' ' || p[13] != ':' || p[16] != ':') + continue; + + /* we have a possible date */ + for (dt = DowList; *dt != NULL; dt++) + if (strncmp(*dt, p, 3) == 0) + break; + if (*dt == NULL) + continue; + + for (dt = MonthList; *dt != NULL; dt++) + if (strncmp(*dt, &p[4], 3) == 0) + break; + if (*dt != NULL) + break; + } + + if (*p != '\0') + { + char *q; + extern char *arpadate(); + + /* we have found a date */ + q = xalloc(25); + (void) strncpy(q, p, 25); + q[24] = '\0'; + q = arpadate(q); + define('a', newstr(q), e); + } +} + +# endif /* NOTUNIX */ diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c new file mode 100644 index 000000000000..ab6db9310027 --- /dev/null +++ b/usr.sbin/sendmail/src/conf.c @@ -0,0 +1,3755 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)conf.c 8.243 (Berkeley) 11/20/95"; +#endif /* not lint */ + +# include "sendmail.h" +# include "pathnames.h" +# include <sys/ioctl.h> +# include <sys/param.h> + +/* +** CONF.C -- Sendmail Configuration Tables. +** +** Defines the configuration of this installation. +** +** Configuration Variables: +** HdrInfo -- a table describing well-known header fields. +** Each entry has the field name and some flags, +** which are described in sendmail.h. +** +** Notes: +** I have tried to put almost all the reasonable +** configuration information into the configuration +** file read at runtime. My intent is that anything +** here is a function of the version of UNIX you +** are running, or is really static -- for example +** the headers are a superset of widely used +** protocols. If you find yourself playing with +** this file too much, you may be making a mistake! +*/ + + + + +/* +** Header info table +** Final (null) entry contains the flags used for any other field. +** +** Not all of these are actually handled specially by sendmail +** at this time. They are included as placeholders, to let +** you know that "someday" I intend to have sendmail do +** something with them. +*/ + +struct hdrinfo HdrInfo[] = +{ + /* originator fields, most to least significant */ + "resent-sender", H_FROM|H_RESENT, + "resent-from", H_FROM|H_RESENT, + "resent-reply-to", H_FROM|H_RESENT, + "sender", H_FROM, + "from", H_FROM, + "reply-to", H_FROM, + "full-name", H_ACHECK, + "return-receipt-to", H_FROM|H_RECEIPTTO, + "errors-to", H_FROM|H_ERRORSTO, + + /* destination fields */ + "to", H_RCPT, + "resent-to", H_RCPT|H_RESENT, + "cc", H_RCPT, + "resent-cc", H_RCPT|H_RESENT, + "bcc", H_RCPT|H_BCC, + "resent-bcc", H_RCPT|H_BCC|H_RESENT, + "apparently-to", H_RCPT, + + /* message identification and control */ + "message-id", 0, + "resent-message-id", H_RESENT, + "message", H_EOH, + "text", H_EOH, + + /* date fields */ + "date", 0, + "resent-date", H_RESENT, + + /* trace fields */ + "received", H_TRACE|H_FORCE, + "x400-received", H_TRACE|H_FORCE, + "via", H_TRACE|H_FORCE, + "mail-from", H_TRACE|H_FORCE, + + /* miscellaneous fields */ + "comments", H_FORCE, + "return-path", H_FORCE|H_ACHECK, + "content-transfer-encoding", H_CTE, + "content-type", H_CTYPE, + "content-length", H_ACHECK, + + NULL, 0, +}; + + + +/* +** Location of system files/databases/etc. +*/ + +char *PidFile = _PATH_SENDMAILPID; /* stores daemon proc id */ + + + +/* +** Privacy values +*/ + +struct prival PrivacyValues[] = +{ + "public", PRIV_PUBLIC, + "needmailhelo", PRIV_NEEDMAILHELO, + "needexpnhelo", PRIV_NEEDEXPNHELO, + "needvrfyhelo", PRIV_NEEDVRFYHELO, + "noexpn", PRIV_NOEXPN, + "novrfy", PRIV_NOVRFY, + "restrictmailq", PRIV_RESTRICTMAILQ, + "restrictqrun", PRIV_RESTRICTQRUN, + "authwarnings", PRIV_AUTHWARNINGS, + "noreceipts", PRIV_NORECEIPTS, + "goaway", PRIV_GOAWAY, + NULL, 0, +}; + + + +/* +** Miscellaneous stuff. +*/ + +int DtableSize = 50; /* max open files; reset in 4.2bsd */ +/* +** SETDEFAULTS -- set default values +** +** Because of the way freezing is done, these must be initialized +** using direct code. +** +** Parameters: +** e -- the default envelope. +** +** Returns: +** none. +** +** Side Effects: +** Initializes a bunch of global variables to their +** default values. +*/ + +#define MINUTES * 60 +#define HOURS * 60 MINUTES +#define DAYS * 24 HOURS + +#ifndef MAXRULERECURSION +# define MAXRULERECURSION 50 /* max ruleset recursion depth */ +#endif + +void +setdefaults(e) + register ENVELOPE *e; +{ + int i; + extern void inittimeouts(); + extern void setdefuser(); + extern void setupmaps(); + extern void setupmailers(); + + SpaceSub = ' '; /* option B */ + QueueLA = 8; /* option x */ + RefuseLA = 12; /* option X */ + WkRecipFact = 30000L; /* option y */ + WkClassFact = 1800L; /* option z */ + WkTimeFact = 90000L; /* option Z */ + QueueFactor = WkRecipFact * 20; /* option q */ + FileMode = (RealUid != geteuid()) ? 0644 : 0600; + /* option F */ + DefUid = 1; /* option u */ + DefGid = 1; /* option g */ + CheckpointInterval = 10; /* option C */ + MaxHopCount = 25; /* option h */ + e->e_sendmode = SM_FORK; /* option d */ + e->e_errormode = EM_PRINT; /* option e */ + SevenBitInput = FALSE; /* option 7 */ + MaxMciCache = 1; /* option k */ + MciCacheTimeout = 5 MINUTES; /* option K */ + LogLevel = 9; /* option L */ + inittimeouts(NULL); /* option r */ + PrivacyFlags = 0; /* option p */ +#if MIME8TO7 + MimeMode = MM_CVTMIME|MM_PASS8BIT; /* option 8 */ +#else + MimeMode = MM_PASS8BIT; +#endif + for (i = 0; i < MAXTOCLASS; i++) + { + TimeOuts.to_q_return[i] = 5 DAYS; /* option T */ + TimeOuts.to_q_warning[i] = 0; /* option T */ + } + ServiceSwitchFile = "/etc/service.switch"; + HostsFile = _PATH_HOSTS; + MustQuoteChars = "@,;:\\()[].'"; + MciInfoTimeout = 30 MINUTES; + MaxRuleRecursion = MAXRULERECURSION; + MaxAliasRecursion = 10; + ColonOkInAddr = TRUE; + setdefuser(); + setupmaps(); + setupmailers(); +} + + +/* +** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups()) +*/ + +void +setdefuser() +{ + struct passwd *defpwent; + static char defuserbuf[40]; + + DefUser = defuserbuf; + if ((defpwent = sm_getpwuid(DefUid)) != NULL) + strcpy(defuserbuf, defpwent->pw_name); + else + strcpy(defuserbuf, "nobody"); +} +/* +** HOST_MAP_INIT -- initialize host class structures +*/ + +bool host_map_init __P((MAP *map, char *args)); + +bool +host_map_init(map, args) + MAP *map; + char *args; +{ + register char *p = args; + + for (;;) + { + while (isascii(*p) && isspace(*p)) + p++; + if (*p != '-') + break; + switch (*++p) + { + case 'a': + map->map_app = ++p; + break; + } + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + } + if (map->map_app != NULL) + map->map_app = newstr(map->map_app); + return TRUE; +} +/* +** SETUPMAILERS -- initialize default mailers +*/ + +void +setupmailers() +{ + char buf[100]; + extern void makemailer(); + + strcpy(buf, "prog, P=/bin/sh, F=lsoD, T=DNS/RFC822/X-Unix, A=sh -c \201u"); + makemailer(buf); + + strcpy(buf, "*file*, P=[FILE], F=lsDFMPEou, T=DNS/RFC822/X-Unix, A=FILE"); + makemailer(buf); + + strcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE"); + makemailer(buf); +} +/* +** SETUPMAPS -- set up map classes +*/ + +#define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \ + { \ + extern bool parse __P((MAP *, char *)); \ + extern bool open __P((MAP *, int)); \ + extern void close __P((MAP *)); \ + extern char *lookup __P((MAP *, char *, char **, int *)); \ + extern void store __P((MAP *, char *, char *)); \ + s = stab(name, ST_MAPCLASS, ST_ENTER); \ + s->s_mapclass.map_cname = name; \ + s->s_mapclass.map_ext = ext; \ + s->s_mapclass.map_cflags = flags; \ + s->s_mapclass.map_parse = parse; \ + s->s_mapclass.map_open = open; \ + s->s_mapclass.map_close = close; \ + s->s_mapclass.map_lookup = lookup; \ + s->s_mapclass.map_store = store; \ + } + +void +setupmaps() +{ + register STAB *s; + +#ifdef NEWDB + MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE, + map_parseargs, hash_map_open, db_map_close, + db_map_lookup, db_map_store); + + MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE, + map_parseargs, bt_map_open, db_map_close, + db_map_lookup, db_map_store); +#endif + +#ifdef NDBM + MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE, + map_parseargs, ndbm_map_open, ndbm_map_close, + ndbm_map_lookup, ndbm_map_store); +#endif + +#ifdef NIS + MAPDEF("nis", NULL, MCF_ALIASOK, + map_parseargs, nis_map_open, null_map_close, + nis_map_lookup, null_map_store); +#endif + +#ifdef NISPLUS + MAPDEF("nisplus", NULL, MCF_ALIASOK, + map_parseargs, nisplus_map_open, null_map_close, + nisplus_map_lookup, null_map_store); +#endif + +#ifdef HESIOD + MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY, + map_parseargs, hes_map_open, null_map_close, + hes_map_lookup, null_map_store); +#endif + +#if NETINFO + MAPDEF("netinfo", NULL, MCF_ALIASOK, + map_parseargs, ni_map_open, null_map_close, + ni_map_lookup, null_map_store); +#endif + +#if 0 + MAPDEF("dns", NULL, 0, + dns_map_init, null_map_open, null_map_close, + dns_map_lookup, null_map_store); +#endif + +#if NAMED_BIND + /* best MX DNS lookup */ + MAPDEF("bestmx", NULL, MCF_OPTFILE, + map_parseargs, null_map_open, null_map_close, + bestmx_map_lookup, null_map_store); +#endif + + MAPDEF("host", NULL, 0, + host_map_init, null_map_open, null_map_close, + host_map_lookup, null_map_store); + + MAPDEF("text", NULL, MCF_ALIASOK, + map_parseargs, text_map_open, null_map_close, + text_map_lookup, null_map_store); + + MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY, + map_parseargs, stab_map_open, null_map_close, + stab_map_lookup, stab_map_store); + + MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE, + map_parseargs, impl_map_open, impl_map_close, + impl_map_lookup, impl_map_store); + + /* access to system passwd file */ + MAPDEF("user", NULL, MCF_OPTFILE, + map_parseargs, user_map_open, null_map_close, + user_map_lookup, null_map_store); + + /* dequote map */ + MAPDEF("dequote", NULL, 0, + dequote_init, null_map_open, null_map_close, + dequote_map, null_map_store); + +#if USERDB + /* user database */ + MAPDEF("userdb", ".db", 0, + map_parseargs, null_map_open, null_map_close, + udb_map_lookup, null_map_store); +#endif + + /* arbitrary programs */ + MAPDEF("program", NULL, MCF_ALIASOK, + map_parseargs, null_map_open, null_map_close, + prog_map_lookup, null_map_store); + + /* sequenced maps */ + MAPDEF("sequence", NULL, MCF_ALIASOK, + seq_map_parse, null_map_open, null_map_close, + seq_map_lookup, seq_map_store); + + /* switched interface to sequenced maps */ + MAPDEF("switch", NULL, MCF_ALIASOK, + map_parseargs, switch_map_open, null_map_close, + seq_map_lookup, seq_map_store); + + /* null map lookup -- really for internal use only */ + MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE, + map_parseargs, null_map_open, null_map_close, + null_map_lookup, null_map_store); +} + +#undef MAPDEF +/* +** INITHOSTMAPS -- initial host-dependent maps +** +** This should act as an interface to any local service switch +** provided by the host operating system. +** +** Parameters: +** none +** +** Returns: +** none +** +** Side Effects: +** Should define maps "host" and "users" as necessary +** for this OS. If they are not defined, they will get +** a default value later. It should check to make sure +** they are not defined first, since it's possible that +** the config file has provided an override. +*/ + +void +inithostmaps() +{ + register int i; + int nmaps; + char *maptype[MAXMAPSTACK]; + short mapreturn[MAXMAPACTIONS]; + char buf[MAXLINE]; + + /* + ** Set up default hosts maps. + */ + +#if 0 + nmaps = switch_map_find("hosts", maptype, mapreturn); + for (i = 0; i < nmaps; i++) + { + if (strcmp(maptype[i], "files") == 0 && + stab("hosts.files", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts"); + (void) makemapentry(buf); + } +#if NAMED_BIND + else if (strcmp(maptype[i], "dns") == 0 && + stab("hosts.dns", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "hosts.dns dns A"); + (void) makemapentry(buf); + } +#endif +#ifdef NISPLUS + else if (strcmp(maptype[i], "nisplus") == 0 && + stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "hosts.nisplus nisplus -k name -v address -d hosts.org_dir"); + (void) makemapentry(buf); + } +#endif +#ifdef NIS + else if (strcmp(maptype[i], "nis") == 0 && + stab("hosts.nis", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "hosts.nis nis -d -k 0 -v 1 hosts.byname"); + (void) makemapentry(buf); + } +#endif +#if NETINFO + else if (strcmp(maptype[i], "netinfo") == 0) && + stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "hosts.netinfo netinfo -v name /machines"); + (void) makemapentry(buf); + } +#endif + } +#endif + + /* + ** Make sure we have a host map. + */ + + if (stab("host", ST_MAP, ST_FIND) == NULL) + { + /* user didn't initialize: set up host map */ + strcpy(buf, "host host"); +#if NAMED_BIND + if (ConfigLevel >= 2) + strcat(buf, " -a."); +#endif + (void) makemapentry(buf); + } + + /* + ** Set up default aliases maps + */ + + nmaps = switch_map_find("aliases", maptype, mapreturn); + for (i = 0; i < nmaps; i++) + { + if (strcmp(maptype[i], "files") == 0 && + stab("aliases.files", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "aliases.files null"); + (void) makemapentry(buf); + } +#ifdef NISPLUS + else if (strcmp(maptype[i], "nisplus") == 0 && + stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion -d mail_aliases.org_dir"); + (void) makemapentry(buf); + } +#endif +#ifdef NIS + else if (strcmp(maptype[i], "nis") == 0 && + stab("aliases.nis", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "aliases.nis nis -d mail.aliases"); + (void) makemapentry(buf); + } +#endif +#ifdef NETINFO + else if (strcmp(maptype[i], "netinfo") == 0 && + stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "aliases.netinfo netinfo /aliases"); + (void) makemapentry(buf); + } +#endif +#ifdef HESIOD + else if (strcmp(maptype[i], "hesiod") == 0 && + stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "aliases.hesiod hesiod aliases"); + (void) makemapentry(buf); + } +#endif + } + if (stab("aliases", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "aliases switch aliases"); + (void) makemapentry(buf); + } + +#if 0 /* "user" map class is a better choice */ + /* + ** Set up default users maps. + */ + + nmaps = switch_map_find("passwd", maptype, mapreturn); + for (i = 0; i < nmaps; i++) + { + if (strcmp(maptype[i], "files") == 0 && + stab("users.files", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd"); + (void) makemapentry(buf); + } +#ifdef NISPLUS + else if (strcmp(maptype[i], "nisplus") == 0 && + stab("users.nisplus", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "users.nisplus nisplus -m -kname -vhome -d passwd.org_dir"); + (void) makemapentry(buf); + } +#endif +#ifdef NIS + else if (strcmp(maptype[i], "nis") == 0 && + stab("users.nis", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "users.nis nis -m -d passwd.byname"); + (void) makemapentry(buf); + } +#endif +#ifdef HESIOD + else if (strcmp(maptype[i], "hesiod") == 0) && + stab("users.hesiod", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "users.hesiod hesiod"); + (void) makemapentry(buf); + } +#endif + } + if (stab("users", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "users switch -m passwd"); + (void) makemapentry(buf); + } +#endif +} +/* +** SWITCH_MAP_FIND -- find the list of types associated with a map +** +** This is the system-dependent interface to the service switch. +** +** Parameters: +** service -- the name of the service of interest. +** maptype -- an out-array of strings containing the types +** of access to use for this service. There can +** be at most MAXMAPSTACK types for a single service. +** mapreturn -- an out-array of return information bitmaps +** for the map. +** +** Returns: +** The number of map types filled in, or -1 for failure. +*/ + +#if defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) +# define _USE_SUN_NSSWITCH_ +#endif + +#ifdef _USE_SUN_NSSWITCH_ +# include <nsswitch.h> +#endif + +#if defined(ultrix) || (defined(__osf__) && defined(__alpha)) +# define _USE_DEC_SVC_CONF_ +#endif + +#ifdef _USE_DEC_SVC_CONF_ +# include <sys/svcinfo.h> +#endif + +int +switch_map_find(service, maptype, mapreturn) + char *service; + char *maptype[MAXMAPSTACK]; + short mapreturn[MAXMAPACTIONS]; +{ + register FILE *fp; + int svcno; + static char buf[MAXLINE]; + +#ifdef _USE_SUN_NSSWITCH_ + struct __nsw_switchconfig *nsw_conf; + enum __nsw_parse_err pserr; + struct __nsw_lookup *lk; + int nsw_rc; + static struct __nsw_lookup lkp0 = + { "files", {1, 0, 0, 0}, NULL, NULL }; + static struct __nsw_switchconfig lkp_default = + { 0, "sendmail", 3, &lkp0 }; + + for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) + mapreturn[svcno] = 0; + + if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL) + lk = lkp_default.lookups; + else + lk = nsw_conf->lookups; + svcno = 0; + while (lk != NULL) + { + maptype[svcno] = lk->service_name; + if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN) + mapreturn[MA_NOTFOUND] |= 1 << svcno; + if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN) + mapreturn[MA_TRYAGAIN] |= 1 << svcno; + if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN) + mapreturn[MA_TRYAGAIN] |= 1 << svcno; + svcno++; + lk = lk->next; + } + return svcno; +#endif + +#ifdef _USE_DEC_SVC_CONF_ + struct svcinfo *svcinfo; + int svc; + + for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) + mapreturn[svcno] = 0; + + svcinfo = getsvc(); + if (svcinfo == NULL) + goto punt; + if (strcmp(service, "hosts") == 0) + svc = SVC_HOSTS; + else if (strcmp(service, "aliases") == 0) + svc = SVC_ALIASES; + else if (strcmp(service, "passwd") == 0) + svc = SVC_PASSWD; + else + return -1; + for (svcno = 0; svcno < SVC_PATHSIZE; svcno++) + { + switch (svcinfo->svcpath[svc][svcno]) + { + case SVC_LOCAL: + maptype[svcno] = "files"; + break; + + case SVC_YP: + maptype[svcno] = "nis"; + break; + + case SVC_BIND: + maptype[svcno] = "dns"; + break; + +#ifdef SVC_HESIOD + case SVC_HESIOD: + maptype[svcno] = "hesiod"; + break; +#endif + + case SVC_LAST: + return svcno; + } + } + return svcno; +#endif + +#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) + /* + ** Fall-back mechanism. + */ + + for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) + mapreturn[svcno] = 0; + + svcno = 0; + fp = fopen(ServiceSwitchFile, "r"); + if (fp != NULL) + { + while (fgets(buf, sizeof buf, fp) != NULL) + { + register char *p; + + p = strpbrk(buf, "#\n"); + if (p != NULL) + *p = '\0'; + p = strpbrk(buf, " \t"); + if (p != NULL) + *p++ = '\0'; + if (strcmp(buf, service) != 0) + continue; + + /* got the right service -- extract data */ + do + { + while (isspace(*p)) + p++; + if (*p == '\0') + break; + maptype[svcno++] = p; + p = strpbrk(p, " \t"); + if (p != NULL) + *p++ = '\0'; + } while (p != NULL); + fclose(fp); + return svcno; + } + + /* service was not found -- use compiled in default */ + fclose(fp); + } +#endif + + /* if the service file doesn't work, use an absolute fallback */ + punt: + for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) + mapreturn[svcno] = 0; + svcno = 0; + if (strcmp(service, "aliases") == 0) + { + maptype[svcno++] = "files"; +#ifdef AUTO_NIS_ALIASES +# ifdef NISPLUS + maptype[svcno++] = "nisplus"; +# endif +# ifdef NIS + maptype[svcno++] = "nis"; +# endif +#endif + return svcno; + } + if (strcmp(service, "hosts") == 0) + { +# if NAMED_BIND + maptype[svcno++] = "dns"; +# else +# if defined(sun) && !defined(BSD) && !defined(_USE_SUN_NSSWITCH_) + /* SunOS */ + maptype[svcno++] = "nis"; +# endif +# endif + maptype[svcno++] = "files"; + return svcno; + } + return -1; +} +/* +** USERNAME -- return the user id of the logged in user. +** +** Parameters: +** none. +** +** Returns: +** The login name of the logged in user. +** +** Side Effects: +** none. +** +** Notes: +** The return value is statically allocated. +*/ + +char * +username() +{ + static char *myname = NULL; + extern char *getlogin(); + register struct passwd *pw; + + /* cache the result */ + if (myname == NULL) + { + myname = getlogin(); + if (myname == NULL || myname[0] == '\0') + { + pw = sm_getpwuid(RealUid); + if (pw != NULL) + myname = newstr(pw->pw_name); + } + else + { + uid_t uid = RealUid; + + myname = newstr(myname); + if ((pw = sm_getpwnam(myname)) == NULL || + (uid != 0 && uid != pw->pw_uid)) + { + pw = sm_getpwuid(uid); + if (pw != NULL) + myname = newstr(pw->pw_name); + } + } + if (myname == NULL || myname[0] == '\0') + { + syserr("554 Who are you?"); + myname = "postmaster"; + } + } + + return (myname); +} +/* +** TTYPATH -- Get the path of the user's tty +** +** Returns the pathname of the user's tty. Returns NULL if +** the user is not logged in or if s/he has write permission +** denied. +** +** Parameters: +** none +** +** Returns: +** pathname of the user's tty. +** NULL if not logged in or write permission denied. +** +** Side Effects: +** none. +** +** WARNING: +** Return value is in a local buffer. +** +** Called By: +** savemail +*/ + +char * +ttypath() +{ + struct stat stbuf; + register char *pathn; + extern char *ttyname(); + extern char *getlogin(); + + /* compute the pathname of the controlling tty */ + if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && + (pathn = ttyname(0)) == NULL) + { + errno = 0; + return (NULL); + } + + /* see if we have write permission */ + if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) + { + errno = 0; + return (NULL); + } + + /* see if the user is logged in */ + if (getlogin() == NULL) + return (NULL); + + /* looks good */ + return (pathn); +} +/* +** CHECKCOMPAT -- check for From and To person compatible. +** +** This routine can be supplied on a per-installation basis +** to determine whether a person is allowed to send a message. +** This allows restriction of certain types of internet +** forwarding or registration of users. +** +** If the hosts are found to be incompatible, an error +** message should be given using "usrerr" and an EX_ code +** should be returned. You can also set to->q_status to +** a DSN-style status code. +** +** EF_NO_BODY_RETN can be set in e->e_flags to suppress the +** body during the return-to-sender function; this should be done +** on huge messages. This bit may already be set by the ESMTP +** protocol. +** +** Parameters: +** to -- the person being sent to. +** +** Returns: +** an exit status +** +** Side Effects: +** none (unless you include the usrerr stuff) +*/ + +int +checkcompat(to, e) + register ADDRESS *to; + register ENVELOPE *e; +{ +# ifdef lint + if (to == NULL) + to++; +# endif /* lint */ + + if (tTd(49, 1)) + printf("checkcompat(to=%s, from=%s)\n", + to->q_paddr, e->e_from.q_paddr); + +# ifdef EXAMPLE_CODE + /* this code is intended as an example only */ + register STAB *s; + + s = stab("arpa", ST_MAILER, ST_FIND); + if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 && + to->q_mailer == s->s_mailer) + { + usrerr("553 No ARPA mail through this machine: see your system administration"); + /* e->e_flags |= EF_NO_BODY_RETN; to supress body on return */ + to->q_status = "5.7.1"; + return (EX_UNAVAILABLE); + } +# endif /* EXAMPLE_CODE */ + return (EX_OK); +} +/* +** SETSIGNAL -- set a signal handler +** +** This is essentially old BSD "signal(3)". +*/ + +sigfunc_t +setsignal(sig, handler) + int sig; + sigfunc_t handler; +{ +#if defined(SYS5SIGNALS) || defined(BSD4_3) + return signal(sig, handler); +#else + struct sigaction n, o; + + bzero(&n, sizeof n); + n.sa_handler = handler; +# ifdef SA_RESTART + n.sa_flags = SA_RESTART; +# endif + if (sigaction(sig, &n, &o) < 0) + return SIG_ERR; + return o.sa_handler; +#endif +} +/* +** RELEASESIGNAL -- release a held signal +** +** Parameters: +** sig -- the signal to release. +** +** Returns: +** 0 on success. +** -1 on failure. +*/ + +int +releasesignal(sig) + int sig; +{ +#ifdef BSD4_3 + return sigsetmask(sigblock(0) & ~(1 << sig)); +#else + sigset_t sset; + + sigemptyset(&sset); + sigaddset(&sset, sig); + return sigprocmask(SIG_UNBLOCK, &sset, NULL); +#endif +} +/* +** HOLDSIGS -- arrange to hold all signals +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Arranges that signals are held. +*/ + +void +holdsigs() +{ +} +/* +** RLSESIGS -- arrange to release all signals +** +** This undoes the effect of holdsigs. +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Arranges that signals are released. +*/ + +void +rlsesigs() +{ +} +/* +** INIT_MD -- do machine dependent initializations +** +** Systems that have global modes that should be set should do +** them here rather than in main. +*/ + +#ifdef _AUX_SOURCE +# include <compat.h> +#endif + +void +init_md(argc, argv) + int argc; + char **argv; +{ +#ifdef _AUX_SOURCE + setcompat(getcompat() | COMPAT_BSDPROT); +#endif + +#ifdef VENDOR_DEFAULT + VendorCode = VENDOR_DEFAULT; +#else + VendorCode = VENDOR_BERKELEY; +#endif +} +/* +** INIT_VENDOR_MACROS -- vendor-dependent macro initializations +** +** Called once, on startup. +** +** Parameters: +** e -- the global envelope. +** +** Returns: +** none. +** +** Side Effects: +** vendor-dependent. +*/ + +void +init_vendor_macros(e) + register ENVELOPE *e; +{ +} +/* +** GETLA -- get the current load average +** +** This code stolen from la.c. +** +** Parameters: +** none. +** +** Returns: +** The current load average as an integer. +** +** Side Effects: +** none. +*/ + +/* try to guess what style of load average we have */ +#define LA_ZERO 1 /* always return load average as zero */ +#define LA_INT 2 /* read kmem for avenrun; interpret as long */ +#define LA_FLOAT 3 /* read kmem for avenrun; interpret as float */ +#define LA_SUBR 4 /* call getloadavg */ +#define LA_MACH 5 /* MACH load averages (as on NeXT boxes) */ +#define LA_SHORT 6 /* read kmem for avenrun; interpret as short */ +#define LA_PROCSTR 7 /* read string ("1.17") from /proc/loadavg */ +#define LA_READKSYM 8 /* SVR4: use MIOC_READKSYM ioctl call */ +#define LA_DGUX 9 /* special DGUX implementation */ +#define LA_HPUX 10 /* special HPUX implementation */ + +/* do guesses based on general OS type */ +#ifndef LA_TYPE +# define LA_TYPE LA_ZERO +#endif + +#ifndef FSHIFT +# if defined(unixpc) +# define FSHIFT 5 +# endif + +# if defined(__alpha) || defined(IRIX) +# define FSHIFT 10 +# endif + +# if defined(_AIX3) +# define FSHIFT 16 +# endif +#endif + +#ifndef FSHIFT +# define FSHIFT 8 +#endif + +#ifndef FSCALE +# define FSCALE (1 << FSHIFT) +#endif + +#ifndef LA_AVENRUN +# ifdef SYSTEM5 +# define LA_AVENRUN "avenrun" +# else +# define LA_AVENRUN "_avenrun" +# endif +#endif + +/* _PATH_KMEM should be defined in <paths.h> */ +#ifndef _PATH_KMEM +# define _PATH_KMEM "/dev/kmem" +#endif + +#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) + +#include <nlist.h> + +#ifdef IRIX64 +# define nlist nlist64 +#endif + +/* _PATH_UNIX should be defined in <paths.h> */ +#ifndef _PATH_UNIX +# if defined(SYSTEM5) +# define _PATH_UNIX "/unix" +# else +# define _PATH_UNIX "/vmunix" +# endif +#endif + +#ifdef _AUX_SOURCE +struct nlist Nl[2]; +#else +struct nlist Nl[] = +{ + { LA_AVENRUN }, + { 0 }, +}; +#endif +#define X_AVENRUN 0 + +getla() +{ + static int kmem = -1; +#if LA_TYPE == LA_INT + long avenrun[3]; +#else +# if LA_TYPE == LA_SHORT + short avenrun[3]; +# else + double avenrun[3]; +# endif +#endif + extern int errno; + extern off_t lseek(); + + if (kmem < 0) + { + kmem = open(_PATH_KMEM, 0, 0); + if (kmem < 0) + { + if (tTd(3, 1)) + printf("getla: open(/dev/kmem): %s\n", + errstring(errno)); + return (-1); + } + (void) fcntl(kmem, F_SETFD, 1); + +#ifdef _AUX_SOURCE + strcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN); + Nl[1].n_name[0] = '\0'; +#endif + +#ifdef _AIX3 + if (knlist(Nl, 1, sizeof Nl[0]) < 0) +#else + if (nlist(_PATH_UNIX, Nl) < 0) +#endif + { + if (tTd(3, 1)) + printf("getla: nlist(%s): %s\n", _PATH_UNIX, + errstring(errno)); + return (-1); + } + if (Nl[X_AVENRUN].n_value == 0) + { + if (tTd(3, 1)) + printf("getla: nlist(%s, %s) ==> 0\n", + _PATH_UNIX, LA_AVENRUN); + return (-1); + } +#ifdef NAMELISTMASK + Nl[X_AVENRUN].n_value &= NAMELISTMASK; +#endif + } + if (tTd(3, 20)) + printf("getla: symbol address = %#x\n", Nl[X_AVENRUN].n_value); + if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 || + read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) + { + /* thank you Ian */ + if (tTd(3, 1)) + printf("getla: lseek or read: %s\n", errstring(errno)); + return (-1); + } +# if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) + if (tTd(3, 5)) + { + printf("getla: avenrun = %d", avenrun[0]); + if (tTd(3, 15)) + printf(", %d, %d", avenrun[1], avenrun[2]); + printf("\n"); + } + if (tTd(3, 1)) + printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT); + return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); +# else /* LA_TYPE == LA_FLOAT */ + if (tTd(3, 5)) + { + printf("getla: avenrun = %g", avenrun[0]); + if (tTd(3, 15)) + printf(", %g, %g", avenrun[1], avenrun[2]); + printf("\n"); + } + if (tTd(3, 1)) + printf("getla: %d\n", (int) (avenrun[0] +0.5)); + return ((int) (avenrun[0] + 0.5)); +# endif +} + +#endif /* LA_TYPE == LA_INT or LA_SHORT or LA_FLOAT */ + +#if LA_TYPE == LA_READKSYM + +# include <sys/ksym.h> + +getla() +{ + static int kmem = -1; + long avenrun[3]; + extern int errno; + struct mioc_rksym mirk; + + if (kmem < 0) + { + kmem = open("/dev/kmem", 0, 0); + if (kmem < 0) + { + if (tTd(3, 1)) + printf("getla: open(/dev/kmem): %s\n", + errstring(errno)); + return (-1); + } + (void) fcntl(kmem, F_SETFD, 1); + } + mirk.mirk_symname = LA_AVENRUN; + mirk.mirk_buf = avenrun; + mirk.mirk_buflen = sizeof(avenrun); + if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0) + { + if (tTd(3, 1)) + printf("getla: ioctl(MIOC_READKSYM) failed: %s\n", + errstring(errno)); + return -1; + } + if (tTd(3, 5)) + { + printf("getla: avenrun = %d", avenrun[0]); + if (tTd(3, 15)) + printf(", %d, %d", avenrun[1], avenrun[2]); + printf("\n"); + } + if (tTd(3, 1)) + printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT); + return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); +} + +#endif /* LA_TYPE == LA_READKSYM */ + +#if LA_TYPE == LA_DGUX + +# include <sys/dg_sys_info.h> + +int +getla() +{ + struct dg_sys_info_load_info load_info; + + dg_sys_info((long *)&load_info, + DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); + + if (tTd(3, 1)) + printf("getla: %d\n", (int) (load_info.one_minute + 0.5)); + + return((int) (load_info.one_minute + 0.5)); +} + +#endif /* LA_TYPE == LA_DGUX */ + +#if LA_TYPE == LA_HPUX + +/* forward declarations to keep gcc from complaining */ +struct pst_dynamic; +struct pst_status; +struct pst_static; +struct pst_vminfo; +struct pst_diskinfo; +struct pst_processor; +struct pst_lv; +struct pst_swapinfo; + +# include <sys/param.h> +# include <sys/pstat.h> + +int +getla() +{ + struct pst_dynamic pstd; + + if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic), + (size_t) 1, 0) == -1) + return 0; + + if (tTd(3, 1)) + printf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5)); + + return (int) (pstd.psd_avg_1_min + 0.5); +} + +#endif /* LA_TYPE == LA_HPUX */ + +#if LA_TYPE == LA_SUBR + +int +getla() +{ + double avenrun[3]; + + if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) + { + if (tTd(3, 1)) + perror("getla: getloadavg failed:"); + return (-1); + } + if (tTd(3, 1)) + printf("getla: %d\n", (int) (avenrun[0] +0.5)); + return ((int) (avenrun[0] + 0.5)); +} + +#endif /* LA_TYPE == LA_SUBR */ + +#if LA_TYPE == LA_MACH + +/* +** This has been tested on NEXTSTEP release 2.1/3.X. +*/ + +#if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 +# include <mach/mach.h> +#else +# include <mach.h> +#endif + +getla() +{ + processor_set_t default_set; + kern_return_t error; + unsigned int info_count; + struct processor_set_basic_info info; + host_t host; + + error = processor_set_default(host_self(), &default_set); + if (error != KERN_SUCCESS) + return -1; + info_count = PROCESSOR_SET_BASIC_INFO_COUNT; + if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO, + &host, (processor_set_info_t)&info, + &info_count) != KERN_SUCCESS) + { + return -1; + } + return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE; +} + +#endif /* LA_TYPE == LA_MACH */ + +#if LA_TYPE == LA_PROCSTR + +/* +** Read /proc/loadavg for the load average. This is assumed to be +** in a format like "0.15 0.12 0.06". +** +** Initially intended for Linux. This has been in the kernel +** since at least 0.99.15. +*/ + +# ifndef _PATH_LOADAVG +# define _PATH_LOADAVG "/proc/loadavg" +# endif + +int +getla() +{ + double avenrun; + register int result; + FILE *fp; + + fp = fopen(_PATH_LOADAVG, "r"); + if (fp == NULL) + { + if (tTd(3, 1)) + printf("getla: fopen(%s): %s\n", + _PATH_LOADAVG, errstring(errno)); + return -1; + } + result = fscanf(fp, "%lf", &avenrun); + fclose(fp); + if (result != 1) + { + if (tTd(3, 1)) + printf("getla: fscanf() = %d: %s\n", + result, errstring(errno)); + return -1; + } + + if (tTd(3, 1)) + printf("getla(): %.2f\n", avenrun); + + return ((int) (avenrun + 0.5)); +} + +#endif /* LA_TYPE == LA_PROCSTR */ + +#if LA_TYPE == LA_ZERO + +getla() +{ + if (tTd(3, 1)) + printf("getla: ZERO\n"); + return (0); +} + +#endif /* LA_TYPE == LA_ZERO */ + + +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Many and varied... + */ + +/* Non Apollo stuff removed by Don Lewis 11/15/93 */ +#ifndef lint +static char rcsid[] = "@(#)$Id: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $"; +#endif /* !lint */ + +#ifdef apollo +# undef volatile +# include <apollo/base.h> + +/* ARGSUSED */ +int getloadavg( call_data ) + caddr_t call_data; /* pointer to (double) return value */ +{ + double *avenrun = (double *) call_data; + int i; + status_$t st; + long loadav[3]; + proc1_$get_loadav(loadav, &st); + *avenrun = loadav[0] / (double) (1 << 16); + return(0); +} +# endif /* apollo */ +/* +** SHOULDQUEUE -- should this message be queued or sent? +** +** Compares the message cost to the load average to decide. +** +** Parameters: +** pri -- the priority of the message in question. +** ctime -- the message creation time. +** +** Returns: +** TRUE -- if this message should be queued up for the +** time being. +** FALSE -- if the load is low enough to send this message. +** +** Side Effects: +** none. +*/ + +bool +shouldqueue(pri, ctime) + long pri; + time_t ctime; +{ + bool rval; + + if (tTd(3, 30)) + printf("shouldqueue: CurrentLA=%d, pri=%d: ", CurrentLA, pri); + if (CurrentLA < QueueLA) + { + if (tTd(3, 30)) + printf("FALSE (CurrentLA < QueueLA)\n"); + return (FALSE); + } +#if 0 /* this code is reported to cause oscillation around RefuseLA */ + if (CurrentLA >= RefuseLA && QueueLA < RefuseLA) + { + if (tTd(3, 30)) + printf("TRUE (CurrentLA >= RefuseLA)\n"); + return (TRUE); + } +#endif + rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1)); + if (tTd(3, 30)) + printf("%s (by calculation)\n", rval ? "TRUE" : "FALSE"); + return rval; +} +/* +** REFUSECONNECTIONS -- decide if connections should be refused +** +** Parameters: +** none. +** +** Returns: +** TRUE if incoming SMTP connections should be refused +** (for now). +** FALSE if we should accept new work. +** +** Side Effects: +** Sets process title when it is rejecting connections. +*/ + +bool +refuseconnections() +{ + extern bool enoughdiskspace(); + extern void setproctitle __P((const char *, ...)); + +#ifdef XLA + if (!xla_smtp_ok()) + return TRUE; +#endif + + if (CurrentLA >= RefuseLA) + { + setproctitle("rejecting connections: load average: %d", + CurrentLA); + } + else if (!enoughdiskspace(MinBlocksFree + 1)) + { + setproctitle("rejecting connections: min free: %d", + MinBlocksFree); + } + else if (MaxChildren > 0 && CurChildren >= MaxChildren) + { + setproctitle("rejecting connections: maximum children: %d", + CurChildren); + } + else + return FALSE; + return TRUE; +} +/* +** SETPROCTITLE -- set process title for ps +** +** Parameters: +** fmt -- a printf style format string. +** a, b, c -- possible parameters to fmt. +** +** Returns: +** none. +** +** Side Effects: +** Clobbers argv of our main procedure so ps(1) will +** display the title. +*/ + +#define SPT_NONE 0 /* don't use it at all */ +#define SPT_REUSEARGV 1 /* cover argv with title information */ +#define SPT_BUILTIN 2 /* use libc builtin */ +#define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */ +#define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */ +#define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */ +#define SPT_SCO 6 /* write kernel u. area */ + +#ifndef SPT_TYPE +# define SPT_TYPE SPT_REUSEARGV +#endif + +#if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN + +# if SPT_TYPE == SPT_PSTAT +# include <sys/pstat.h> +# endif +# if SPT_TYPE == SPT_PSSTRINGS +# include <machine/vmparam.h> +# include <sys/exec.h> +# ifndef PS_STRINGS /* hmmmm.... apparently not available after all */ +# undef SPT_TYPE +# define SPT_TYPE SPT_REUSEARGV +# else +# ifndef NKPDE /* FreeBSD 2.0 */ +# define NKPDE 63 +typedef unsigned int *pt_entry_t; +# endif +# endif +# endif + +# if SPT_TYPE == SPT_PSSTRINGS +# define SETPROC_STATIC static +# else +# define SETPROC_STATIC +# endif + +# if SPT_TYPE == SPT_SYSMIPS +# include <sys/sysmips.h> +# include <sys/sysnews.h> +# endif + +# if SPT_TYPE == SPT_SCO +# include <sys/immu.h> +# include <sys/dir.h> +# include <sys/user.h> +# include <sys/fs/s5param.h> +# if PSARGSZ > MAXLINE +# define SPT_BUFSIZE PSARGSZ +# endif +# endif + +# ifndef SPT_PADCHAR +# define SPT_PADCHAR ' ' +# endif + +# ifndef SPT_BUFSIZE +# define SPT_BUFSIZE MAXLINE +# endif + +#endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */ + +/* +** Pointers for setproctitle. +** This allows "ps" listings to give more useful information. +*/ + +char **Argv = NULL; /* pointer to argument vector */ +char *LastArgv = NULL; /* end of argv */ + +void +initsetproctitle(argc, argv, envp) + int argc; + char **argv; + char **envp; +{ + register int i; + extern char **environ; + + /* + ** Move the environment so setproctitle can use the space at + ** the top of memory. + */ + + for (i = 0; envp[i] != NULL; i++) + continue; + environ = (char **) xalloc(sizeof (char *) * (i + 1)); + for (i = 0; envp[i] != NULL; i++) + environ[i] = newstr(envp[i]); + environ[i] = NULL; + + /* + ** Save start and extent of argv for setproctitle. + */ + + Argv = argv; + if (i > 0) + LastArgv = envp[i - 1] + strlen(envp[i - 1]); + else + LastArgv = argv[argc - 1] + strlen(argv[argc - 1]); +} + +#if SPT_TYPE != SPT_BUILTIN + + +/*VARARGS1*/ +void +# ifdef __STDC__ +setproctitle(const char *fmt, ...) +# else +setproctitle(fmt, va_alist) + const char *fmt; + va_dcl +# endif +{ +# if SPT_TYPE != SPT_NONE + register char *p; + register int i; + SETPROC_STATIC char buf[SPT_BUFSIZE]; + VA_LOCAL_DECL +# if SPT_TYPE == SPT_PSTAT + union pstun pst; +# endif +# if SPT_TYPE == SPT_SCO + off_t seek_off; + static int kmem = -1; + static int kmempid = -1; + struct user u; +# endif + + p = buf; + + /* print sendmail: heading for grep */ + (void) strcpy(p, "sendmail: "); + p += strlen(p); + + /* print the argument string */ + VA_START(fmt); + (void) vsnprintf(p, sizeof buf - (p - buf), fmt, ap); + VA_END; + + i = strlen(buf); + +# if SPT_TYPE == SPT_PSTAT + pst.pst_command = buf; + pstat(PSTAT_SETCMD, pst, i, 0, 0); +# endif +# if SPT_TYPE == SPT_PSSTRINGS + PS_STRINGS->ps_nargvstr = 1; + PS_STRINGS->ps_argvstr = buf; +# endif +# if SPT_TYPE == SPT_SYSMIPS + sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); +# endif +# if SPT_TYPE == SPT_SCO + if (kmem < 0 || kmempid != getpid()) + { + if (kmem >= 0) + close(kmem); + kmem = open(_PATH_KMEM, O_RDWR, 0); + if (kmem < 0) + return; + (void) fcntl(kmem, F_SETFD, 1); + kmempid = getpid(); + } + buf[PSARGSZ - 1] = '\0'; + seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u; + if (lseek(kmem, (char *) seek_off, SEEK_SET) == seek_off) + (void) write(kmem, buf, PSARGSZ); +# endif +# if SPT_TYPE == SPT_REUSEARGV + if (i > LastArgv - Argv[0] - 2) + { + i = LastArgv - Argv[0] - 2; + buf[i] = '\0'; + } + (void) strcpy(Argv[0], buf); + p = &Argv[0][i]; + while (p < LastArgv) + *p++ = SPT_PADCHAR; + Argv[1] = NULL; +# endif +# endif /* SPT_TYPE != SPT_NONE */ +} + +#endif /* SPT_TYPE != SPT_BUILTIN */ +/* +** REAPCHILD -- pick up the body of my child, lest it become a zombie +** +** Parameters: +** sig -- the signal that got us here (unused). +** +** Returns: +** none. +** +** Side Effects: +** Picks up extant zombies. +*/ + +void +reapchild(sig) + int sig; +{ + int olderrno = errno; +# ifdef HASWAITPID + auto int status; + int count; + int pid; + + count = 0; + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + { + if (count++ > 1000) + { +#ifdef LOG + syslog(LOG_ALERT, "reapchild: waitpid loop: pid=%d, status=%x", + pid, status); +#endif + break; + } + CurChildren--; + } +# else +# ifdef WNOHANG + union wait status; + + while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0) + CurChildren--; +# else /* WNOHANG */ + auto int status; + + while (wait(&status) > 0) + CurChildren--; +# endif /* WNOHANG */ +# endif +# ifdef SYS5SIGNALS + (void) setsignal(SIGCHLD, reapchild); +# endif + errno = olderrno; +} +/* +** PUTENV -- emulation of putenv() in terms of setenv() +** +** Not needed on Posix-compliant systems. +** This doesn't have full Posix semantics, but it's good enough +** for sendmail. +** +** Parameter: +** env -- the environment to put. +** +** Returns: +** none. +*/ + +#ifdef NEEDPUTENV + +# if NEEDPUTENV == 2 /* no setenv(3) call available */ + +int +putenv(str) + char *str; +{ + char **current; + int matchlen, envlen=0; + char *tmp; + char **newenv; + static int first=1; + extern char **environ; + + /* + * find out how much of str to match when searching + * for a string to replace. + */ + if ((tmp = index(str, '=')) == NULL || tmp == str) + matchlen = strlen(str); + else + matchlen = (int) (tmp - str); + ++matchlen; + + /* + * Search for an existing string in the environment and find the + * length of environ. If found, replace and exit. + */ + for (current=environ; *current; current++) { + ++envlen; + + if (strncmp(str, *current, matchlen) == 0) { + /* found it, now insert the new version */ + *current = (char *)str; + return(0); + } + } + + /* + * There wasn't already a slot so add space for a new slot. + * If this is our first time through, use malloc(), else realloc(). + */ + if (first) { + newenv = (char **) malloc(sizeof(char *) * (envlen + 2)); + if (newenv == NULL) + return(-1); + + first=0; + (void) memcpy(newenv, environ, sizeof(char *) * envlen); + } else { + newenv = (char **) realloc((char *)environ, sizeof(char *) * (envlen + 2)); + if (newenv == NULL) + return(-1); + } + + /* actually add in the new entry */ + environ = newenv; + environ[envlen] = (char *)str; + environ[envlen+1] = NULL; + + return(0); +} + +#else /* implement putenv() in terms of setenv() */ + +int +putenv(env) + char *env; +{ + char *p; + int l; + char nbuf[100]; + + p = strchr(env, '='); + if (p == NULL) + return 0; + l = p - env; + if (l > sizeof nbuf - 1) + l = sizeof nbuf - 1; + bcopy(env, nbuf, l); + nbuf[l] = '\0'; + return setenv(nbuf, ++p, 1); +} + +# endif +#endif +/* +** UNSETENV -- remove a variable from the environment +** +** Not needed on newer systems. +** +** Parameters: +** name -- the string name of the environment variable to be +** deleted from the current environment. +** +** Returns: +** none. +** +** Globals: +** environ -- a pointer to the current environment. +** +** Side Effects: +** Modifies environ. +*/ + +#ifndef HASUNSETENV + +void +unsetenv(name) + char *name; +{ + extern char **environ; + register char **pp; + int len = strlen(name); + + for (pp = environ; *pp != NULL; pp++) + { + if (strncmp(name, *pp, len) == 0 && + ((*pp)[len] == '=' || (*pp)[len] == '\0')) + break; + } + + for (; *pp != NULL; pp++) + *pp = pp[1]; +} + +#endif +/* +** GETDTABLESIZE -- return number of file descriptors +** +** Only on non-BSD systems +** +** Parameters: +** none +** +** Returns: +** size of file descriptor table +** +** Side Effects: +** none +*/ + +#ifdef SOLARIS +# include <sys/resource.h> +#endif + +int +getdtsize() +{ +#ifdef RLIMIT_NOFILE + struct rlimit rl; + + if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) + return rl.rlim_cur; +#endif + +# ifdef HASGETDTABLESIZE + return getdtablesize(); +# else +# ifdef _SC_OPEN_MAX + return sysconf(_SC_OPEN_MAX); +# else + return NOFILE; +# endif +# endif +} +/* +** UNAME -- get the UUCP name of this system. +*/ + +#ifndef HASUNAME + +int +uname(name) + struct utsname *name; +{ + FILE *file; + char *n; + + name->nodename[0] = '\0'; + + /* try /etc/whoami -- one line with the node name */ + if ((file = fopen("/etc/whoami", "r")) != NULL) + { + (void) fgets(name->nodename, NODE_LENGTH + 1, file); + (void) fclose(file); + n = strchr(name->nodename, '\n'); + if (n != NULL) + *n = '\0'; + if (name->nodename[0] != '\0') + return (0); + } + + /* try /usr/include/whoami.h -- has a #define somewhere */ + if ((file = fopen("/usr/include/whoami.h", "r")) != NULL) + { + char buf[MAXLINE]; + + while (fgets(buf, MAXLINE, file) != NULL) + if (sscanf(buf, "#define sysname \"%*[^\"]\"", + NODE_LENGTH, name->nodename) > 0) + break; + (void) fclose(file); + if (name->nodename[0] != '\0') + return (0); + } + +#ifdef TRUST_POPEN + /* + ** Popen is known to have security holes. + */ + + /* try uuname -l to return local name */ + if ((file = popen("uuname -l", "r")) != NULL) + { + (void) fgets(name, NODE_LENGTH + 1, file); + (void) pclose(file); + n = strchr(name, '\n'); + if (n != NULL) + *n = '\0'; + if (name->nodename[0] != '\0') + return (0); + } +#endif + + return (-1); +} +#endif /* HASUNAME */ +/* +** INITGROUPS -- initialize groups +** +** Stub implementation for System V style systems +*/ + +#ifndef HASINITGROUPS + +initgroups(name, basegid) + char *name; + int basegid; +{ + return 0; +} + +#endif +/* +** SETSID -- set session id (for non-POSIX systems) +*/ + +#ifndef HASSETSID + +pid_t +setsid __P ((void)) +{ +#ifdef TIOCNOTTY + int fd; + + fd = open("/dev/tty", O_RDWR, 0); + if (fd >= 0) + { + (void) ioctl(fd, (int) TIOCNOTTY, (char *) 0); + (void) close(fd); + } +#endif /* TIOCNOTTY */ +# ifdef SYS5SETPGRP + return setpgrp(); +# else + return setpgid(0, getpid()); +# endif +} + +#endif +/* +** FSYNC -- dummy fsync +*/ + +#ifdef NEEDFSYNC + +fsync(fd) + int fd; +{ +# ifdef O_SYNC + return fcntl(fd, F_SETFL, O_SYNC); +# else + /* nothing we can do */ + return 0; +# endif +} + +#endif +/* +** DGUX_INET_ADDR -- inet_addr for DG/UX +** +** Data General DG/UX version of inet_addr returns a struct in_addr +** instead of a long. This patches things. Only needed on versions +** prior to 5.4.3. +*/ + +#ifdef DGUX_5_4_2 + +#undef inet_addr + +long +dgux_inet_addr(host) + char *host; +{ + struct in_addr haddr; + + haddr = inet_addr(host); + return haddr.s_addr; +} + +#endif +/* +** GETOPT -- for old systems or systems with bogus implementations +*/ + +#ifdef NEEDGETOPT + +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + + +/* +** this version hacked to add `atend' flag to allow state machine +** to reset if invoked by the program to scan args for a 2nd time +*/ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getopt.c 4.3 (Berkeley) 3/9/86"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +/* + * get option letter from argument vector + */ +#ifdef _CONVEX_SOURCE +extern int optind, opterr, optopt; +extern char *optarg; +#else +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = 0; /* character checked for validity */ +char *optarg = NULL; /* argument associated with option */ +#endif + +#define BADCH (int)'?' +#define EMSG "" +#define tell(s) if (opterr) {fputs(*nargv,stderr);fputs(s,stderr); \ + fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);} + +getopt(nargc,nargv,ostr) + int nargc; + char *const *nargv; + const char *ostr; +{ + static char *place = EMSG; /* option letter processing */ + static char atend = 0; + register char *oli; /* option letter list index */ + + if (atend) { + atend = 0; + place = EMSG; + } + if(!*place) { /* update scanning pointer */ + if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) { + atend++; + return(EOF); + } + if (*place == '-') { /* found "--" */ + ++optind; + atend++; + return(EOF); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) { + if (!*place) ++optind; + tell(": illegal option -- "); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) ++optind; + } + else { /* need an argument */ + if (*place) optarg = place; /* no white space */ + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + tell(": option requires an argument -- "); + } + else optarg = nargv[optind]; /* white space */ + place = EMSG; + ++optind; + } + return(optopt); /* dump back option letter */ +} + +#endif +/* +** VFPRINTF, VSPRINTF -- for old 4.3 BSD systems missing a real version +*/ + +#ifdef NEEDVPRINTF + +#define MAXARG 16 + +vfprintf(fp, fmt, ap) + FILE *fp; + char *fmt; + char **ap; +{ + char *bp[MAXARG]; + int i = 0; + + while (*ap && i < MAXARG) + bp[i++] = *ap++; + fprintf(fp, fmt, bp[0], bp[1], bp[2], bp[3], + bp[4], bp[5], bp[6], bp[7], + bp[8], bp[9], bp[10], bp[11], + bp[12], bp[13], bp[14], bp[15]); +} + +vsprintf(s, fmt, ap) + char *s; + char *fmt; + char **ap; +{ + char *bp[MAXARG]; + int i = 0; + + while (*ap && i < MAXARG) + bp[i++] = *ap++; + sprintf(s, fmt, bp[0], bp[1], bp[2], bp[3], + bp[4], bp[5], bp[6], bp[7], + bp[8], bp[9], bp[10], bp[11], + bp[12], bp[13], bp[14], bp[15]); +} + +#endif +/* +** SNPRINTF, VSNPRINT -- counted versions of printf +** +** These are at best crude emulations. +*/ + +#if !HASSNPRINTF + +void +# ifdef __STDC__ +snprintf(char *buf, size_t bufsize, const char *fmt, ...) +# else +snprintf(buf, bufsize, fmt, va_alist) + char *buf; + size_t bufsize; + const char *fmt; + va_dcl +# endif +{ + VA_LOCAL_DECL + + VA_START(fmt); + vsprintf(buf, fmt, ap); + VA_END; +# if defined(XDEBUG) && defined(LOG) + if (strlen(buf) > bufsize) + syslog(LOG_ALERT, "INTERNAL ERROR: snprintf overflow: %s", + shortenstring(buf, 200)); +# endif +} + + +#ifndef luna2 +void +vsnprintf(buf, bufsize, fmt, ap) + char *buf; + size_t bufsize; + const char *fmt; + va_list ap; +{ + vsprintf(buf, fmt, ap); +# if defined(XDEBUG) && defined(LOG) + if (strlen(buf) > bufsize) + syslog(LOG_ALERT, "INTERNAL ERROR: vsnprintf overflow: %s", + shortenstring(buf, 200)); +# endif +} +#endif + +#endif +/* +** USERSHELLOK -- tell if a user's shell is ok for unrestricted use +** +** Parameters: +** user -- the name of the user we are checking. +** shell -- the user's shell from /etc/passwd +** +** Returns: +** TRUE -- if it is ok to use this for unrestricted access. +** FALSE -- if the shell is restricted. +*/ + +#if !HASGETUSERSHELL + +# ifndef _PATH_SHELLS +# define _PATH_SHELLS "/etc/shells" +# endif + +# ifdef _AIX3 +# include <userconf.h> +# include <usersec.h> +# endif + +char *DefaultUserShells[] = +{ + "/bin/sh", /* standard shell */ + "/usr/bin/sh", + "/bin/csh", /* C shell */ + "/usr/bin/csh", +#ifdef __hpux +# ifdef V4FS + "/usr/bin/rsh", /* restricted Bourne shell */ + "/usr/bin/ksh", /* Korn shell */ + "/usr/bin/rksh", /* restricted Korn shell */ + "/usr/bin/pam", + "/usr/bin/keysh", /* key shell (extended Korn shell) */ + "/usr/bin/posix/sh", +# else + "/bin/rsh", /* restricted Bourne shell */ + "/bin/ksh", /* Korn shell */ + "/bin/rksh", /* restricted Korn shell */ + "/bin/pam", + "/usr/bin/keysh", /* key shell (extended Korn shell) */ + "/bin/posix/sh", +# endif +#endif +#ifdef _AIX3 + "/bin/ksh", /* Korn shell */ + "/usr/bin/ksh", + "/bin/tsh", /* trusted shell */ + "/usr/bin/tsh", + "/bin/bsh", /* Bourne shell */ + "/usr/bin/bsh", +#endif +#ifdef __svr4__ + "/bin/ksh", /* Korn shell */ + "/usr/bin/ksh", +#endif + NULL +}; + +#endif + +#define WILDCARD_SHELL "/SENDMAIL/ANY/SHELL/" + +bool +usershellok(user, shell) + char *user; + char *shell; +{ +#if HASGETUSERSHELL + register char *p; + extern char *getusershell(); + + if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') || + ConfigLevel <= 1) + return TRUE; + + setusershell(); + while ((p = getusershell()) != NULL) + if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0) + break; + endusershell(); + return p != NULL; +#else +# if USEGETCONFATTR + auto char *v; +# endif + register FILE *shellf; + char buf[MAXLINE]; + + if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't')) + return TRUE; + +# if USEGETCONFATTR + /* + ** Naturally IBM has a "better" idea..... + ** + ** What a crock. This interface isn't documented, it is + ** considered part of the security library (-ls), and it + ** only works if you are running as root (since the list + ** of valid shells is obviously a source of great concern). + ** I recommend that you do NOT define USEGETCONFATTR, + ** especially since you are going to have to set up an + ** /etc/shells anyhow to handle the cases where getconfattr + ** fails. + */ + + if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL) + { + while (*v != '\0') + { + if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0) + return TRUE; + v += strlen(v) + 1; + } + return FALSE; + } +# endif + + shellf = fopen(_PATH_SHELLS, "r"); + if (shellf == NULL) + { + /* no /etc/shells; see if it is one of the std shells */ + char **d; + + for (d = DefaultUserShells; *d != NULL; d++) + { + if (strcmp(shell, *d) == 0) + return TRUE; + } + return FALSE; + } + + while (fgets(buf, sizeof buf, shellf) != NULL) + { + register char *p, *q; + + p = buf; + while (*p != '\0' && *p != '#' && *p != '/') + p++; + if (*p == '#' || *p == '\0') + continue; + q = p; + while (*p != '\0' && *p != '#' && !isspace(*p)) + p++; + *p = '\0'; + if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0) + { + fclose(shellf); + return TRUE; + } + } + fclose(shellf); + return FALSE; +#endif +} +/* +** FREEDISKSPACE -- see how much free space is on the queue filesystem +** +** Only implemented if you have statfs. +** +** Parameters: +** dir -- the directory in question. +** bsize -- a variable into which the filesystem +** block size is stored. +** +** Returns: +** The number of bytes free on the queue filesystem. +** -1 if the statfs call fails. +** +** Side effects: +** Puts the filesystem block size into bsize. +*/ + +/* statfs types */ +#define SFS_NONE 0 /* no statfs implementation */ +#define SFS_USTAT 1 /* use ustat */ +#define SFS_4ARGS 2 /* use four-argument statfs call */ +#define SFS_VFS 3 /* use <sys/vfs.h> implementation */ +#define SFS_MOUNT 4 /* use <sys/mount.h> implementation */ +#define SFS_STATFS 5 /* use <sys/statfs.h> implementation */ +#define SFS_STATVFS 6 /* use <sys/statvfs.h> implementation */ + +#ifndef SFS_TYPE +# define SFS_TYPE SFS_NONE +#endif + +#if SFS_TYPE == SFS_USTAT +# include <ustat.h> +#endif +#if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS +# include <sys/statfs.h> +#endif +#if SFS_TYPE == SFS_VFS +# include <sys/vfs.h> +#endif +#if SFS_TYPE == SFS_MOUNT +# include <sys/mount.h> +#endif +#if SFS_TYPE == SFS_STATVFS +# include <sys/statvfs.h> +#endif + +long +freediskspace(dir, bsize) + char *dir; + long *bsize; +{ +#if SFS_TYPE != SFS_NONE +# if SFS_TYPE == SFS_USTAT + struct ustat fs; + struct stat statbuf; +# define FSBLOCKSIZE DEV_BSIZE +# define SFS_BAVAIL f_tfree +# else +# if defined(ultrix) + struct fs_data fs; +# define SFS_BAVAIL fd_bfreen +# define FSBLOCKSIZE 1024L +# else +# if SFS_TYPE == SFS_STATVFS + struct statvfs fs; +# define FSBLOCKSIZE fs.f_frsize +# else + struct statfs fs; +# define FSBLOCKSIZE fs.f_bsize +# endif +# endif +# endif +# ifndef SFS_BAVAIL +# define SFS_BAVAIL f_bavail +# endif + +# if SFS_TYPE == SFS_USTAT + if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0) +# else +# if SFS_TYPE == SFS_4ARGS + if (statfs(dir, &fs, sizeof fs, 0) == 0) +# else +# if SFS_TYPE == SFS_STATVFS + if (statvfs(dir, &fs) == 0) +# else +# if defined(ultrix) + if (statfs(dir, &fs) > 0) +# else + if (statfs(dir, &fs) == 0) +# endif +# endif +# endif +# endif + { + if (bsize != NULL) + *bsize = FSBLOCKSIZE; + if (fs.SFS_BAVAIL < 0) + return 0; + else + return fs.SFS_BAVAIL; + } +#endif + return (-1); +} +/* +** ENOUGHDISKSPACE -- is there enough free space on the queue fs? +** +** Only implemented if you have statfs. +** +** Parameters: +** msize -- the size to check against. If zero, we don't yet +** know how big the message will be, so just check for +** a "reasonable" amount. +** +** Returns: +** TRUE if there is enough space. +** FALSE otherwise. +*/ + +bool +enoughdiskspace(msize) + long msize; +{ + long bfree, bsize; + + if (MinBlocksFree <= 0 && msize <= 0) + { + if (tTd(4, 80)) + printf("enoughdiskspace: no threshold\n"); + return TRUE; + } + + if ((bfree = freediskspace(QueueDir, &bsize)) >= 0) + { + if (tTd(4, 80)) + printf("enoughdiskspace: bavail=%ld, need=%ld\n", + bfree, msize); + + /* convert msize to block count */ + msize = msize / bsize + 1; + if (MinBlocksFree >= 0) + msize += MinBlocksFree; + + if (bfree < msize) + { +#ifdef LOG + if (LogLevel > 0) + syslog(LOG_ALERT, + "%s: low on space (have %ld, %s needs %ld in %s)", + CurEnv->e_id == NULL ? "[NOQUEUE]" : CurEnv->e_id, + bfree, + CurHostName == NULL ? "SMTP-DAEMON" : CurHostName, + msize, QueueDir); +#endif + return FALSE; + } + } + else if (tTd(4, 80)) + printf("enoughdiskspace failure: min=%ld, need=%ld: %s\n", + MinBlocksFree, msize, errstring(errno)); + return TRUE; +} +/* +** TRANSIENTERROR -- tell if an error code indicates a transient failure +** +** This looks at an errno value and tells if this is likely to +** go away if retried later. +** +** Parameters: +** err -- the errno code to classify. +** +** Returns: +** TRUE if this is probably transient. +** FALSE otherwise. +*/ + +bool +transienterror(err) + int err; +{ + switch (err) + { + case EIO: /* I/O error */ + case ENXIO: /* Device not configured */ + case EAGAIN: /* Resource temporarily unavailable */ + case ENOMEM: /* Cannot allocate memory */ + case ENODEV: /* Operation not supported by device */ + case ENFILE: /* Too many open files in system */ + case EMFILE: /* Too many open files */ + case ENOSPC: /* No space left on device */ +#ifdef ETIMEDOUT + case ETIMEDOUT: /* Connection timed out */ +#endif +#ifdef ESTALE + case ESTALE: /* Stale NFS file handle */ +#endif +#ifdef ENETDOWN + case ENETDOWN: /* Network is down */ +#endif +#ifdef ENETUNREACH + case ENETUNREACH: /* Network is unreachable */ +#endif +#ifdef ENETRESET + case ENETRESET: /* Network dropped connection on reset */ +#endif +#ifdef ECONNABORTED + case ECONNABORTED: /* Software caused connection abort */ +#endif +#ifdef ECONNRESET + case ECONNRESET: /* Connection reset by peer */ +#endif +#ifdef ENOBUFS + case ENOBUFS: /* No buffer space available */ +#endif +#ifdef ESHUTDOWN + case ESHUTDOWN: /* Can't send after socket shutdown */ +#endif +#ifdef ECONNREFUSED + case ECONNREFUSED: /* Connection refused */ +#endif +#ifdef EHOSTDOWN + case EHOSTDOWN: /* Host is down */ +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: /* No route to host */ +#endif +#ifdef EDQUOT + case EDQUOT: /* Disc quota exceeded */ +#endif +#ifdef EPROCLIM + case EPROCLIM: /* Too many processes */ +#endif +#ifdef EUSERS + case EUSERS: /* Too many users */ +#endif +#ifdef EDEADLK + case EDEADLK: /* Resource deadlock avoided */ +#endif +#ifdef EISCONN + case EISCONN: /* Socket already connected */ +#endif +#ifdef EINPROGRESS + case EINPROGRESS: /* Operation now in progress */ +#endif +#ifdef EALREADY + case EALREADY: /* Operation already in progress */ +#endif +#ifdef EADDRINUSE + case EADDRINUSE: /* Address already in use */ +#endif +#ifdef EADDRNOTAVAIL + case EADDRNOTAVAIL: /* Can't assign requested address */ +#endif +#ifdef ETXTBSY + case ETXTBSY: /* (Apollo) file locked */ +#endif +#if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) + case ENOSR: /* Out of streams resources */ +#endif + case EOPENTIMEOUT: /* PSEUDO: open timed out */ + return TRUE; + } + + /* nope, must be permanent */ + return FALSE; +} +/* +** LOCKFILE -- lock a file using flock or (shudder) fcntl locking +** +** Parameters: +** fd -- the file descriptor of the file. +** filename -- the file name (for error messages). +** ext -- the filename extension. +** type -- type of the lock. Bits can be: +** LOCK_EX -- exclusive lock. +** LOCK_NB -- non-blocking. +** +** Returns: +** TRUE if the lock was acquired. +** FALSE otherwise. +*/ + +bool +lockfile(fd, filename, ext, type) + int fd; + char *filename; + char *ext; + int type; +{ +# if !HASFLOCK + int action; + struct flock lfd; + + if (ext == NULL) + ext = ""; + + bzero(&lfd, sizeof lfd); + if (bitset(LOCK_UN, type)) + lfd.l_type = F_UNLCK; + else if (bitset(LOCK_EX, type)) + lfd.l_type = F_WRLCK; + else + lfd.l_type = F_RDLCK; + + if (bitset(LOCK_NB, type)) + action = F_SETLK; + else + action = F_SETLKW; + + if (tTd(55, 60)) + printf("lockfile(%s%s, action=%d, type=%d): ", + filename, ext, action, lfd.l_type); + + if (fcntl(fd, action, &lfd) >= 0) + { + if (tTd(55, 60)) + printf("SUCCESS\n"); + return TRUE; + } + + if (tTd(55, 60)) + printf("(%s) ", errstring(errno)); + + /* + ** On SunOS, if you are testing using -oQ/tmp/mqueue or + ** -oA/tmp/aliases or anything like that, and /tmp is mounted + ** as type "tmp" (that is, served from swap space), the + ** previous fcntl will fail with "Invalid argument" errors. + ** Since this is fairly common during testing, we will assume + ** that this indicates that the lock is successfully grabbed. + */ + + if (errno == EINVAL) + { + if (tTd(55, 60)) + printf("SUCCESS\n"); + return TRUE; + } + + if (!bitset(LOCK_NB, type) || (errno != EACCES && errno != EAGAIN)) + { + int omode = -1; +# ifdef F_GETFL + int oerrno = errno; + + (void) fcntl(fd, F_GETFL, &omode); + errno = oerrno; +# endif + syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)", + filename, ext, fd, type, omode, geteuid()); + } +# else + if (ext == NULL) + ext = ""; + + if (tTd(55, 60)) + printf("lockfile(%s%s, type=%o): ", filename, ext, type); + + if (flock(fd, type) >= 0) + { + if (tTd(55, 60)) + printf("SUCCESS\n"); + return TRUE; + } + + if (tTd(55, 60)) + printf("(%s) ", errstring(errno)); + + if (!bitset(LOCK_NB, type) || errno != EWOULDBLOCK) + { + int omode = -1; +# ifdef F_GETFL + int oerrno = errno; + + (void) fcntl(fd, F_GETFL, &omode); + errno = oerrno; +# endif + syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)", + filename, ext, fd, type, omode, geteuid()); + } +# endif + if (tTd(55, 60)) + printf("FAIL\n"); + return FALSE; +} +/* +** CHOWNSAFE -- tell if chown is "safe" (executable only by root) +** +** Parameters: +** fd -- the file descriptor to check. +** +** Returns: +** TRUE -- if only root can chown the file to an arbitrary +** user. +** FALSE -- if an arbitrary user can give away a file. +*/ + +bool +chownsafe(fd) + int fd; +{ +#ifdef __hpux + char *s; + int tfd; + uid_t o_uid, o_euid; + gid_t o_gid, o_egid; + bool rval; + struct stat stbuf; + + o_uid = getuid(); + o_euid = geteuid(); + o_gid = getgid(); + o_egid = getegid(); + fstat(fd, &stbuf); + setresuid(stbuf.st_uid, stbuf.st_uid, -1); + setresgid(stbuf.st_gid, stbuf.st_gid, -1); + s = tmpnam(NULL); + tfd = open(s, O_RDONLY|O_CREAT, 0600); + rval = fchown(tfd, DefUid, DefGid) != 0; + close(tfd); + unlink(s); + setresuid(o_uid, o_euid, -1); + setresgid(o_gid, o_egid, -1); + return rval; +#else +# ifdef _POSIX_CHOWN_RESTRICTED +# if _POSIX_CHOWN_RESTRICTED == -1 + return FALSE; +# else + return TRUE; +# endif +# else +# ifdef _PC_CHOWN_RESTRICTED + int rval; + + /* + ** Some systems (e.g., SunOS) seem to have the call and the + ** #define _PC_CHOWN_RESTRICTED, but don't actually implement + ** the call. This heuristic checks for that. + */ + + errno = 0; + rval = fpathconf(fd, _PC_CHOWN_RESTRICTED); + if (errno == 0) + return rval > 0; +# endif +# ifdef BSD + return TRUE; +# else + return FALSE; +# endif +# endif +#endif +} +/* +** RESETLIMITS -- reset system controlled resource limits +** +** This is to avoid denial-of-service attacks +** +** Parameters: +** none +** +** Returns: +** none +*/ + +#if HASSETRLIMIT +# ifdef apollo +# include <sys/time.h> +# endif +# include <sys/resource.h> +#endif + +void +resetlimits() +{ +#if HASSETRLIMIT + struct rlimit lim; + + lim.rlim_cur = lim.rlim_max = RLIM_INFINITY; + (void) setrlimit(RLIMIT_CPU, &lim); + (void) setrlimit(RLIMIT_FSIZE, &lim); +#else +# if HASULIMIT + (void) ulimit(2, 0x3fffff); +# endif +#endif +} +/* +** GETCFNAME -- return the name of the .cf file. +** +** Some systems (e.g., NeXT) determine this dynamically. +*/ + +char * +getcfname() +{ + + if (ConfFile != NULL) + return ConfFile; +#if NETINFO + { + extern char *ni_propval(); + char *cflocation; + + cflocation = ni_propval("/locations", NULL, "sendmail", + "sendmail.cf", '\0'); + if (cflocation != NULL) + return cflocation; + } +#endif + + return _PATH_SENDMAILCF; +} +/* +** SETVENDOR -- process vendor code from V configuration line +** +** Parameters: +** vendor -- string representation of vendor. +** +** Returns: +** TRUE -- if ok. +** FALSE -- if vendor code could not be processed. +** +** Side Effects: +** It is reasonable to set mode flags here to tweak +** processing in other parts of the code if necessary. +** For example, if you are a vendor that uses $%y to +** indicate YP lookups, you could enable that here. +*/ + +bool +setvendor(vendor) + char *vendor; +{ + if (strcasecmp(vendor, "Berkeley") == 0) + { + VendorCode = VENDOR_BERKELEY; + return TRUE; + } + + /* add vendor extensions here */ + +#ifdef SUN_EXTENSIONS + if (strcasecmp(vendor, "Sun") == 0) + { + VendorCode = VENDOR_SUN; + return TRUE; + } +#endif + + return FALSE; +} +/* +** VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults +** +** Vendor_pre_defaults is called before reading the configuration +** file; vendor_post_defaults is called immediately after. +** +** Parameters: +** e -- the global environment to initialize. +** +** Returns: +** none. +*/ + +void +vendor_pre_defaults(e) + ENVELOPE *e; +{ +} + + +void +vendor_post_defaults(e) + ENVELOPE *e; +{ +} +/* +** STRTOL -- convert string to long integer +** +** For systems that don't have it in the C library. +** +** This is taken verbatim from the 4.4-Lite C library. +*/ + +#ifdef NEEDSTRTOL + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <limits.h> + +/* + * Convert a string to a long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ + +long +strtol(nptr, endptr, base) + const char *nptr; + char **endptr; + register int base; +{ + register const char *s = nptr; + register unsigned long acc; + register int c; + register unsigned long cutoff; + register int neg = 0, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') + c = *s++; + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; + cutlim = cutoff % (unsigned long)base; + cutoff /= (unsigned long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +#endif +/* +** STRSTR -- find first substring in string +** +** Parameters: +** big -- the big (full) string. +** little -- the little (sub) string. +** +** Returns: +** A pointer to the first instance of little in big. +** big if little is the null string. +** NULL if little is not contained in big. +*/ + +#ifdef NEEDSTRSTR + +char * +strstr(big, little) + char *big; + char *little; +{ + register char *p = big; + int l; + + if (*little == '\0') + return big; + l = strlen(little); + + while ((p = strchr(p, *little)) != NULL) + { + if (strncmp(p, little, l) == 0) + return p; + p++; + } + return NULL; +} + +#endif +/* +** SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX +** +** Some operating systems have wierd problems with the gethostbyXXX +** routines. For example, Solaris versions at least through 2.3 +** don't properly deliver a canonical h_name field. This tries to +** work around these problems. +*/ + +struct hostent * +sm_gethostbyname(name) + char *name; +{ + struct hostent *h; +#if defined(SOLARIS) && SOLARIS < 204 || defined(sony_news) && defined(__svr4) +# if SOLARIS == 203 + static struct hostent hp; + static char buf[1000]; + extern struct hostent *_switch_gethostbyname_r(); + + if (tTd(61, 10)) + printf("_switch_gethostbyname_r(%s)... ", name); + h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno); +# else + extern struct hostent *__switch_gethostbyname(); + + if (tTd(61, 10)) + printf("__switch_gethostbyname(%s)... ", name); + h = __switch_gethostbyname(name); +# endif +#else + int nmaps; + char *maptype[MAXMAPSTACK]; + short mapreturn[MAXMAPACTIONS]; + char hbuf[MAXNAME]; + + if (tTd(61, 10)) + printf("gethostbyname(%s)... ", name); + h = gethostbyname(name); + if (h == NULL) + { + if (tTd(61, 10)) + printf("failure\n"); + + nmaps = switch_map_find("hosts", maptype, mapreturn); + while (--nmaps >= 0) + if (strcmp(maptype[nmaps], "nis") == 0 || + strcmp(maptype[nmaps], "files") == 0) + break; + if (nmaps >= 0) + { + /* try short name */ + if (strlen(name) > sizeof hbuf - 1) + return NULL; + strcpy(hbuf, name); + shorten_hostname(hbuf); + + /* if it hasn't been shortened, there's no point */ + if (strcmp(hbuf, name) != 0) + { + if (tTd(61, 10)) + printf("gethostbyname(%s)... ", hbuf); + h = gethostbyname(hbuf); + } + } + } +#endif + if (tTd(61, 10)) + { + if (h == NULL) + printf("failure\n"); + else + printf("%s\n", h->h_name); + } + return h; +} + +struct hostent * +sm_gethostbyaddr(addr, len, type) + char *addr; + int len; + int type; +{ +#if defined(SOLARIS) && SOLARIS < 204 +# if SOLARIS == 203 + static struct hostent hp; + static char buf[1000]; + extern struct hostent *_switch_gethostbyaddr_r(); + + return _switch_gethostbyaddr_r(addr, len, type, &hp, buf, sizeof(buf), &h_errno); +# else + extern struct hostent *__switch_gethostbyaddr(); + + return __switch_gethostbyaddr(addr, len, type); +# endif +#else + return gethostbyaddr(addr, len, type); +#endif +} +/* +** SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid +*/ + +struct passwd * +sm_getpwnam(user) + char *user; +{ + return getpwnam(user); +} + +struct passwd * +sm_getpwuid(uid) + UID_T uid; +{ + return getpwuid(uid); +} +/* +** LOAD_IF_NAMES -- load interface-specific names into $=w +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Loads $=w with the names of all the interfaces. +*/ + +#ifdef SIOCGIFCONF +struct rtentry; +struct mbuf; +# include <arpa/inet.h> +# ifndef SUNOS403 +# include <sys/time.h> +# endif +# include <net/if.h> +#endif + +void +load_if_names() +{ +#ifdef SIOCGIFCONF + int s; + int i; + struct ifconf ifc; + char interfacebuf[1024]; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) + return; + + /* get the list of known IP address from the kernel */ + ifc.ifc_buf = interfacebuf; + ifc.ifc_len = sizeof interfacebuf; + if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) + { + if (tTd(0, 4)) + printf("SIOGIFCONF failed: %s\n", errstring(errno)); + close(s); + return; + } + close(s); + + /* scan the list of IP address */ + if (tTd(0, 40)) + printf("scanning for interface specific names, ifc_len=%d\n", + ifc.ifc_len); + + for (i = 0; i < ifc.ifc_len; ) + { + struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i]; + struct sockaddr *sa = &ifr->ifr_addr; + struct in_addr ia; + struct hostent *hp; + char ip_addr[256]; + extern char *inet_ntoa(); + extern struct hostent *gethostbyaddr(); + +#ifdef BSD4_4_SOCKADDR + if (sa->sa_len > sizeof ifr->ifr_addr) + i += sizeof ifr->ifr_name + sa->sa_len; + else +#endif + i += sizeof *ifr; + + if (tTd(0, 20)) + printf("%s\n", anynet_ntoa((SOCKADDR *) sa)); + + /* for some reason gcc 2.3 pukes on || here */ + if (!bitset(IFF_UP, ifr->ifr_flags)) + continue; + if (ifr->ifr_addr.sa_family != AF_INET) + continue; + + /* extract IP address from the list*/ + ia = (((struct sockaddr_in *) sa)->sin_addr); + + /* save IP address in text from */ + (void) sprintf(ip_addr, "[%.*s]", + sizeof ip_addr - 3, + inet_ntoa(((struct sockaddr_in *) sa)->sin_addr)); + if (!wordinclass(ip_addr, 'w')) + { + setclass('w', ip_addr); + if (tTd(0, 4)) + printf("\ta.k.a.: %s\n", ip_addr); + } + + /* skip "loopback" interface "lo" */ + if (strcmp("lo0", ifr->ifr_name) == 0) + continue; + + /* lookup name with IP address */ + hp = sm_gethostbyaddr((char *) &ia, sizeof(ia), AF_INET); + if (hp == NULL) + { + syslog(LOG_CRIT, "gethostbyaddr() failed for %.100s\n", + inet_ntoa(ia)); + continue; + } + + /* save its cname */ + if (!wordinclass((char *) hp->h_name, 'w')) + { + setclass('w', (char *) hp->h_name); + if (tTd(0, 4)) + printf("\ta.k.a.: %s\n", hp->h_name); + } + + /* save all it aliases name */ + while (*hp->h_aliases) + { + if (!wordinclass(*hp->h_aliases, 'w')) + { + setclass('w', *hp->h_aliases); + if (tTd(0, 4)) + printf("\ta.k.a.: %s\n", *hp->h_aliases); + } + hp->h_aliases++; + } + } +#endif +} +/* +** HARD_SYSLOG -- call syslog repeatedly until it works +** +** Needed on HP-UX, which apparently doesn't guarantee that +** syslog succeeds during interrupt handlers. +*/ + +#ifdef __hpux + +# define MAXSYSLOGTRIES 100 +# undef syslog + +# ifdef __STDC__ +void +hard_syslog(int pri, char *msg, ...) +# else +hard_syslog(pri, msg, va_alist) + int pri; + char *msg; + va_dcl +# endif +{ + int i; + char buf[SYSLOG_BUFSIZE * 2]; + VA_LOCAL_DECL; + + VA_START(msg); + vsnprintf(buf, sizeof buf, msg, ap); + VA_END; + + for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, "%s", buf) < 0; ) + continue; +} + +#endif +/* +** LOCAL_HOSTNAME_LENGTH +** +** This is required to get sendmail to compile against BIND 4.9.x +** on Ultrix. +*/ + +#if defined(ultrix) && NAMED_BIND + +# include <resolv.h> +# if __RES >= 19931104 && __RES < 19950621 + +int +local_hostname_length(hostname) + char *hostname; +{ + int len_host, len_domain; + + if (!*_res.defdname) + res_init(); + len_host = strlen(hostname); + len_domain = strlen(_res.defdname); + if (len_host > len_domain && + (strcasecmp(hostname + len_host - len_domain,_res.defdname) == 0) && + hostname[len_host - len_domain - 1] == '.') + return len_host - len_domain - 1; + else + return 0; +} + +# endif +#endif +/* +** Compile-Time options +*/ + +char *CompileOptions[] = +{ +#if HESIOD + "HESIOD", +#endif +#if HES_GETMAILHOST + "HES_GETMAILHOST", +#endif +#ifdef LOG + "LOG", +#endif +#if MATCHGECOS + "MATCHGECOS", +#endif +#if MIME8TO7 + "MIME8TO7", +#endif +#if NAMED_BIND + "NAMED_BIND", +#endif +#if NDBM + "NDBM", +#endif +#if NETINET + "NETINET", +#endif +#if NETINFO + "NETINFO", +#endif +#if NETISO + "NETISO", +#endif +#if NETNS + "NETNS", +#endif +#if NETUNIX + "NETUNIX", +#endif +#if NETX25 + "NETX25", +#endif +#if NEWDB + "NEWDB", +#endif +#if NIS + "NIS", +#endif +#if NISPLUS + "NISPLUS", +#endif +#if SCANF + "SCANF", +#endif +#if SUID_ROOT_FILES_OK + "SUID_ROOT_FILES_OK", +#endif +#if USERDB + "USERDB", +#endif +#if XDEBUG + "XDEBUG", +#endif +#if XLA + "XLA", +#endif + NULL +}; + + +/* +** OS compile options. +*/ + +char *OsCompileOptions[] = +{ +#if HASFCHMOD + "HASFCHMOD", +#endif +#if HASFLOCK + "HASFLOCK", +#endif +#if HASGETUSERSHELL + "HASGETUSERSHELL", +#endif +#if HASINITGROUPS + "HASINITGROUPS", +#endif +#if HASLSTAT + "HASLSTAT", +#endif +#if HASSETREUID + "HASSETREUID", +#endif +#if HASSETSID + "HASSETSID", +#endif +#if HASSETVBUF + "HASSETVBUF", +#endif +#if HASSNPRINTF + "HASSNPRINTF", +#endif +#if HASUNAME + "HASUNAME", +#endif +#if IDENTPROTO + "IDENTPROTO", +#endif +#if IP_SRCROUTE + "IP_SRCROUTE", +#endif +#if NEEDFSYNC + "NEEDFSYNC", +#endif +#if NOFTRUNCATE + "NOFTRUNCATE", +#endif +#if SYS5SETPGRP + "SYS5SETPGRP", +#endif +#if SYSTEM5 + "SYSTEM5", +#endif +#if USESETEUID + "USESETEUID", +#endif + NULL +}; diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h new file mode 100644 index 000000000000..30bb9d1e2e6b --- /dev/null +++ b/usr.sbin/sendmail/src/conf.h @@ -0,0 +1,1807 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)conf.h 8.219 (Berkeley) 11/11/95 + */ + +/* +** CONF.H -- All user-configurable parameters for sendmail +** +** Send updates to sendmail@Sendmail.ORG so they will be +** included in the next release. +*/ + +struct rusage; /* forward declaration to get gcc to shut up in wait.h */ + +# include <sys/param.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <sys/file.h> +# include <sys/wait.h> +# include <limits.h> +# include <fcntl.h> +# include <signal.h> +# include <netdb.h> +# include <pwd.h> + +/********************************************************************** +** Table sizes, etc.... +** There shouldn't be much need to change these.... +**********************************************************************/ + +# define MAXLINE 2048 /* max line length */ +# define MAXNAME 256 /* max length of a name */ +# define MAXPV 40 /* max # of parms to mailers */ +# define MAXATOM 200 /* max atoms per address */ +# define MAXMAILERS 25 /* maximum mailers known to system */ +# define MAXRWSETS 200 /* max # of sets of rewriting rules */ +# define MAXPRIORITIES 25 /* max values for Precedence: field */ +# define MAXMXHOSTS 20 /* max # of MX records */ +# define SMTPLINELIM 990 /* maximum SMTP line length */ +# define MAXKEY 128 /* maximum size of a database key */ +# define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */ +# define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */ +# define MAXALIASDB 12 /* max # of alias databases */ +# define MAXMAPSTACK 12 /* max # of stacked or sequenced maps */ +# define MAXTOCLASS 8 /* max # of message timeout classes */ +# define MAXMIMEARGS 20 /* max args in Content-Type: */ +# define MAXMIMENESTING 20 /* max MIME multipart nesting */ +# define QUEUESEGSIZE 1000 /* increment for queue size */ + +/********************************************************************** +** Compilation options. +** #define these to 1 if they are available; +** #define them to 0 otherwise. +** All can be overridden from Makefile. +**********************************************************************/ + +# ifndef NETINET +# define NETINET 1 /* include internet support */ +# endif + +# ifndef NETISO +# define NETISO 0 /* do not include ISO socket support */ +# endif + +# ifndef NAMED_BIND +# define NAMED_BIND 1 /* use Berkeley Internet Domain Server */ +# endif + +# ifndef XDEBUG +# define XDEBUG 1 /* enable extended debugging */ +# endif + +# ifndef MATCHGECOS +# define MATCHGECOS 1 /* match user names from gecos field */ +# endif + +# ifndef DSN +# define DSN 1 /* include delivery status notification code */ +# endif + +# if !defined(USERDB) && (defined(NEWDB) || defined(HESIOD)) +# define USERDB 1 /* look in user database */ +# endif + +# ifndef MIME8TO7 +# define MIME8TO7 1 /* 8->7 bit MIME conversions */ +# endif + +# ifndef MIME7TO8 +# define MIME7TO8 1 /* 7->8 bit MIME conversions */ +# endif + +/********************************************************************** +** "Hard" compilation options. +** #define these if they are available; comment them out otherwise. +** These cannot be overridden from the Makefile, and should really not +** be turned off unless absolutely necessary. +**********************************************************************/ + +# define LOG /* enable logging -- don't turn off */ + +/********************************************************************** +** End of site-specific configuration. +**********************************************************************/ +/* +** General "standard C" defines. +** +** These may be undone later, to cope with systems that claim to +** be Standard C but aren't. Gcc is the biggest offender -- it +** doesn't realize that the library is part of the language. +** +** Life would be much easier if we could get rid of this sort +** of bozo problems. +*/ + +#ifdef __STDC__ +# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ +#endif + +/* +** Assume you have standard calls; can be #undefed below if necessary. +*/ + +# define HASLSTAT 1 /* has lstat(2) call */ +/********************************************************************** +** Operating system configuration. +** +** Unless you are porting to a new OS, you shouldn't have to +** change these. +**********************************************************************/ + +/* +** HP-UX -- tested for 8.07, 9.00, and 9.01. +** +** If V4FS is defined, compile for HP-UX 10.0. +*/ + +#ifdef __hpux + /* common definitions for HP-UX 9.x and 10.x */ +# undef m_flags /* conflict between db.h & sys/sysmacros.h on HP 300 */ +# define SYSTEM5 1 /* include all the System V defines */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define USESETEUID 1 /* has useable seteuid(2) call */ +# define seteuid(e) setresuid(-1, e, -1) +# define IP_SRCROUTE 1 /* can check IP source routing */ +# define LA_TYPE LA_HPUX +# define SPT_TYPE SPT_PSTAT +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# define GIDSET_T gid_t +# ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */ +# endif +# define syslog hard_syslog +# ifdef __STDC__ +extern void hard_syslog(int, char *, ...); +# endif + +# ifdef V4FS + /* HP-UX 10.x */ +# define _PATH_UNIX "/stand/vmunix" +# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid" +# endif +# ifndef IDENTPROTO +# define IDENTPROTO 1 /* TCP/IP implementation fixed in 10.0 */ +# endif + +# else + /* HP-UX 9.x */ +# define _PATH_UNIX "/hp-ux" +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# endif + +#endif + + +/* +** IBM AIX 3.x -- actually tested for 3.2.3 +*/ + +#ifdef _AIX3 +# include <paths.h> +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */ +# define FORK fork /* no vfork primitive available */ +# define GIDSET_T gid_t +# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ +# define SPT_PADCHAR '\0' /* pad process title with nulls */ +# define LA_TYPE LA_INT +# define LA_AVENRUN "avenrun" +#endif + + +/* +** Silicon Graphics IRIX +** +** Compiles on 4.0.1. +** +** Use IRIX64 instead of IRIX for 64-bit IRIX (6.0). +** Use IRIX5 instead of IRIX for IRIX 5.x. +** +** IRIX64 changes from Mark R. Levinson <ml@cvdev.rochester.edu>. +** IRIX5 changes from Kari E. Hurtta <Kari.Hurtta@fmi.fi>. +*/ + +#if defined(IRIX64) || defined(IRIX5) +# define IRIX +#endif + +#ifdef IRIX +# define SYSTEM5 1 /* this is a System-V derived system */ +# define HASSETREUID 1 /* has setreuid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define IP_SRCROUTE 1 /* can check IP source routing */ +# define FORK fork /* no vfork primitive available */ +# define setpgid BSDsetpgrp +# define GIDSET_T gid_t +# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ +# define SFS_BAVAIL f_bfree /* alternate field name */ +# define LA_TYPE LA_INT +# ifdef IRIX64 +# define NAMELISTMASK 0x7fffffffffffffff /* mask for nlist() values */ +# else +# define NAMELISTMASK 0x7fffffff /* mask for nlist() values */ +# endif +# if defined(IRIX64) || defined(IRIX5) +# define ARGV_T char *const * +# define HASSETRLIMIT 1 /* has setrlimit(2) syscall */ +# define HASGETDTABLESIZE 1 /* has getdtablesize(2) syscall */ +# else +# define ARGV_T const char ** +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# endif +#endif + + +/* +** SunOS and Solaris +** +** Tested on SunOS 4.1.x (a.k.a. Solaris 1.1.x) and +** Solaris 2.4 (a.k.a. SunOS 5.4). +*/ + +#if defined(sun) && !defined(BSD) + +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define IP_SRCROUTE 1 /* can check IP source routing */ +# define LA_TYPE LA_INT + +# ifdef SOLARIS_2_3 +# define SOLARIS 203 /* for back compat only -- use -DSOLARIS=203 */ +# endif + +# ifdef SOLARIS + /* Solaris 2.x (a.k.a. SunOS 5.x) */ +# ifndef __svr4__ +# define __svr4__ /* use all System V Releae 4 defines below */ +# endif +# include <sys/time.h> +# define GIDSET_T gid_t +# ifndef _PATH_UNIX +# define _PATH_UNIX "/dev/ksyms" +# endif +# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid" +# endif +# ifndef _PATH_HOSTS +# define _PATH_HOSTS "/etc/inet/hosts" +# endif +# ifndef SYSLOG_BUFSIZE +# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */ +# endif + +# else + /* SunOS 4.0.3 or 4.1.x */ +# define HASSETREUID 1 /* has setreuid(2) call */ +# ifndef HASFLOCK +# define HASFLOCK 1 /* has flock(2) call */ +# endif +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */ +# include <vfork.h> + +# ifdef SUNOS403 + /* special tweaking for SunOS 4.0.3 */ +# include <malloc.h> +# define BSD4_3 1 /* 4.3 BSD-based */ +# define NEEDSTRSTR 1 /* need emulation of strstr(3) routine */ +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# undef WIFEXITED +# undef WEXITSTATUS +# undef HASUNAME +# define setpgid setpgrp +typedef int pid_t; +extern char *getenv(); + +# else + /* 4.1.x specifics */ +# define HASSETSID 1 /* has Posix setsid(2) call */ +# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ + +# endif +# endif +#endif + +/* +** DG/UX +** +** Tested on 5.4.2 and 5.4.3. Use DGUX_5_4_2 to get the +** older support. +** 5.4.3 changes from Mark T. Robinson <mtr@ornl.gov>. +*/ + +#ifdef DGUX_5_4_2 +# define DGUX 1 +#endif + +#ifdef DGUX +# define SYSTEM5 1 +# define LA_TYPE LA_DGUX +# define HASSETREUID 1 /* has setreuid(2) call */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASSETSID 1 /* has Posix setsid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define IP_SRCROUTE 0 /* does not have <netinet/ip_var.h> */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) */ +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# define SPT_TYPE SPT_NONE /* don't use setproctitle */ +# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ + +/* these include files must be included early on DG/UX */ +# include <netinet/in.h> +# include <arpa/inet.h> + +/* compiler doesn't understand const? */ +# define const + +# ifdef DGUX_5_4_2 +# define inet_addr dgux_inet_addr +extern long dgux_inet_addr(); +# endif +#endif + + +/* +** Digital Ultrix 4.2A or 4.3 +** +** Apparently, fcntl locking is broken on 4.2A, in that locks are +** not dropped when the process exits. This causes major problems, +** so flock is the only alternative. +*/ + +#ifdef ultrix +# define HASSETREUID 1 /* has setreuid(2) call */ +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# ifndef HASFLOCK +# define HASFLOCK 1 /* has flock(2) call */ +# endif +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# ifndef BROKEN_RES_SEARCH +# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */ +# endif +# ifdef vax +# define LA_TYPE LA_FLOAT +# else +# define LA_TYPE LA_INT +# define LA_AVENRUN "avenrun" +# endif +# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* pre-4.4 TCP/IP implementation is broken */ +# endif +#endif + + +/* +** OSF/1 for KSR. +** +** Contributed by Todd C. Miller <Todd.Miller@cs.colorado.edu> +*/ + +#ifdef __ksr__ +# define __osf__ 1 /* get OSF/1 defines below */ +# define FORK fork /* no vfork primitive available */ +# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf" +# ifndef TZ_TYPE +# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */ +# endif +#endif + + +/* +** OSF/1 for Intel Paragon. +** +** Contributed by Jeff A. Earickson <jeff@ssd.intel.com> +** of Intel Scalable Systems Divison. +*/ + +#ifdef __PARAGON__ +# define __osf__ 1 /* get OSF/1 defines below */ +# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf" +#endif + + +/* +** OSF/1 (tested on Alpha) +*/ + +#ifdef __osf__ +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# define USESETEUID 1 /* has useable seteuid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define IP_SRCROUTE 1 /* can check IP source routing */ +# ifndef HASFLOCK +# define HASFLOCK 1 /* has flock(2) call */ +# endif +# define LA_TYPE LA_INT +# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/var/run/sendmail.pid" +# endif +#endif + + +/* +** NeXTstep +*/ + +#ifdef NeXT +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define NEEDPUTENV 2 /* need putenv(3) call; no setenv(3) call */ +# ifndef HASFLOCK +# define HASFLOCK 1 /* has flock(2) call */ +# endif +# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# define UID_T int /* compiler gripes on uid_t */ +# define sleep sleepX +# define setpgid setpgrp +# ifndef LA_TYPE +# define LA_TYPE LA_MACH +# endif +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# ifndef _POSIX_SOURCE +typedef int pid_t; +# undef WEXITSTATUS +# undef WIFEXITED +# endif +# define _PATH_VENDOR_CF "/etc/sendmail/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/sendmail/sendmail.pid" +# endif +#endif + + +/* +** 4.4 BSD +** +** See also BSD defines. +*/ + +#if defined(BSD4_4) && !defined(__bsdi__) +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# define USESETEUID 1 /* has useable seteuid(2) call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ +# include <sys/cdefs.h> +# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ +# define BSD4_4_SOCKADDR /* has sa_len */ +# define NETLINK 1 /* supports AF_LINK */ +# ifndef LA_TYPE +# define LA_TYPE LA_SUBR +# endif +# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ +# define SPT_TYPE SPT_PSSTRINGS /* use PS_STRINGS pointer */ +#endif + + +/* +** BSD/386 (all versions) +** From Tony Sanders, BSDI +*/ + +#ifdef __bsdi__ +# define HASUNSETENV 1 /* has the unsetenv(3) call */ +# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ +# define USESETEUID 1 /* has useable seteuid(2) call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ +# define HASUNAME 1 /* has uname(2) syscall */ +# include <sys/cdefs.h> +# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ +# define BSD4_4_SOCKADDR /* has sa_len */ +# define NETLINK 1 /* supports AF_LINK */ +# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ +# ifndef LA_TYPE +# define LA_TYPE LA_SUBR +# endif +# define GIDSET_T gid_t +# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312 + /* version 1.1 or later */ +# undef SPT_TYPE +# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ +# else + /* version 1.0 or earlier */ +# ifndef OLD_NEWDB +# define OLD_NEWDB 1 /* old version of newdb library */ +# endif +# define SPT_PADCHAR '\0' /* pad process title with nulls */ +# endif +#endif + + + +/* +** FreeBSD / NetBSD (all architectures, all versions) +** +** 4.3BSD clone, closer to 4.4BSD for FreeBSD 1.x and NetBSD 0.9x +** 4.4BSD-Lite based for FreeBSD 2.x and NetBSD 1.x +** +** See also BSD defines. +*/ + +#if defined(__FreeBSD__) || defined(__NetBSD__) +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ +# define USESETEUID 1 /* has useable seteuid(2) call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ +# define HASUNAME 1 /* has uname(2) syscall */ +# include <sys/cdefs.h> +# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ +# define BSD4_4_SOCKADDR /* has sa_len */ +# define NETLINK 1 /* supports AF_LINK */ +# define GIDSET_T gid_t +# ifndef LA_TYPE +# define LA_TYPE LA_SUBR +# endif +# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ +# if defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1) +# undef SPT_TYPE +# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ +# define setreuid __setreuid +# endif +#endif + + +/* +** Mach386 +** +** For mt Xinu's Mach386 system. +*/ + +#if defined(MACH) && defined(i386) +# define MACH386 1 +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# ifndef HASFLOCK +# define HASFLOCK 1 /* has flock(2) call */ +# endif +# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ +# define NEEDSTRTOL 1 /* need the strtol() function */ +# define setpgid setpgrp +# ifndef LA_TYPE +# define LA_TYPE LA_FLOAT +# endif +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# undef HASSETVBUF /* don't actually have setvbuf(3) */ +# undef WEXITSTATUS +# undef WIFEXITED +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/sendmail.pid" +# endif +#endif + + +/* +** 4.3 BSD -- this is for very old systems +** +** Should work for mt Xinu MORE/BSD and Mips UMIPS-BSD 2.1. +** +** You'll also have to install a new resolver library. +** I don't guarantee that support for this environment is complete. +*/ + +#if defined(oldBSD43) || defined(MORE_BSD) || defined(umipsbsd) +# define NEEDVPRINTF 1 /* need a replacement for vprintf(3) */ +# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ +# define ARBPTR_T char * +# define setpgid setpgrp +# ifndef LA_TYPE +# define LA_TYPE LA_FLOAT +# endif +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# undef WEXITSTATUS +# undef WIFEXITED +typedef short pid_t; +extern int errno; +#endif + + +/* +** SCO Unix +** +** This includes two parts -- the first is for SCO Open Server 3.2v4 +** (contributed by Philippe Brand <phb@colombo.telesys-innov.fr>). +** The second is, I believe, for an older version. +*/ + +#ifdef _SCO_unix_4_2 +# define _SCO_unix_ +# define HASSETREUID 1 /* has setreuid(2) call */ +# define _PATH_UNIX "/unix" +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/sendmail.pid" +# endif +#endif + +#ifdef _SCO_unix_ +# include <sys/stream.h> /* needed for IP_SRCROUTE */ +# define SYSTEM5 1 /* include all the System V defines */ +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define NEEDFSYNC 1 /* needs the fsync(2) call stub */ +# define FORK fork +# define MAXPATHLEN PATHSIZE +# define LA_TYPE LA_SHORT +# define SFS_TYPE SFS_4ARGS /* use <sys/statfs.h> 4-arg impl */ +# define SFS_BAVAIL f_bfree /* alternate field name */ +# define SPT_TYPE SPT_SCO /* write kernel u. area */ +# define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */ +# define NETUNIX 0 /* no unix domain socket support */ +#endif + + +/* +** ISC (SunSoft) Unix. +** +** Contributed by J.J. Bailey <jjb@jagware.bcc.com> +*/ + +#ifdef ISC_UNIX +# include <net/errno.h> +# include <sys/stream.h> /* needed for IP_SRCROUTE */ +# include <sys/bsdtypes.h> +# define SYSTEM5 1 /* include all the System V defines */ +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define HASSETREUID 1 /* has setreuid(2) call */ +# define NEEDFSYNC 1 /* needs the fsync(2) call stub */ +# define NETUNIX 0 /* no unix domain socket support */ +# define FORK fork +# define MAXPATHLEN 1024 +# define LA_TYPE LA_SHORT +# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ +# define SFS_BAVAIL f_bfree /* alternate field name */ +# define _PATH_UNIX "/unix" +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/sendmail.pid" +# endif + +#endif + + +/* +** Altos System V. +** Contributed by Tim Rice <timr@crl.com>. +*/ + +#ifdef ALTOS_SYS_V +# define SYSTEM5 1 /* include all the System V defines */ +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# define NEEDFSYNC 1 /* no fsync(2) in system library */ +# define FORK fork +# define MAXPATHLEN PATHSIZE +# define LA_TYPE LA_SHORT +# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ +# define SFS_BAVAIL f_bfree /* alternate field name */ +# define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */ +# define NETUNIX 0 /* no unix domain socket support */ +# undef WIFEXITED +# undef WEXITSTATUS +# define strtoul strtol /* gcc library bogosity */ + +typedef unsigned short uid_t; +typedef unsigned short gid_t; +typedef short pid_t; +#endif + + +/* +** ConvexOS 11.0 and later +** +** "Todd C. Miller" <millert@mroe.cs.colorado.edu> claims this +** works on 9.1 as well. +*/ + +#ifdef _CONVEX_SOURCE +# define BSD 1 /* include all the BSD defines */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ +# define NEEDGETOPT 1 /* need replacement for getopt(3) */ +# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */ +# define LA_TYPE LA_FLOAT +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef S_IREAD +# define S_IREAD _S_IREAD +# define S_IWRITE _S_IWRITE +# define S_IEXEC _S_IEXEC +# define S_IFMT _S_IFMT +# define S_IFCHR _S_IFCHR +# define S_IFBLK _S_IFBLK +# endif +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +#endif + + +/* +** RISC/os 4.52 +** +** Gives a ton of warning messages, but otherwise compiles. +*/ + +#ifdef RISCOS + +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# ifndef HASFLOCK +# define HASFLOCK 1 /* has flock(2) call */ +# endif +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ +# define NEEDPUTENV 1 /* need putenv(3) call */ +# define NEEDSTRSTR 1 /* need emulation of the strstr(3) call */ +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# define LA_TYPE LA_INT +# define LA_AVENRUN "avenrun" +# define _PATH_UNIX "/unix" +# undef WIFEXITED + +# define setpgid setpgrp + +extern int errno; +typedef int pid_t; +#define SIGFUNC_DEFINED +typedef int (*sigfunc_t)(); +extern char *getenv(); +extern void *malloc(); + +# include <sys/time.h> + +#endif + + +/* +** Linux 0.99pl10 and above... +** +** Thanks to, in reverse order of contact: +** +** John Kennedy <warlock@csuchico.edu> +** Andrew Pam <avatar@aus.xanadu.com> +** Florian La Roche <rzsfl@rz.uni-sb.de> +** Karl London <karl@borg.demon.co.uk> +** +** Last compiled against: [09/06/95 @ 10:20:58 AM (Wednesday)] +** sendmail 8.7-b14 named 4.9.3-beta17 db-1.85 +** gcc 2.7.0 libc-5.2.7 linux 1.2.13 +*/ + +#ifdef __linux__ +# define BSD 1 /* include BSD defines */ +# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# ifndef HASSNPRINTF +# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ +# endif +# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ +# define GIDSET_T gid_t /* from <linux/types.h> */ +# define HASGETUSERSHELL 0 /* getusershell(3) broken in Slackware 2.0 */ +# define IP_SRCROUTE 0 /* linux <= 1.2.8 doesn't support IP_OPTIONS */ +# ifndef HASFLOCK +# define HASFLOCK 0 /* flock(2) is broken after 0.99.13 */ +# endif +# ifndef LA_TYPE +# define LA_TYPE LA_PROCSTR +# endif +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() impl */ +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/var/run/sendmail.pid" +# endif +# define TZ_TYPE TZ_TNAME +# include <sys/sysmacros.h> +# undef atol /* wounded in <stdlib.h> */ +#endif + + +/* +** DELL SVR4 Issue 2.2, and others +** From Kimmo Suominen <kim@grendel.lut.fi> +** +** It's on #ifdef DELL_SVR4 because Solaris also gets __svr4__ +** defined, and the definitions conflict. +** +** Peter Wemm <peter@perth.DIALix.oz.au> claims that the setreuid +** trick works on DELL 2.2 (SVR4.0/386 version 4.0) and ESIX 4.0.3A +** (SVR4.0/386 version 3.0). +*/ + +#ifdef DELL_SVR4 + /* no changes necessary */ + /* see general __svr4__ defines below */ +#endif + + +/* +** Apple A/UX 3.0 +*/ + +#ifdef _AUX_SOURCE +# include <sys/sysmacros.h> +# define BSD /* has BSD routines */ +# define HASSETRLIMIT 0 /* ... but not setrlimit(2) */ +# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ +# define SIGFUNC_DEFINED /* sigfunc_t already defined */ +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# define FORK fork +# ifndef LA_TYPE +# define LA_TYPE LA_INT +# define FSHIFT 16 +# endif +# define LA_AVENRUN "avenrun" +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# define TZ_TYPE TZ_TZNAME +# ifndef _PATH_UNIX +# define _PATH_UNIX "/unix" /* should be in <paths.h> */ +# endif +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# undef WIFEXITED +# undef WEXITSTATUS +#endif + + +/* +** Encore UMAX V +** +** Not extensively tested. +*/ + +#ifdef UMAXV +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */ +# define FORK fork /* no vfork(2) primitive available */ +# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ +# define MAXPATHLEN PATH_MAX +extern struct passwd *getpwent(), *getpwnam(), *getpwuid(); +extern struct group *getgrent(), *getgrnam(), *getgrgid(); +# undef WIFEXITED +# undef WEXITSTATUS +#endif + + +/* +** Stardent Titan 3000 running TitanOS 4.2. +** +** Must be compiled in "cc -43" mode. +** +** From Kate Hedstrom <kate@ahab.rutgers.edu>. +** +** Note the tweaking below after the BSD defines are set. +*/ + +#ifdef titan +# define setpgid setpgrp +typedef int pid_t; +# undef WIFEXITED +# undef WEXITSTATUS +#endif + + +/* +** Sequent DYNIX 3.2.0 +** +** From Jim Davis <jdavis@cs.arizona.edu>. +*/ + +#ifdef sequent + +# define BSD 1 +# define HASUNSETENV 1 +# define BSD4_3 1 /* to get signal() in conf.c */ +# define WAITUNION 1 +# define LA_TYPE LA_FLOAT +# ifdef _POSIX_VERSION +# undef _POSIX_VERSION /* set in <unistd.h> */ +# endif +# undef HASSETVBUF /* don't actually have setvbuf(3) */ +# define setpgid setpgrp + +/* Have to redefine WIFEXITED to take an int, to work with waitfor() */ +# undef WIFEXITED +# define WIFEXITED(s) (((union wait*)&(s))->w_stopval != WSTOPPED && \ + ((union wait*)&(s))->w_termsig == 0) +# define WEXITSTATUS(s) (((union wait*)&(s))->w_retcode) +typedef int pid_t; +# define isgraph(c) (isprint(c) && (c != ' ')) + +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif + +# ifndef _PATH_UNIX +# define _PATH_UNIX "/dynix" +# endif +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" + +#endif + + +/* +** Sequent DYNIX/ptx v2.0 (and higher) +** +** For DYNIX/ptx v1.x, undefine HASSETREUID. +** +** From Tim Wright <timw@sequent.com>. +*/ + +#ifdef _SEQUENT_ +# define SYSTEM5 1 /* include all the System V defines */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASSETREUID 1 /* has setreuid(2) call */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define GIDSET_T gid_t +# define LA_TYPE LA_INT +# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ +# define SPT_TYPE SPT_NONE /* don't use setproctitle */ +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/sendmail.pid" +# endif +#endif + + +/* +** Cray Unicos +** +** Ported by David L. Kensiski, Sterling Sofware <kensiski@nas.nasa.gov> +*/ + +#ifdef UNICOS +# define SYSTEM5 1 /* include all the System V defines */ +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define MAXPATHLEN PATHSIZE +# define LA_TYPE LA_ZERO +# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ +# define SFS_BAVAIL f_bfree /* alternate field name */ +#endif + + +/* +** Apollo DomainOS +** +** From Todd Martin <tmartint@tus.ssi1.com> & Don Lewis <gdonl@gv.ssi1.com> +** +** 15 Jan 1994; updated 2 Aug 1995 +** +*/ + +#ifdef apollo +# define HASSETREUID 1 /* has setreuid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(2) call */ +# define IP_SRCROUTE 0 /* does not have <netinet/ip_var.h> */ +# define SPT_TYPE SPT_NONE /* don't use setproctitle */ +# define LA_TYPE LA_SUBR /* use getloadavg.c */ +# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ +# define SFS_BAVAIL f_bfree /* alternate field name */ +# define TZ_TYPE TZ_TZNAME +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/sendmail.pid" +# endif +# undef S_IFSOCK /* S_IFSOCK and S_IFIFO are the same */ +# undef S_IFIFO +# define S_IFIFO 0010000 +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +#endif + + +/* +** UnixWare 2.x +*/ + +#ifdef UNIXWARE2 +# define UNIXWARE 1 +# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ +#endif + + +/* +** UnixWare 1.1.2. +** +** Updated by Petr Lampa <lampa@fee.vutbr.cz>. +** From Evan Champion <evanc@spatial.synapse.org>. +*/ + +#ifdef UNIXWARE +# include <sys/mkdev.h> +# define SYSTEM5 1 +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define HASSETREUID 1 +# define HASSETSID 1 +# define HASINITGROUPS 1 +# define GIDSET_T gid_t +# define SLEEP_T unsigned +# define SFS_TYPE SFS_STATVFS +# define LA_TYPE LA_ZERO +# undef WIFEXITED +# undef WEXITSTATUS +# define _PATH_UNIX "/unix" +# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid" +# endif +# define SYSLOG_BUFSIZE 128 +#endif + + +/* +** Intergraph CLIX 3.1 +** +** From Paul Southworth <pauls@locust.cic.net> +*/ + +#ifdef CLIX +# define SYSTEM5 1 /* looks like System V */ +# ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# endif +# define DEV_BSIZE 512 /* device block size not defined */ +# define GIDSET_T gid_t +# undef LOG /* syslog not available */ +# define NEEDFSYNC 1 /* no fsync in system library */ +# define GETSHORT _getshort +#endif + + +/* +** NCR 3000 Series (SysVr4) +** +** From Kevin Darcy <kevin@tech.mis.cfc.com>. +*/ + +#ifdef NCR3000 +# include <sys/sockio.h> +# define __svr4__ +# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */ +# undef BSD +# define LA_AVENRUN "avenrun" +# define SYSLOG_BUFSIZE 1024 +#endif + + +/* +** Tandem NonStop-UX SVR4 +** +** From Rick McCarty <mccarty@mpd.tandem.com>. +*/ + +#ifdef NonStop_UX_BXX +# define __svr4__ +#endif + + +/* +** Hitachi 3050R & 3050RX Workstations running HI-UX/WE2. +** +** Tested for 1.04 and 1.03 +** From Akihiro Hashimoto ("Hash") <hash@dominic.ipc.chiba-u.ac.jp>. +*/ + +#ifdef __H3050R +# define SYSTEM5 1 /* include all the System V defines */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define setreuid(r, e) setresuid(r, e, -1) +# define LA_TYPE LA_FLOAT +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# define HASSETVBUF /* HI-UX has no setlinebuf */ +# ifndef GIDSET_T +# define GIDSET_T gid_t +# endif +# ifndef _PATH_UNIX +# define _PATH_UNIX "/HI-UX" +# endif +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */ +# endif + +/* avoid m_flags conflict between db.h & sys/sysmacros.h on HIUX 3050 */ +# undef m_flags + +# ifdef __STDC__ +extern int syslog(int, char *, ...); +# endif + +#endif + + +/* +** Amdahl UTS System V 2.1.5 (SVr3-based) +** +** From: Janet Jackson <janet@dialix.oz.au>. +*/ + +#ifdef _UTS +# include <sys/sysmacros.h> +# undef HASLSTAT /* has symlinks, but they cause problems */ +# define NEEDFSYNC 1 /* system fsync(2) fails on non-EFS filesys */ +# define SYS5SIGNALS 1 /* System V signal semantics */ +# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASINITGROUPS 1 /* has initgroups(3) function */ +# define HASSETVBUF 1 /* has setvbuf(3) function */ +# define HASSIGSETMASK 0 /* does not have sigsetmask(2) function */ +# ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 0 /* does not have getusershell(3) function */ +# endif +# define GIDSET_T gid_t /* type of 2nd arg to getgroups(2) isn't int */ +# define LA_TYPE LA_ZERO /* doesn't have load average */ +# define SFS_TYPE SFS_4ARGS /* use 4-arg statfs() */ +# define SFS_BAVAIL f_bfree /* alternate field name */ +# define _PATH_UNIX "/unix" +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +#endif + +/* +** Cray Computer Corporation's CSOS +** +** From Scott Bolte <scott@craycos.com>. +*/ + +#ifdef _CRAYCOM +# define SYSTEM5 1 /* include all the System V defines */ +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define NEEDFSYNC 1 /* no fsync in system library */ +# define MAXPATHLEN PATHSIZE +# define LA_TYPE LA_ZERO +# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ +# define SFS_BAVAIL f_bfree /* alternate field name */ +# define _POSIX_CHOWN_RESTRICTED -1 +extern struct group *getgrent(), *getgrnam(), *getgrgid(); +#endif + + +/* +** Sony NEWS-OS 4.2.1R and 6.0.3 +** +** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>. +*/ + +#ifdef sony_news +# ifndef __svr4 + /* NEWS-OS 4.2.1R */ +# ifndef BSD +# define BSD /* has BSD routines */ +# endif +# define HASUNSETENV 1 /* has unsetenv(2) call */ +# undef HASSETVBUF /* don't actually have setvbuf(3) */ +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# define LA_TYPE LA_INT +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# ifndef HASFLOCK +# define HASFLOCK 1 /* has flock(2) call */ +# endif +# define setpgid setpgrp +# undef WIFEXITED +# undef WEXITSTATUS +typedef int pid_t; +typedef int (*sigfunc_t)(); +# define SIGFUNC_DEFINED + +# else + /* NEWS-OS 6.0.3 with /bin/cc */ +# ifndef __svr4__ +# define __svr4__ /* use all System V Releae 4 defines below */ +# endif +# define HASSETSID 1 /* has Posix setsid(2) call */ +# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */ +# define LA_TYPE LA_READKSYM /* use MIOC_READKSYM ioctl */ +# ifndef SPT_TYPE +# define SPT_TYPE SPT_SYSMIPS /* use sysmips() (OS 6.0.2 or later) */ +# endif +# define GIDSET_T gid_t +# undef WIFEXITED +# undef WEXITSTATUS +# ifndef SYSLOG_BUFSIZE +# define SYSLOG_BUFSIZE 1024 +# endif +# define _PATH_UNIX "/stand/unix" +# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid" +# endif + +# endif +#endif + + +/* +** Omron LUNA/UNIOS-B 3.0, LUNA2/Mach and LUNA88K Mach +** +** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>. +*/ + +#ifdef luna +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# define HASUNSETENV 1 /* has unsetenv(2) call */ +# define NEEDPUTENV 1 /* need putenv(3) call */ +# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ +# define NEEDSTRSTR 1 /* need emulation of the strstr(3) call */ +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# ifdef uniosb +# include <sys/time.h> +# define NEEDVPRINTF 1 /* need a replacement for vprintf(3) */ +# define LA_TYPE LA_INT +# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */ +# endif +# ifdef luna2 +# define LA_TYPE LA_SUBR +# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */ +# endif +# ifdef luna88k +# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ +# define LA_TYPE LA_INT +# endif +# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ +# define setpgid setpgrp +# undef WIFEXITED +# undef WEXITSTATUS +typedef int pid_t; +typedef int (*sigfunc_t)(); +# define SIGFUNC_DEFINED +extern char *getenv(); +extern int errno; +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +#endif + + +/* +** NEC EWS-UX/V 4.2 (with /usr/ucb/cc) +** +** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>. +*/ + +#if defined(nec_ews_svr4) || defined(_nec_ews_svr4) +# ifndef __svr4__ +# define __svr4__ /* use all System V Releae 4 defines below */ +# endif +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define HASSETSID 1 /* has Posix setsid(2) call */ +# define LA_TYPE LA_READKSYM /* use MIOC_READSYM ioctl */ +# define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */ +# define GIDSET_T gid_t +# undef WIFEXITED +# undef WEXITSTATUS +# define NAMELISTMASK 0x7fffffff /* mask for nlist() values */ +# ifndef SYSLOG_BUFSIZE +# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */ +# endif +#endif + + +/* +** Fujitsu/ICL UXP/DS (For the DS/90 Series) +** +** From Diego R. Lopez <drlopez@cica.es>. +*/ + +#ifdef UXPDS +# define __svr4__ +# define HASGETUSERSHELL 1 +# define HASFLOCK 0 +# define _PATH_UNIX "/stand/unix" +# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf" +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid" +# endif +#endif + + + +/********************************************************************** +** End of Per-Operating System defines +**********************************************************************/ +/********************************************************************** +** More general defines +**********************************************************************/ + +/* general BSD defines */ +#ifdef BSD +# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */ +# define HASSETREUID 1 /* has setreuid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# ifndef IP_SRCROUTE +# define IP_SRCROUTE 1 /* can check IP source routing */ +# endif +# ifndef HASSETRLIMIT +# define HASSETRLIMIT 1 /* has setrlimit(2) call */ +# endif +# ifndef HASFLOCK +# define HASFLOCK 1 /* has flock(2) call */ +# endif +# ifndef TZ_TYPE +# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone variable */ +# endif +#endif + +/* general System V Release 4 defines */ +#ifdef __svr4__ +# define SYSTEM5 1 +# define USESETEUID 1 /* has useable seteuid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define BSD_COMP 1 /* get BSD ioctl calls */ +# ifndef HASSETRLIMIT +# define HASSETRLIMIT 1 /* has setrlimit(2) call */ +# endif +# ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# endif + +# ifndef _PATH_UNIX +# define _PATH_UNIX "/unix" +# endif +# ifndef _PATH_VENDOR_CF +# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf" +# endif +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid" +# endif +# ifndef SYSLOG_BUFSIZE +# define SYSLOG_BUFSIZE 128 +# endif +# ifndef SFS_TYPE +# define SFS_TYPE SFS_STATVFS +# endif + +# define jmp_buf sigjmp_buf +# define setjmp(env) sigsetjmp(env, 1) +# define longjmp(env, val) siglongjmp(env, val) +#endif + +/* general System V defines */ +#ifdef SYSTEM5 +# include <sys/sysmacros.h> +# define HASUNAME 1 /* use System V uname(2) system call */ +# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */ +# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ +# ifndef HASULIMIT +# define HASULIMIT 1 /* has the ulimit(2) syscall */ +# endif +# ifndef LA_TYPE +# ifdef MIOC_READKSYM +# define LA_TYPE LA_READKSYM /* use MIOC_READKSYM ioctl */ +# else +# define LA_TYPE LA_INT /* assume integer load average */ +# endif +# endif +# ifndef SFS_TYPE +# define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */ +# endif +# ifndef TZ_TYPE +# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */ +# endif +# define bcopy(s, d, l) (memmove((d), (s), (l))) +# define bzero(d, l) (memset((d), '\0', (l))) +# define bcmp(s, d, l) (memcmp((s), (d), (l))) +#endif + +/* general POSIX defines */ +#ifdef _POSIX_VERSION +# define HASSETSID 1 /* has Posix setsid(2) call */ +# define HASWAITPID 1 /* has Posix waitpid(2) call */ +# if _POSIX_VERSION >= 199500 && !defined(USESETEUID) +# define USESETEUID 1 /* has useable seteuid(2) call */ +# endif +#endif +/* +** Tweaking for systems that (for example) claim to be BSD or POSIX +** but don't have all the standard BSD or POSIX routines (boo hiss). +*/ + +#ifdef titan +# undef HASINITGROUPS /* doesn't have initgroups(3) call */ +#endif + +#ifdef _CRAYCOM +# undef HASSETSID /* despite POSIX claim, doesn't have setsid */ +#endif + +#ifdef ISC_UNIX +# undef bcopy /* despite SystemV claim, uses BSD bcopy */ +#endif + +#ifdef ALTOS_SYS_V +# undef bcopy /* despite SystemV claim, uses BSD bcopy */ +# undef bzero /* despite SystemV claim, uses BSD bzero */ +# undef bcmp /* despite SystemV claim, uses BSD bcmp */ +#endif + + +/* +** Due to a "feature" in some operating systems such as Ultrix 4.3 and +** HPUX 8.0, if you receive a "No route to host" message (ICMP message +** ICMP_UNREACH_HOST) on _any_ connection, all connections to that host +** are closed. Some firewalls return this error if you try to connect +** to the IDENT port (113), so you can't receive email from these hosts +** on these systems. The firewall really should use a more specific +** message such as ICMP_UNREACH_PROTOCOL or _PORT or _NET_PROHIB. If +** not explicitly set to zero above, default it on. +*/ + +#ifndef IDENTPROTO +# define IDENTPROTO 1 /* use IDENT proto (RFC 1413) */ +#endif + +#ifndef IP_SRCROUTE +# define IP_SRCROUTE 1 /* Detect IP source routing */ +#endif + +#ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 1 /* libc has getusershell(3) call */ +#endif + +#ifndef NETUNIX +# define NETUNIX 1 /* include unix domain support */ +#endif + +#ifndef HASFLOCK +# define HASFLOCK 0 /* assume no flock(2) support */ +#endif + +#ifndef HASSETREUID +# define HASSETREUID 0 /* assume no setreuid(2) call */ +#endif + +#ifndef HASFCHMOD +# define HASFCHMOD 0 /* assume no fchmod(2) syscall */ +#endif + +#ifndef USESETEUID +# define USESETEUID 0 /* assume no seteuid(2) call or no saved ids */ +#endif + +#ifndef HASSETRLIMIT +# define HASSETRLIMIT 0 /* assume no setrlimit(2) support */ +#endif + +#ifndef HASULIMIT +# define HASULIMIT 0 /* assume no ulimit(2) support */ +#endif + +#ifndef OLD_NEWDB +# define OLD_NEWDB 0 /* assume newer version of newdb */ +#endif + +/* heuristic setting of HASSETSIGMASK; can override above */ +#ifndef HASSIGSETMASK +# ifdef SIGVTALRM +# define HASSETSIGMASK 1 +# else +# define HASSETSIGMASK 0 +# endif +#endif + +/* +** If no type for argument two of getgroups call is defined, assume +** it's an integer -- unfortunately, there seem to be several choices +** here. +*/ + +#ifndef GIDSET_T +# define GIDSET_T int +#endif + +#ifndef UID_T +# define UID_T uid_t +#endif + +#ifndef SIZE_T +# define SIZE_T size_t +#endif + +#ifndef ARGV_T +# define ARGV_T char ** +#endif +/********************************************************************** +** Remaining definitions should never have to be changed. They are +** primarily to provide back compatibility for older systems -- for +** example, it includes some POSIX compatibility definitions +**********************************************************************/ + +/* System 5 compatibility */ +#ifndef S_ISREG +# define S_ISREG(foo) ((foo & S_IFMT) == S_IFREG) +#endif +#if !defined(S_ISLNK) && defined(S_IFLNK) +# define S_ISLNK(foo) ((foo & S_IFMT) == S_IFLNK) +#endif +#ifndef S_IWUSR +# define S_IWUSR 0200 +#endif +#ifndef S_IWGRP +# define S_IWGRP 0020 +#endif +#ifndef S_IWOTH +# define S_IWOTH 0002 +#endif + +/* +** Older systems don't have this error code -- it should be in +** /usr/include/sysexits.h. +*/ + +# ifndef EX_CONFIG +# define EX_CONFIG 78 /* configuration error */ +# endif + +/* pseudo-code used in server SMTP */ +# define EX_QUIT 22 /* drop out of server immediately */ + + +/* +** These are used in a few cases where we need some special +** error codes, but where the system doesn't provide something +** reasonable. They are printed in errstring. +*/ + +#ifndef E_PSEUDOBASE +# define E_PSEUDOBASE 256 +#endif + +#define EOPENTIMEOUT (E_PSEUDOBASE + 0) /* timeout on open */ +#define E_DNSBASE (E_PSEUDOBASE + 20) /* base for DNS h_errno */ + +/* type of arbitrary pointer */ +#ifndef ARBPTR_T +# define ARBPTR_T void * +#endif + +#ifndef __P +# include "cdefs.h" +#endif + +#if NAMED_BIND +# include <arpa/nameser.h> +# ifdef __svr4__ +# ifdef NOERROR +# undef NOERROR /* avoid compiler conflict with stream.h */ +# endif +# endif +# ifndef __ksr__ +extern int h_errno; +# endif +#endif + +/* +** The size of an IP address -- can't use sizeof because of problems +** on Crays, where everything is 64 bits. This will break if/when +** IP addresses are expanded to eight bytes. +*/ + +#ifndef INADDRSZ +# define INADDRSZ 4 +#endif + +/* +** The size of various known types -- for reading network protocols. +** Again, we can't use sizeof because of compiler randomness. +*/ + +#ifndef INT16SZ +# define INT16SZ 2 +#endif +#ifndef INT32SZ +# define INT32SZ 4 +#endif + +/* +** Do some required dependencies +*/ + +#if NETINET || NETISO +# define SMTP 1 /* enable user and server SMTP */ +# define QUEUE 1 /* enable queueing */ +# define DAEMON 1 /* include the daemon (requires IPC & SMTP) */ +#endif + + +/* +** Arrange to use either varargs or stdargs +*/ + +# ifdef __STDC__ + +# include <stdarg.h> + +# define VA_LOCAL_DECL va_list ap; +# define VA_START(f) va_start(ap, f) +# define VA_END va_end(ap) + +# else + +# include <varargs.h> + +# define VA_LOCAL_DECL va_list ap; +# define VA_START(f) va_start(ap) +# define VA_END va_end(ap) + +# endif + +#ifdef HASUNAME +# include <sys/utsname.h> +# ifdef newstr +# undef newstr +# endif +#else /* ! HASUNAME */ +# define NODE_LENGTH 32 +struct utsname +{ + char nodename[NODE_LENGTH+1]; +}; +#endif /* HASUNAME */ + +#if !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYS_V) +# define MAXHOSTNAMELEN 256 +#endif + +#if !defined(SIGCHLD) && defined(SIGCLD) +# define SIGCHLD SIGCLD +#endif + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif + +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif + +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +#ifndef LOCK_SH +# define LOCK_SH 0x01 /* shared lock */ +# define LOCK_EX 0x02 /* exclusive lock */ +# define LOCK_NB 0x04 /* non-blocking lock */ +# define LOCK_UN 0x08 /* unlock */ +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 +# define SEEK_CUR 1 +# define SEEK_END 2 +#endif + +#ifndef SIG_ERR +# define SIG_ERR ((void (*)()) -1) +#endif + +#ifndef WEXITSTATUS +# define WEXITSTATUS(st) (((st) >> 8) & 0377) +#endif +#ifndef WIFEXITED +# define WIFEXITED(st) (((st) & 0377) == 0) +#endif + +#ifndef SIGFUNC_DEFINED +typedef void (*sigfunc_t) __P((int)); +#endif + +/* size of syslog buffer */ +#ifndef SYSLOG_BUFSIZE +# define SYSLOG_BUFSIZE 1024 +#endif + +/* +** Size of tobuf (deliver.c) +** Tweak this to match your syslog implementation. It will have to +** allow for the extra information printed. +*/ + +#ifndef TOBUFSIZE +# if (SYSLOG_BUFSIZE) > 768 +# define TOBUFSIZE (SYSLOG_BUFSIZE - 512) +# else +# define TOBUFSIZE 256 +# endif +#endif + +/* TOBUFSIZE must never be permitted to exceed MAXLINE - 128 */ +#if TOBUFSIZE > (MAXLINE - 128) +# undef TOBUFSIZE +# define TOBUFSIZE (MAXLINE - 128) +#endif + +/* +** Size of prescan buffer. +** Despite comments in the _sendmail_ book, this probably should +** not be changed; there are some hard-to-define dependencies. +*/ + +# define PSBUFSIZE (MAXNAME + MAXATOM) /* size of prescan buffer */ +/* fork routine -- set above using #ifdef _osname_ or in Makefile */ +# ifndef FORK +# define FORK vfork /* function to call to fork mailer */ +# endif + +/* +** Default to using scanf in readcf. +*/ + +#ifndef SCANF +# define SCANF 1 +#endif diff --git a/usr.sbin/sendmail/src/convtime.c b/usr.sbin/sendmail/src/convtime.c new file mode 100644 index 000000000000..f978e92f15ed --- /dev/null +++ b/usr.sbin/sendmail/src/convtime.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)convtime.c 8.4 (Berkeley) 5/19/95"; +#endif /* not lint */ + +# include <ctype.h> +# include <string.h> +# include "useful.h" + +/* +** CONVTIME -- convert time +** +** Takes a time as an ascii string with a trailing character +** giving units: +** s -- seconds +** m -- minutes +** h -- hours +** d -- days (default) +** w -- weeks +** For example, "3d12h" is three and a half days. +** +** Parameters: +** p -- pointer to ascii time. +** units -- default units if none specified. +** +** Returns: +** time in seconds. +** +** Side Effects: +** none. +*/ + +time_t +convtime(p, units) + char *p; + char units; +{ + register time_t t, r; + register char c; + + r = 0; + while (*p != '\0') + { + t = 0; + while ((c = *p++) != '\0' && isascii(c) && isdigit(c)) + t = t * 10 + (c - '0'); + if (c == '\0') + { + c = units; + p--; + } + else if (strchr("wdhms", c) == NULL) + { + usrerr("Invalid time unit `%c'", c); + c = units; + } + switch (c) + { + case 'w': /* weeks */ + t *= 7; + + case 'd': /* days */ + default: + t *= 24; + + case 'h': /* hours */ + t *= 60; + + case 'm': /* minutes */ + t *= 60; + + case 's': /* seconds */ + break; + } + r += t; + } + + return (r); +} +/* +** PINTVL -- produce printable version of a time interval +** +** Parameters: +** intvl -- the interval to be converted +** brief -- if TRUE, print this in an extremely compact form +** (basically used for logging). +** +** Returns: +** A pointer to a string version of intvl suitable for +** printing or framing. +** +** Side Effects: +** none. +** +** Warning: +** The string returned is in a static buffer. +*/ + +# define PLURAL(n) ((n) == 1 ? "" : "s") + +char * +pintvl(intvl, brief) + time_t intvl; + bool brief; +{ + static char buf[256]; + register char *p; + int wk, dy, hr, mi, se; + + if (intvl == 0 && !brief) + return ("zero seconds"); + + /* decode the interval into weeks, days, hours, minutes, seconds */ + se = intvl % 60; + intvl /= 60; + mi = intvl % 60; + intvl /= 60; + hr = intvl % 24; + intvl /= 24; + if (brief) + dy = intvl; + else + { + dy = intvl % 7; + intvl /= 7; + wk = intvl; + } + + /* now turn it into a sexy form */ + p = buf; + if (brief) + { + if (dy > 0) + { + (void) sprintf(p, "%d+", dy); + p += strlen(p); + } + (void) sprintf(p, "%02d:%02d:%02d", hr, mi, se); + return (buf); + } + + /* use the verbose form */ + if (wk > 0) + { + (void) sprintf(p, ", %d week%s", wk, PLURAL(wk)); + p += strlen(p); + } + if (dy > 0) + { + (void) sprintf(p, ", %d day%s", dy, PLURAL(dy)); + p += strlen(p); + } + if (hr > 0) + { + (void) sprintf(p, ", %d hour%s", hr, PLURAL(hr)); + p += strlen(p); + } + if (mi > 0) + { + (void) sprintf(p, ", %d minute%s", mi, PLURAL(mi)); + p += strlen(p); + } + if (se > 0) + { + (void) sprintf(p, ", %d second%s", se, PLURAL(se)); + p += strlen(p); + } + + return (buf + 2); +} diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c new file mode 100644 index 000000000000..c2f5327b1e34 --- /dev/null +++ b/usr.sbin/sendmail/src/daemon.c @@ -0,0 +1,1736 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <errno.h> +#include "sendmail.h" + +#ifndef lint +#ifdef DAEMON +static char sccsid[] = "@(#)daemon.c 8.118 (Berkeley) 10/8/95 (with daemon mode)"; +#else +static char sccsid[] = "@(#)daemon.c 8.118 (Berkeley) 10/8/95 (without daemon mode)"; +#endif +#endif /* not lint */ + +#ifdef DAEMON + +# include <arpa/inet.h> + +#if NAMED_BIND +# include <resolv.h> +# ifndef NO_DATA +# define NO_DATA NO_ADDRESS +# endif +#endif + +#if IP_SRCROUTE +# include <netinet/in_systm.h> +# include <netinet/ip.h> +# include <netinet/ip_var.h> +#endif + +/* +** DAEMON.C -- routines to use when running as a daemon. +** +** This entire file is highly dependent on the 4.2 BSD +** interprocess communication primitives. No attempt has +** been made to make this file portable to Version 7, +** Version 6, MPX files, etc. If you should try such a +** thing yourself, I recommend chucking the entire file +** and starting from scratch. Basic semantics are: +** +** getrequests() +** Opens a port and initiates a connection. +** Returns in a child. Must set InChannel and +** OutChannel appropriately. +** clrdaemon() +** Close any open files associated with getting +** the connection; this is used when running the queue, +** etc., to avoid having extra file descriptors during +** the queue run and to avoid confusing the network +** code (if it cares). +** makeconnection(host, port, outfile, infile, usesecureport) +** Make a connection to the named host on the given +** port. Set *outfile and *infile to the files +** appropriate for communication. Returns zero on +** success, else an exit status describing the +** error. +** host_map_lookup(map, hbuf, avp, pstat) +** Convert the entry in hbuf into a canonical form. +*/ +/* +** GETREQUESTS -- open mail IPC port and get requests. +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Waits until some interesting activity occurs. When +** it does, a child is created to process it, and the +** parent waits for completion. Return from this +** routine is always in the child. The file pointers +** "InChannel" and "OutChannel" should be set to point +** to the communication channel. +*/ + +int DaemonSocket = -1; /* fd describing socket */ +SOCKADDR DaemonAddr; /* socket for incoming */ +int ListenQueueSize = 10; /* size of listen queue */ +int TcpRcvBufferSize = 0; /* size of TCP receive buffer */ +int TcpSndBufferSize = 0; /* size of TCP send buffer */ + +void +getrequests() +{ + int t; + bool refusingconnections = TRUE; + FILE *pidf; + int socksize; +#if XDEBUG + bool j_has_dot; +#endif + extern void reapchild(); + + /* + ** Set up the address for the mailer. + */ + + if (DaemonAddr.sin.sin_family == 0) + DaemonAddr.sin.sin_family = AF_INET; + if (DaemonAddr.sin.sin_addr.s_addr == 0) + DaemonAddr.sin.sin_addr.s_addr = INADDR_ANY; + if (DaemonAddr.sin.sin_port == 0) + { + register struct servent *sp; + + sp = getservbyname("smtp", "tcp"); + if (sp == NULL) + { + syserr("554 service \"smtp\" unknown"); + DaemonAddr.sin.sin_port = htons(25); + } + else + DaemonAddr.sin.sin_port = sp->s_port; + } + + /* + ** Try to actually open the connection. + */ + + if (tTd(15, 1)) + printf("getrequests: port 0x%x\n", DaemonAddr.sin.sin_port); + + /* get a socket for the SMTP connection */ + socksize = opendaemonsocket(TRUE); + + (void) setsignal(SIGCHLD, reapchild); + + /* write the pid to the log file for posterity */ + pidf = fopen(PidFile, "w"); + if (pidf != NULL) + { + extern char *CommandLineArgs; + + /* write the process id on line 1 */ + fprintf(pidf, "%d\n", getpid()); + + /* line 2 contains all command line flags */ + fprintf(pidf, "%s\n", CommandLineArgs); + + /* flush and close */ + fclose(pidf); + } + +#if XDEBUG + { + char jbuf[MAXHOSTNAMELEN]; + + expand("\201j", jbuf, sizeof jbuf, CurEnv); + j_has_dot = strchr(jbuf, '.') != NULL; + } +#endif + + if (tTd(15, 1)) + printf("getrequests: %d\n", DaemonSocket); + + for (;;) + { + register int pid; + auto int lotherend; + extern bool refuseconnections(); + extern int getla(); + + /* see if we are rejecting connections */ + CurrentLA = getla(); + if (refuseconnections()) + { + if (DaemonSocket >= 0) + { + /* close socket so peer will fail quickly */ + (void) close(DaemonSocket); + DaemonSocket = -1; + } + refusingconnections = TRUE; + sleep(15); + continue; + } + + /* arrange to (re)open the socket if necessary */ + if (refusingconnections) + { + (void) opendaemonsocket(FALSE); + refusingconnections = FALSE; + } + +#if XDEBUG + /* check for disaster */ + { + char jbuf[MAXHOSTNAMELEN]; + + expand("\201j", jbuf, sizeof jbuf, CurEnv); + if (!wordinclass(jbuf, 'w')) + { + dumpstate("daemon lost $j"); + syslog(LOG_ALERT, "daemon process doesn't have $j in $=w; see syslog"); + abort(); + } + else if (j_has_dot && strchr(jbuf, '.') == NULL) + { + dumpstate("daemon $j lost dot"); + syslog(LOG_ALERT, "daemon process $j lost dot; see syslog"); + abort(); + } + } +#endif + + /* wait for a connection */ + setproctitle("accepting connections"); + do + { + errno = 0; + lotherend = socksize; + t = accept(DaemonSocket, + (struct sockaddr *)&RealHostAddr, &lotherend); + } while (t < 0 && errno == EINTR); + if (t < 0) + { + syserr("getrequests: accept"); + + /* arrange to re-open the socket next time around */ + (void) close(DaemonSocket); + DaemonSocket = -1; + refusingconnections = TRUE; + sleep(5); + continue; + } + + /* + ** Create a subprocess to process the mail. + */ + + if (tTd(15, 2)) + printf("getrequests: forking (fd = %d)\n", t); + + pid = fork(); + if (pid < 0) + { + syserr("daemon: cannot fork"); + sleep(10); + (void) close(t); + continue; + } + + if (pid == 0) + { + char *p; + extern char *hostnamebyanyaddr(); + extern void intsig(); + FILE *inchannel, *outchannel; + + /* + ** CHILD -- return to caller. + ** Collect verified idea of sending host. + ** Verify calling user id if possible here. + */ + + (void) setsignal(SIGCHLD, SIG_DFL); + (void) setsignal(SIGHUP, intsig); + (void) close(DaemonSocket); + + setproctitle("startup with %s", + anynet_ntoa(&RealHostAddr)); + + /* determine host name */ + p = hostnamebyanyaddr(&RealHostAddr); + if (strlen(p) > MAXNAME) + p[MAXNAME] = '\0'; + RealHostName = newstr(p); + setproctitle("startup with %s", p); + + if ((inchannel = fdopen(t, "r")) == NULL || + (t = dup(t)) < 0 || + (outchannel = fdopen(t, "w")) == NULL) + { + syserr("cannot open SMTP server channel, fd=%d", t); + exit(0); + } + + InChannel = inchannel; + OutChannel = outchannel; + DisConnected = FALSE; + + /* should we check for illegal connection here? XXX */ +#ifdef XLA + if (!xla_host_ok(RealHostName)) + { + message("421 Too many SMTP sessions for this host"); + exit(0); + } +#endif + + if (tTd(15, 2)) + printf("getreq: returning\n"); + return; + } + + CurChildren++; + + /* close the port so that others will hang (for a while) */ + (void) close(t); + } + /*NOTREACHED*/ +} +/* +** OPENDAEMONSOCKET -- open the SMTP socket +** +** Deals with setting all appropriate options. DaemonAddr must +** be set up in advance. +** +** Parameters: +** firsttime -- set if this is the initial open. +** +** Returns: +** Size in bytes of the daemon socket addr. +** +** Side Effects: +** Leaves DaemonSocket set to the open socket. +** Exits if the socket cannot be created. +*/ + +#define MAXOPENTRIES 10 /* maximum number of tries to open connection */ + +int +opendaemonsocket(firsttime) + bool firsttime; +{ + int on = 1; + int socksize = 0; + int ntries = 0; + int saveerrno; + + if (tTd(15, 2)) + printf("opendaemonsocket()\n"); + + do + { + if (ntries > 0) + sleep(5); + if (firsttime || DaemonSocket < 0) + { + DaemonSocket = socket(DaemonAddr.sa.sa_family, SOCK_STREAM, 0); + if (DaemonSocket < 0) + { + saveerrno = errno; + syserr("opendaemonsocket: can't create server SMTP socket"); + severe: +# ifdef LOG + if (LogLevel > 0) + syslog(LOG_ALERT, "problem creating SMTP socket"); +# endif /* LOG */ + DaemonSocket = -1; + continue; + } + + /* turn on network debugging? */ + if (tTd(15, 101)) + (void) setsockopt(DaemonSocket, SOL_SOCKET, + SO_DEBUG, (char *)&on, + sizeof on); + + (void) setsockopt(DaemonSocket, SOL_SOCKET, + SO_REUSEADDR, (char *)&on, sizeof on); + (void) setsockopt(DaemonSocket, SOL_SOCKET, + SO_KEEPALIVE, (char *)&on, sizeof on); + +#ifdef SO_RCVBUF + if (TcpRcvBufferSize > 0) + { + if (setsockopt(DaemonSocket, SOL_SOCKET, + SO_RCVBUF, + (char *) &TcpRcvBufferSize, + sizeof(TcpRcvBufferSize)) < 0) + syserr("opendaemonsocket: setsockopt(SO_RCVBUF)"); + } +#endif + + switch (DaemonAddr.sa.sa_family) + { +# if NETINET + case AF_INET: + socksize = sizeof DaemonAddr.sin; + break; +# endif + +# if NETISO + case AF_ISO: + socksize = sizeof DaemonAddr.siso; + break; +# endif + + default: + socksize = sizeof DaemonAddr; + break; + } + + if (bind(DaemonSocket, &DaemonAddr.sa, socksize) < 0) + { + /* probably another daemon already */ + saveerrno = errno; + syserr("opendaemonsocket: cannot bind"); + (void) close(DaemonSocket); + goto severe; + } + } + if (!firsttime && listen(DaemonSocket, ListenQueueSize) < 0) + { + saveerrno = errno; + syserr("opendaemonsocket: cannot listen"); + (void) close(DaemonSocket); + goto severe; + } + return socksize; + } while (ntries++ < MAXOPENTRIES && transienterror(saveerrno)); + syserr("!opendaemonsocket: server SMTP socket wedged: exiting"); + finis(); +} +/* +** CLRDAEMON -- reset the daemon connection +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** releases any resources used by the passive daemon. +*/ + +void +clrdaemon() +{ + if (DaemonSocket >= 0) + (void) close(DaemonSocket); + DaemonSocket = -1; +} +/* +** SETDAEMONOPTIONS -- set options for running the daemon +** +** Parameters: +** p -- the options line. +** +** Returns: +** none. +*/ + +void +setdaemonoptions(p) + register char *p; +{ + if (DaemonAddr.sa.sa_family == AF_UNSPEC) + DaemonAddr.sa.sa_family = AF_INET; + + while (p != NULL) + { + register char *f; + register char *v; + + while (isascii(*p) && isspace(*p)) + p++; + if (*p == '\0') + break; + f = p; + p = strchr(p, ','); + if (p != NULL) + *p++ = '\0'; + v = strchr(f, '='); + if (v == NULL) + continue; + while (isascii(*++v) && isspace(*v)) + continue; + if (isascii(*f) && islower(*f)) + *f = toupper(*f); + + switch (*f) + { + case 'F': /* address family */ + if (isascii(*v) && isdigit(*v)) + DaemonAddr.sa.sa_family = atoi(v); +#if NETINET + else if (strcasecmp(v, "inet") == 0) + DaemonAddr.sa.sa_family = AF_INET; +#endif +#if NETISO + else if (strcasecmp(v, "iso") == 0) + DaemonAddr.sa.sa_family = AF_ISO; +#endif +#if NETNS + else if (strcasecmp(v, "ns") == 0) + DaemonAddr.sa.sa_family = AF_NS; +#endif +#if NETX25 + else if (strcasecmp(v, "x.25") == 0) + DaemonAddr.sa.sa_family = AF_CCITT; +#endif + else + syserr("554 Unknown address family %s in Family=option", v); + break; + + case 'A': /* address */ + switch (DaemonAddr.sa.sa_family) + { +#if NETINET + case AF_INET: + if (isascii(*v) && isdigit(*v)) + DaemonAddr.sin.sin_addr.s_addr = htonl(inet_network(v)); + else + { + register struct netent *np; + + np = getnetbyname(v); + if (np == NULL) + syserr("554 network \"%s\" unknown", v); + else + DaemonAddr.sin.sin_addr.s_addr = np->n_net; + } + break; +#endif + + default: + syserr("554 Address= option unsupported for family %d", + DaemonAddr.sa.sa_family); + break; + } + break; + + case 'P': /* port */ + switch (DaemonAddr.sa.sa_family) + { + short port; + +#if NETINET + case AF_INET: + if (isascii(*v) && isdigit(*v)) + DaemonAddr.sin.sin_port = htons(atoi(v)); + else + { + register struct servent *sp; + + sp = getservbyname(v, "tcp"); + if (sp == NULL) + syserr("554 service \"%s\" unknown", v); + else + DaemonAddr.sin.sin_port = sp->s_port; + } + break; +#endif + +#if NETISO + case AF_ISO: + /* assume two byte transport selector */ + if (isascii(*v) && isdigit(*v)) + port = htons(atoi(v)); + else + { + register struct servent *sp; + + sp = getservbyname(v, "tcp"); + if (sp == NULL) + syserr("554 service \"%s\" unknown", v); + else + port = sp->s_port; + } + bcopy((char *) &port, TSEL(&DaemonAddr.siso), 2); + break; +#endif + + default: + syserr("554 Port= option unsupported for family %d", + DaemonAddr.sa.sa_family); + break; + } + break; + + case 'L': /* listen queue size */ + ListenQueueSize = atoi(v); + break; + + case 'S': /* send buffer size */ + TcpSndBufferSize = atoi(v); + break; + + case 'R': /* receive buffer size */ + TcpRcvBufferSize = atoi(v); + break; + + default: + syserr("554 DaemonPortOptions parameter \"%s\" unknown", f); + } + } +} +/* +** MAKECONNECTION -- make a connection to an SMTP socket on another machine. +** +** Parameters: +** host -- the name of the host. +** port -- the port number to connect to. +** mci -- a pointer to the mail connection information +** structure to be filled in. +** usesecureport -- if set, use a low numbered (reserved) +** port to provide some rudimentary authentication. +** +** Returns: +** An exit code telling whether the connection could be +** made and if not why not. +** +** Side Effects: +** none. +*/ + +static jmp_buf CtxConnectTimeout; + +static void +connecttimeout() +{ + errno = ETIMEDOUT; + longjmp(CtxConnectTimeout, 1); +} + +SOCKADDR CurHostAddr; /* address of current host */ + +int +makeconnection(host, port, mci, usesecureport) + char *host; + u_short port; + register MCI *mci; + bool usesecureport; +{ + register int i = 0; + register int s; + register struct hostent *hp = (struct hostent *)NULL; + SOCKADDR addr; + int sav_errno; + int addrlen; + bool firstconnect; + EVENT *ev; + + /* + ** Set up the address for the mailer. + ** Accept "[a.b.c.d]" syntax for host name. + */ + +#if NAMED_BIND + h_errno = 0; +#endif + errno = 0; + bzero(&CurHostAddr, sizeof CurHostAddr); + SmtpPhase = mci->mci_phase = "initial connection"; + CurHostName = host; + + if (host[0] == '[') + { + long hid; + register char *p = strchr(host, ']'); + + if (p != NULL) + { + *p = '\0'; +#if NETINET + hid = inet_addr(&host[1]); + if (hid == -1) +#endif + { + /* try it as a host name (avoid MX lookup) */ + hp = sm_gethostbyname(&host[1]); + if (hp == NULL && p[-1] == '.') + { +#if NAMED_BIND + int oldopts = _res.options; + + _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); +#endif + p[-1] = '\0'; + hp = sm_gethostbyname(&host[1]); + p[-1] = '.'; +#if NAMED_BIND + _res.options = oldopts; +#endif + } + *p = ']'; + goto gothostent; + } + *p = ']'; + } + if (p == NULL) + { + usrerr("553 Invalid numeric domain spec \"%s\"", host); + mci->mci_status = "5.1.2"; + return (EX_NOHOST); + } +#if NETINET + addr.sin.sin_family = AF_INET; /*XXX*/ + addr.sin.sin_addr.s_addr = hid; +#endif + } + else + { + register char *p = &host[strlen(host) - 1]; + + hp = sm_gethostbyname(host); + if (hp == NULL && *p == '.') + { +#if NAMED_BIND + int oldopts = _res.options; + + _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); +#endif + *p = '\0'; + hp = sm_gethostbyname(host); + *p = '.'; +#if NAMED_BIND + _res.options = oldopts; +#endif + } +gothostent: + if (hp == NULL) + { +#if NAMED_BIND + /* check for name server timeouts */ + if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || + (errno == ECONNREFUSED && UseNameServer)) + { + mci->mci_status = "4.4.3"; + return (EX_TEMPFAIL); + } +#endif + return (EX_NOHOST); + } + addr.sa.sa_family = hp->h_addrtype; + switch (hp->h_addrtype) + { +#if NETINET + case AF_INET: + bcopy(hp->h_addr, + &addr.sin.sin_addr, + INADDRSZ); + break; +#endif + + default: + bcopy(hp->h_addr, + addr.sa.sa_data, + hp->h_length); + break; + } + i = 1; + } + + /* + ** Determine the port number. + */ + + if (port == 0) + { + register struct servent *sp = getservbyname("smtp", "tcp"); + + if (sp == NULL) + { +#ifdef LOG + if (LogLevel > 2) + syslog(LOG_ERR, "makeconnection: service \"smtp\" unknown"); +#endif + port = htons(25); + } + else + port = sp->s_port; + } + + switch (addr.sa.sa_family) + { +#if NETINET + case AF_INET: + addr.sin.sin_port = port; + addrlen = sizeof (struct sockaddr_in); + break; +#endif + +#if NETISO + case AF_ISO: + /* assume two byte transport selector */ + bcopy((char *) &port, TSEL((struct sockaddr_iso *) &addr), 2); + addrlen = sizeof (struct sockaddr_iso); + break; +#endif + + default: + syserr("Can't connect to address family %d", addr.sa.sa_family); + return (EX_NOHOST); + } + + /* + ** Try to actually open the connection. + */ + +#ifdef XLA + /* if too many connections, don't bother trying */ + if (!xla_noqueue_ok(host)) + return EX_TEMPFAIL; +#endif + + firstconnect = TRUE; + for (;;) + { + if (tTd(16, 1)) + printf("makeconnection (%s [%s])\n", + host, anynet_ntoa(&addr)); + + /* save for logging */ + CurHostAddr = addr; + + if (usesecureport) + { + int rport = IPPORT_RESERVED - 1; + + s = rresvport(&rport); + } + else + { + s = socket(AF_INET, SOCK_STREAM, 0); + } + if (s < 0) + { + sav_errno = errno; + syserr("makeconnection: cannot create socket"); + goto failure; + } + +#ifdef SO_SNDBUF + if (TcpSndBufferSize > 0) + { + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, + (char *) &TcpSndBufferSize, + sizeof(TcpSndBufferSize)) < 0) + syserr("makeconnection: setsockopt(SO_SNDBUF)"); + } +#endif + + if (tTd(16, 1)) + printf("makeconnection: fd=%d\n", s); + + /* turn on network debugging? */ + if (tTd(16, 101)) + { + int on = 1; + (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, + (char *)&on, sizeof on); + } + if (CurEnv->e_xfp != NULL) + (void) fflush(CurEnv->e_xfp); /* for debugging */ + errno = 0; /* for debugging */ + + /* + ** Linux seems to hang in connect for 90 minutes (!!!). + ** Time out the connect to avoid this problem. + */ + + if (setjmp(CtxConnectTimeout) == 0) + { + if (TimeOuts.to_connect == 0) + ev = NULL; + else + ev = setevent(TimeOuts.to_connect, connecttimeout, 0); + if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0) + { + if (ev != NULL) + clrevent(ev); + break; + } + } + sav_errno = errno; + if (ev != NULL) + clrevent(ev); + + /* if running demand-dialed connection, try again */ + if (DialDelay > 0 && firstconnect) + { + if (tTd(16, 1)) + printf("Connect failed (%s); trying again...\n", + errstring(sav_errno)); + firstconnect = FALSE; + sleep(DialDelay); + continue; + } + + /* couldn't connect.... figure out why */ + (void) close(s); + if (hp != NULL && hp->h_addr_list[i]) + { + if (tTd(16, 1)) + printf("Connect failed (%s); trying new address....\n", + errstring(sav_errno)); + switch (addr.sa.sa_family) + { +#if NETINET + case AF_INET: + bcopy(hp->h_addr_list[i++], + &addr.sin.sin_addr, + INADDRSZ); + break; +#endif + + default: + bcopy(hp->h_addr_list[i++], + addr.sa.sa_data, + hp->h_length); + break; + } + continue; + } + + /* failure, decide if temporary or not */ + failure: +#ifdef XLA + xla_host_end(host); +#endif + if (transienterror(sav_errno)) + return EX_TEMPFAIL; + else + { + message("%s", errstring(sav_errno)); + return (EX_UNAVAILABLE); + } + } + + /* connection ok, put it into canonical form */ + if ((mci->mci_out = fdopen(s, "w")) == NULL || + (s = dup(s)) < 0 || + (mci->mci_in = fdopen(s, "r")) == NULL) + { + syserr("cannot open SMTP client channel, fd=%d", s); + return EX_TEMPFAIL; + } + + return (EX_OK); +} +/* +** MYHOSTNAME -- return the name of this host. +** +** Parameters: +** hostbuf -- a place to return the name of this host. +** size -- the size of hostbuf. +** +** Returns: +** A list of aliases for this host. +** +** Side Effects: +** Adds numeric codes to $=w. +*/ + +struct hostent * +myhostname(hostbuf, size) + char hostbuf[]; + int size; +{ + register struct hostent *hp; + extern bool getcanonname(); + + if (gethostname(hostbuf, size) < 0) + { + (void) strcpy(hostbuf, "localhost"); + } + hp = sm_gethostbyname(hostbuf); + if (hp == NULL) + return NULL; + if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL) + { + (void) strncpy(hostbuf, hp->h_name, size - 1); + hostbuf[size - 1] = '\0'; + } + + /* + ** If there is still no dot in the name, try looking for a + ** dotted alias. + */ + + if (strchr(hostbuf, '.') == NULL) + { + char **ha; + + for (ha = hp->h_aliases; *ha != NULL; ha++) + { + if (strchr(*ha, '.') != NULL) + { + (void) strncpy(hostbuf, *ha, size - 1); + hostbuf[size - 1] = '\0'; + break; + } + } + } + + /* + ** If _still_ no dot, wait for a while and try again -- it is + ** possible that some service is starting up. This can result + ** in excessive delays if the system is badly configured, but + ** there really isn't a way around that, particularly given that + ** the config file hasn't been read at this point. + ** All in all, a bit of a mess. + */ + + if (strchr(hostbuf, '.') == NULL && + !getcanonname(hostbuf, size, TRUE)) + { +#ifdef LOG + syslog(LOG_CRIT, "My unqualifed host name (%s) unknown; sleeping for retry", + hostbuf); +#endif + message("My unqualifed host name (%s) unknown; sleeping for retry", + hostbuf); + sleep(60); + if (!getcanonname(hostbuf, size, TRUE)) + { +#ifdef LOG + syslog(LOG_ALERT, "unable to qualify my own domain name (%s) -- using short name", + hostbuf); +#endif + message("WARNING: unable to qualify my own domain name (%s) -- using short name", + hostbuf); + } + } + return (hp); +} +/* +** GETAUTHINFO -- get the real host name asociated with a file descriptor +** +** Uses RFC1413 protocol to try to get info from the other end. +** +** Parameters: +** fd -- the descriptor +** +** Returns: +** The user@host information associated with this descriptor. +*/ + +static jmp_buf CtxAuthTimeout; + +static void +authtimeout() +{ + longjmp(CtxAuthTimeout, 1); +} + +char * +getauthinfo(fd) + int fd; +{ + int falen; + register char *p; + SOCKADDR la; + int lalen; + register struct servent *sp; + volatile int s; + int i; + EVENT *ev; + int nleft; + char ibuf[MAXNAME + 1]; + static char hbuf[MAXNAME * 2 + 2]; + extern char *hostnamebyanyaddr(); + + falen = sizeof RealHostAddr; + if (isatty(fd) || getpeername(fd, &RealHostAddr.sa, &falen) < 0 || + falen <= 0 || RealHostAddr.sa.sa_family == 0) + { + (void) sprintf(hbuf, "%s@localhost", RealUserName); + if (tTd(9, 1)) + printf("getauthinfo: %s\n", hbuf); + return hbuf; + } + + if (RealHostName == NULL) + { + /* translate that to a host name */ + RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr)); + } + + if (TimeOuts.to_ident == 0) + goto noident; + + lalen = sizeof la; + if (RealHostAddr.sa.sa_family != AF_INET || + getsockname(fd, &la.sa, &lalen) < 0 || lalen <= 0 || + la.sa.sa_family != AF_INET) + { + /* no ident info */ + goto noident; + } + + /* create ident query */ + (void) sprintf(ibuf, "%d,%d\r\n", + ntohs(RealHostAddr.sin.sin_port), ntohs(la.sin.sin_port)); + + /* create local address */ + la.sin.sin_port = 0; + + /* create foreign address */ + sp = getservbyname("auth", "tcp"); + if (sp != NULL) + RealHostAddr.sin.sin_port = sp->s_port; + else + RealHostAddr.sin.sin_port = htons(113); + + s = -1; + if (setjmp(CtxAuthTimeout) != 0) + { + if (s >= 0) + (void) close(s); + goto noident; + } + + /* put a timeout around the whole thing */ + ev = setevent(TimeOuts.to_ident, authtimeout, 0); + + /* connect to foreign IDENT server using same address as SMTP socket */ + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + { + clrevent(ev); + goto noident; + } + if (bind(s, &la.sa, sizeof la.sin) < 0 || + connect(s, &RealHostAddr.sa, sizeof RealHostAddr.sin) < 0) + { + goto closeident; + } + + if (tTd(9, 10)) + printf("getauthinfo: sent %s", ibuf); + + /* send query */ + if (write(s, ibuf, strlen(ibuf)) < 0) + goto closeident; + + /* get result */ + p = &ibuf[0]; + nleft = sizeof ibuf - 1; + while ((i = read(s, p, nleft)) > 0) + { + p += i; + nleft -= i; + } + (void) close(s); + clrevent(ev); + if (i < 0 || p == &ibuf[0]) + goto noident; + + if (*--p == '\n' && *--p == '\r') + p--; + *++p = '\0'; + + if (tTd(9, 3)) + printf("getauthinfo: got %s\n", ibuf); + + /* parse result */ + p = strchr(ibuf, ':'); + if (p == NULL) + { + /* malformed response */ + goto noident; + } + while (isascii(*++p) && isspace(*p)) + continue; + if (strncasecmp(p, "userid", 6) != 0) + { + /* presumably an error string */ + goto noident; + } + p += 6; + while (isascii(*p) && isspace(*p)) + p++; + if (*p++ != ':') + { + /* either useridxx or malformed response */ + goto noident; + } + + /* p now points to the OSTYPE field */ + while (isascii(*p) && isspace(*p)) + p++; + if (strncasecmp(p, "other", 5) == 0 && + (p[5] == ':' || p[5] == ' ' || p[5] == ',' || p[5] == '\0')) + { + /* not useful information */ + goto noident; + } + p = strchr(p, ':'); + if (p == NULL) + { + /* malformed response */ + goto noident; + } + + /* 1413 says don't do this -- but it's broken otherwise */ + while (isascii(*++p) && isspace(*p)) + continue; + + /* p now points to the authenticated name -- copy carefully */ + cleanstrcpy(hbuf, p, MAXNAME); + i = strlen(hbuf); + hbuf[i++] = '@'; + strcpy(&hbuf[i], RealHostName == NULL ? "localhost" : RealHostName); + goto postident; + +closeident: + (void) close(s); + clrevent(ev); + +noident: + if (RealHostName == NULL) + { + if (tTd(9, 1)) + printf("getauthinfo: NULL\n"); + return NULL; + } + (void) strcpy(hbuf, RealHostName); + +postident: +#if IP_SRCROUTE + /* + ** Extract IP source routing information. + ** + ** Format of output for a connection from site a through b + ** through c to d: + ** loose: @site-c@site-b:site-a + ** strict: !@site-c@site-b:site-a + ** + ** o - pointer within ipopt_list structure. + ** q - pointer within ls/ss rr route data + ** p - pointer to hbuf + */ + + if (RealHostAddr.sa.sa_family == AF_INET) + { + int ipoptlen, j; + u_char *q; + u_char *o; + struct in_addr addr; + struct ipoption ipopt; + + ipoptlen = sizeof ipopt; + if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS, + (char *) &ipopt, &ipoptlen) < 0) + goto noipsr; + if (ipoptlen == 0) + goto noipsr; + o = (u_char *) ipopt.ipopt_list; + while (o != NULL && o < (u_char *) &ipopt + ipoptlen) + { + switch (*o) + { + case IPOPT_EOL: + o = NULL; + break; + + case IPOPT_NOP: + o++; + break; + + case IPOPT_SSRR: + case IPOPT_LSRR: + p = &hbuf[strlen(hbuf)]; + sprintf(p, " [%s@%.120s", + *o == IPOPT_SSRR ? "!" : "", + inet_ntoa(ipopt.ipopt_dst)); + p += strlen(p); + + /* o[1] is option length */ + j = *++o / sizeof(struct in_addr) - 1; + + /* q skips length and router pointer to data */ + q = o + 2; + for ( ; j >= 0; j--) + { + memcpy(&addr, q, sizeof(addr)); + sprintf(p, "%c%.120s", + j ? '@' : ':', + inet_ntoa(addr)); + p += strlen(p); + q += sizeof(struct in_addr); + } + o += *o; + break; + + default: + /* Skip over option */ + o += o[1]; + break; + } + } + strcat(hbuf,"]"); + goto postipsr; + } +#endif + +noipsr: + if (RealHostName != NULL && RealHostName[0] != '[') + { + p = &hbuf[strlen(hbuf)]; + (void) sprintf(p, " [%.100s]", anynet_ntoa(&RealHostAddr)); + } + +postipsr: + if (tTd(9, 1)) + printf("getauthinfo: %s\n", hbuf); + return hbuf; +} +/* +** HOST_MAP_LOOKUP -- turn a hostname into canonical form +** +** Parameters: +** map -- a pointer to this map (unused). +** name -- the (presumably unqualified) hostname. +** av -- unused -- for compatibility with other mapping +** functions. +** statp -- an exit status (out parameter) -- set to +** EX_TEMPFAIL if the name server is unavailable. +** +** Returns: +** The mapping, if found. +** NULL if no mapping found. +** +** Side Effects: +** Looks up the host specified in hbuf. If it is not +** the canonical name for that host, return the canonical +** name. +*/ + +char * +host_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + register struct hostent *hp; + struct in_addr in_addr; + char *cp; + register STAB *s; + char hbuf[MAXNAME + 1]; + + /* + ** See if we have already looked up this name. If so, just + ** return it. + */ + + s = stab(name, ST_NAMECANON, ST_ENTER); + if (bitset(NCF_VALID, s->s_namecanon.nc_flags)) + { + if (tTd(9, 1)) + printf("host_map_lookup(%s) => CACHE %s\n", + name, + s->s_namecanon.nc_cname == NULL + ? "NULL" + : s->s_namecanon.nc_cname); + errno = s->s_namecanon.nc_errno; +#if NAMED_BIND + h_errno = s->s_namecanon.nc_herrno; +#endif + *statp = s->s_namecanon.nc_stat; + if (*statp == EX_TEMPFAIL) + { + CurEnv->e_status = "4.4.3"; + message("851 %s: Name server timeout", + shortenstring(name, 33)); + } + return s->s_namecanon.nc_cname; + } + + /* + ** If we are running without a regular network connection (usually + ** dial-on-demand) and we are just queueing, we want to avoid DNS + ** lookups because those could try to connect to a server. + */ + + if (CurEnv->e_sendmode == SM_DEFER) + { + if (tTd(9, 1)) + printf("host_map_lookup(%s) => DEFERRED\n", name); + *statp = EX_TEMPFAIL; + return NULL; + } + + /* + ** If first character is a bracket, then it is an address + ** lookup. Address is copied into a temporary buffer to + ** strip the brackets and to preserve name if address is + ** unknown. + */ + + if (*name != '[') + { + extern bool getcanonname(); + + if (tTd(9, 1)) + printf("host_map_lookup(%s) => ", name); + s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */ + if (strlen(name) < sizeof hbuf) + (void) strcpy(hbuf, name); + else + { + bcopy(name, hbuf, sizeof hbuf - 1); + hbuf[sizeof hbuf - 1] = '\0'; + } + if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX)) + { + if (tTd(9, 1)) + printf("%s\n", hbuf); + cp = map_rewrite(map, hbuf, strlen(hbuf), av); + s->s_namecanon.nc_cname = newstr(cp); + return cp; + } + else + { + register struct hostent *hp; + + s->s_namecanon.nc_errno = errno; +#if NAMED_BIND + s->s_namecanon.nc_herrno = h_errno; + if (tTd(9, 1)) + printf("FAIL (%d)\n", h_errno); + switch (h_errno) + { + case TRY_AGAIN: + if (UseNameServer) + { + CurEnv->e_status = "4.4.3"; + message("851 %s: Name server timeout", + shortenstring(name, 33)); + } + *statp = EX_TEMPFAIL; + break; + + case HOST_NOT_FOUND: + case NO_DATA: + *statp = EX_NOHOST; + break; + + case NO_RECOVERY: + *statp = EX_SOFTWARE; + break; + + default: + *statp = EX_UNAVAILABLE; + break; + } +#else + if (tTd(9, 1)) + printf("FAIL\n"); + *statp = EX_NOHOST; +#endif + s->s_namecanon.nc_stat = *statp; + return NULL; + } + } + if ((cp = strchr(name, ']')) == NULL) + return (NULL); + *cp = '\0'; + in_addr.s_addr = inet_addr(&name[1]); + + /* nope -- ask the name server */ + hp = sm_gethostbyaddr((char *)&in_addr, INADDRSZ, AF_INET); + s->s_namecanon.nc_errno = errno; +#if NAMED_BIND + s->s_namecanon.nc_herrno = h_errno; +#endif + s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */ + if (hp == NULL) + { + s->s_namecanon.nc_stat = *statp = EX_NOHOST; + return (NULL); + } + + /* found a match -- copy out */ + cp = map_rewrite(map, (char *) hp->h_name, strlen(hp->h_name), av); + s->s_namecanon.nc_stat = *statp = EX_OK; + s->s_namecanon.nc_cname = newstr(cp); + return cp; +} +/* +** ANYNET_NTOA -- convert a network address to printable form. +** +** Parameters: +** sap -- a pointer to a sockaddr structure. +** +** Returns: +** A printable version of that sockaddr. +*/ + +#if NETLINK +# include <net/if_dl.h> +#endif + +char * +anynet_ntoa(sap) + register SOCKADDR *sap; +{ + register char *bp; + register char *ap; + int l; + static char buf[100]; + + /* check for null/zero family */ + if (sap == NULL) + return "NULLADDR"; + if (sap->sa.sa_family == 0) + return "0"; + + switch (sap->sa.sa_family) + { +#if NETUNIX + case AF_UNIX: + if (sap->sunix.sun_path[0] != '\0') + sprintf(buf, "[UNIX: %.64s]", sap->sunix.sun_path); + else + sprintf(buf, "[UNIX: localhost]"); + return buf; +#endif + +#if NETINET + case AF_INET: + return inet_ntoa(sap->sin.sin_addr); +#endif + +#if NETLINK + case AF_LINK: + sprintf(buf, "[LINK: %s]", + link_ntoa((struct sockaddr_dl *) &sap->sa)); + return buf; +#endif + default: + /* this case is needed when nothing is #defined */ + /* in order to keep the switch syntactically correct */ + break; + } + + /* unknown family -- just dump bytes */ + (void) sprintf(buf, "Family %d: ", sap->sa.sa_family); + bp = &buf[strlen(buf)]; + ap = sap->sa.sa_data; + for (l = sizeof sap->sa.sa_data; --l >= 0; ) + { + (void) sprintf(bp, "%02x:", *ap++ & 0377); + bp += 3; + } + *--bp = '\0'; + return buf; +} +/* +** HOSTNAMEBYANYADDR -- return name of host based on address +** +** Parameters: +** sap -- SOCKADDR pointer +** +** Returns: +** text representation of host name. +** +** Side Effects: +** none. +*/ + +char * +hostnamebyanyaddr(sap) + register SOCKADDR *sap; +{ + register struct hostent *hp; + int saveretry; + +#if NAMED_BIND + /* shorten name server timeout to avoid higher level timeouts */ + saveretry = _res.retry; + _res.retry = 3; +#endif /* NAMED_BIND */ + + switch (sap->sa.sa_family) + { +#if NETINET + case AF_INET: + hp = sm_gethostbyaddr((char *) &sap->sin.sin_addr, + INADDRSZ, + AF_INET); + break; +#endif + +#if NETISO + case AF_ISO: + hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr, + sizeof sap->siso.siso_addr, + AF_ISO); + break; +#endif + + case AF_UNIX: + hp = NULL; + break; + + default: + hp = sm_gethostbyaddr(sap->sa.sa_data, + sizeof sap->sa.sa_data, + sap->sa.sa_family); + break; + } + +#if NAMED_BIND + _res.retry = saveretry; +#endif /* NAMED_BIND */ + + if (hp != NULL) + return (char *) hp->h_name; + else + { + /* produce a dotted quad */ + static char buf[203]; + + (void) sprintf(buf, "[%.200s]", anynet_ntoa(sap)); + return buf; + } +} + +# else /* DAEMON */ +/* code for systems without sophisticated networking */ + +/* +** MYHOSTNAME -- stub version for case of no daemon code. +** +** Can't convert to upper case here because might be a UUCP name. +** +** Mark, you can change this to be anything you want...... +*/ + +char ** +myhostname(hostbuf, size) + char hostbuf[]; + int size; +{ + register FILE *f; + + hostbuf[0] = '\0'; + f = fopen("/usr/include/whoami", "r"); + if (f != NULL) + { + (void) fgets(hostbuf, size, f); + fixcrlf(hostbuf, TRUE); + (void) fclose(f); + } + return (NULL); +} +/* +** GETAUTHINFO -- get the real host name asociated with a file descriptor +** +** Parameters: +** fd -- the descriptor +** +** Returns: +** The host name associated with this descriptor, if it can +** be determined. +** NULL otherwise. +** +** Side Effects: +** none +*/ + +char * +getauthinfo(fd) + int fd; +{ + return NULL; +} +/* +** MAPHOSTNAME -- turn a hostname into canonical form +** +** Parameters: +** map -- a pointer to the database map. +** name -- a buffer containing a hostname. +** avp -- a pointer to a (cf file defined) argument vector. +** statp -- an exit status (out parameter). +** +** Returns: +** mapped host name +** FALSE otherwise. +** +** Side Effects: +** Looks up the host specified in name. If it is not +** the canonical name for that host, replace it with +** the canonical name. If the name is unknown, or it +** is already the canonical name, leave it unchanged. +*/ + +/*ARGSUSED*/ +char * +host_map_lookup(map, name, avp, statp) + MAP *map; + char *name; + char **avp; + char *statp; +{ + register struct hostent *hp; + + hp = sm_gethostbyname(name); + if (hp != NULL) + return hp->h_name; + *statp = EX_NOHOST; + return NULL; +} + +#endif /* DAEMON */ diff --git a/usr.sbin/sendmail/src/deliver.c b/usr.sbin/sendmail/src/deliver.c new file mode 100644 index 000000000000..2435f0477836 --- /dev/null +++ b/usr.sbin/sendmail/src/deliver.c @@ -0,0 +1,3016 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)deliver.c 8.185 (Berkeley) 11/18/95"; +#endif /* not lint */ + +#include "sendmail.h" +#include <errno.h> +#if NAMED_BIND +#include <resolv.h> + +extern int h_errno; +#endif + +#ifdef SMTP +extern char SmtpError[]; +#endif + +/* +** SENDALL -- actually send all the messages. +** +** Parameters: +** e -- the envelope to send. +** mode -- the delivery mode to use. If SM_DEFAULT, use +** the current e->e_sendmode. +** +** Returns: +** none. +** +** Side Effects: +** Scans the send lists and sends everything it finds. +** Delivers any appropriate error messages. +** If we are running in a non-interactive mode, takes the +** appropriate action. +*/ + +void +sendall(e, mode) + ENVELOPE *e; + char mode; +{ + register ADDRESS *q; + char *owner; + int otherowners; + register ENVELOPE *ee; + ENVELOPE *splitenv = NULL; + bool oldverbose = Verbose; + bool somedeliveries = FALSE; + int pid; + extern void sendenvelope(); + + /* + ** If we have had global, fatal errors, don't bother sending + ** the message at all if we are in SMTP mode. Local errors + ** (e.g., a single address failing) will still cause the other + ** addresses to be sent. + */ + + if (bitset(EF_FATALERRS, e->e_flags) && + (OpMode == MD_SMTP || OpMode == MD_DAEMON)) + { + e->e_flags |= EF_CLRQUEUE; + return; + } + + /* determine actual delivery mode */ + CurrentLA = getla(); + if (mode == SM_DEFAULT) + { + mode = e->e_sendmode; + if (mode != SM_VERIFY && mode != SM_DEFER && + shouldqueue(e->e_msgpriority, e->e_ctime)) + mode = SM_QUEUE; + } + + if (tTd(13, 1)) + { + extern void printenvflags(); + + printf("\n===== SENDALL: mode %c, id %s, e_from ", + mode, e->e_id); + printaddr(&e->e_from, FALSE); + printf("\te_flags = "); + printenvflags(e); + printf("sendqueue:\n"); + printaddr(e->e_sendqueue, TRUE); + } + + /* + ** Do any preprocessing necessary for the mode we are running. + ** Check to make sure the hop count is reasonable. + ** Delete sends to the sender in mailing lists. + */ + + CurEnv = e; + + if (e->e_hopcount > MaxHopCount) + { + errno = 0; +#ifdef QUEUE + queueup(e, mode == SM_QUEUE || mode == SM_DEFER); +#endif + e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE; + syserr("554 Too many hops %d (%d max): from %s via %s, to %s", + e->e_hopcount, MaxHopCount, e->e_from.q_paddr, + RealHostName == NULL ? "localhost" : RealHostName, + e->e_sendqueue->q_paddr); + e->e_sendqueue->q_status = "5.4.6"; + return; + } + + /* + ** Do sender deletion. + ** + ** If the sender has the QQUEUEUP flag set, skip this. + ** This can happen if the name server is hosed when you + ** are trying to send mail. The result is that the sender + ** is instantiated in the queue as a recipient. + */ + + if (!bitset(EF_METOO, e->e_flags) && + !bitset(QQUEUEUP, e->e_from.q_flags)) + { + if (tTd(13, 5)) + { + printf("sendall: QDONTSEND "); + printaddr(&e->e_from, FALSE); + } + e->e_from.q_flags |= QDONTSEND; + (void) recipient(&e->e_from, &e->e_sendqueue, 0, e); + } + + /* + ** Handle alias owners. + ** + ** We scan up the q_alias chain looking for owners. + ** We discard owners that are the same as the return path. + */ + + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + register struct address *a; + + for (a = q; a != NULL && a->q_owner == NULL; a = a->q_alias) + continue; + if (a != NULL) + q->q_owner = a->q_owner; + + if (q->q_owner != NULL && + !bitset(QDONTSEND, q->q_flags) && + strcmp(q->q_owner, e->e_from.q_paddr) == 0) + q->q_owner = NULL; + } + + owner = ""; + otherowners = 1; + while (owner != NULL && otherowners > 0) + { + owner = NULL; + otherowners = 0; + + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (tTd(13, 30)) + { + printf("Checking "); + printaddr(q, FALSE); + } + if (bitset(QDONTSEND, q->q_flags)) + { + if (tTd(13, 30)) + printf(" ... QDONTSEND\n"); + continue; + } + + if (q->q_owner != NULL) + { + if (owner == NULL) + owner = q->q_owner; + else if (owner != q->q_owner) + { + if (strcmp(owner, q->q_owner) == 0) + { + /* make future comparisons cheap */ + q->q_owner = owner; + } + else + { + otherowners++; + } + owner = q->q_owner; + } + } + else + { + otherowners++; + } + + /* + ** If this mailer is expensive, and if we don't + ** want to make connections now, just mark these + ** addresses and return. This is useful if we + ** want to batch connections to reduce load. This + ** will cause the messages to be queued up, and a + ** daemon will come along to send the messages later. + */ + + if (bitset(QBADADDR|QQUEUEUP, q->q_flags)) + { + if (tTd(13, 30)) + printf(" ... QBADADDR|QQUEUEUP\n"); + continue; + } + if (NoConnect && !Verbose && + bitnset(M_EXPENSIVE, q->q_mailer->m_flags)) + { + if (tTd(13, 30)) + printf(" ... expensive\n"); + q->q_flags |= QQUEUEUP; + } + else + { + if (tTd(13, 30)) + printf(" ... deliverable\n"); + somedeliveries = TRUE; + } + } + + if (owner != NULL && otherowners > 0) + { + extern HDR *copyheader(); + extern ADDRESS *copyqueue(); + + /* + ** Split this envelope into two. + */ + + ee = (ENVELOPE *) xalloc(sizeof(ENVELOPE)); + *ee = *e; + ee->e_id = NULL; + (void) queuename(ee, '\0'); + + if (tTd(13, 1)) + printf("sendall: split %s into %s\n", + e->e_id, ee->e_id); + + ee->e_header = copyheader(e->e_header); + ee->e_sendqueue = copyqueue(e->e_sendqueue); + ee->e_errorqueue = copyqueue(e->e_errorqueue); + ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT|EF_RET_PARAM); + ee->e_flags |= EF_NORECEIPT; + setsender(owner, ee, NULL, TRUE); + if (tTd(13, 5)) + { + printf("sendall(split): QDONTSEND "); + printaddr(&ee->e_from, FALSE); + } + ee->e_from.q_flags |= QDONTSEND; + ee->e_dfp = NULL; + ee->e_xfp = NULL; + ee->e_errormode = EM_MAIL; + ee->e_sibling = splitenv; + splitenv = ee; + + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (q->q_owner == owner) + { + q->q_flags |= QDONTSEND; + q->q_flags &= ~QQUEUEUP; + } + } + for (q = ee->e_sendqueue; q != NULL; q = q->q_next) + { + if (q->q_owner != owner) + { + q->q_flags |= QDONTSEND; + q->q_flags &= ~QQUEUEUP; + } + else + { + /* clear DSN parameters */ + q->q_flags &= ~(QHASNOTIFY|QPINGONSUCCESS); + q->q_flags |= QPINGONFAILURE|QPINGONDELAY; + } + } + + if (mode != SM_VERIFY && bitset(EF_HAS_DF, e->e_flags)) + { + char df1buf[20], df2buf[20]; + + ee->e_dfp = NULL; + strcpy(df1buf, queuename(e, 'd')); + strcpy(df2buf, queuename(ee, 'd')); + if (link(df1buf, df2buf) < 0) + { + int saverrno = errno; + + syserr("sendall: link(%s, %s)", + df1buf, df2buf); + if (saverrno == EEXIST) + { + if (unlink(df2buf) < 0) + { + syserr("!sendall: unlink(%s): permanent", + df2buf); + /*NOTREACHED*/ + } + if (link(df1buf, df2buf) < 0) + { + syserr("!sendall: link(%s, %s): permanent", + df1buf, df2buf); + /*NOTREACHED*/ + } + } + } + } +#ifdef LOG + if (LogLevel > 4) + syslog(LOG_INFO, "%s: clone %s, owner=%s", + ee->e_id, e->e_id, owner); +#endif + } + } + + if (owner != NULL) + { + setsender(owner, e, NULL, TRUE); + if (tTd(13, 5)) + { + printf("sendall(owner): QDONTSEND "); + printaddr(&e->e_from, FALSE); + } + e->e_from.q_flags |= QDONTSEND; + e->e_errormode = EM_MAIL; + e->e_flags |= EF_NORECEIPT; + } + + /* if nothing to be delivered, just queue up everything */ + if (!somedeliveries && mode != SM_QUEUE && mode != SM_DEFER && + mode != SM_VERIFY) + { + if (tTd(13, 29)) + printf("No deliveries: auto-queuing\n"); + mode = SM_QUEUE; + } + +# ifdef QUEUE + if ((mode == SM_QUEUE || mode == SM_DEFER || mode == SM_FORK || + (mode != SM_VERIFY && SuperSafe)) && + !bitset(EF_INQUEUE, e->e_flags)) + { + /* be sure everything is instantiated in the queue */ + queueup(e, mode == SM_QUEUE || mode == SM_DEFER); + for (ee = splitenv; ee != NULL; ee = ee->e_sibling) + queueup(ee, mode == SM_QUEUE || mode == SM_DEFER); + } +#endif /* QUEUE */ + + /* + ** If we belong in background, fork now. + */ + + if (tTd(13, 20)) + printf("sendall: final mode = %c\n", mode); + switch (mode) + { + case SM_VERIFY: + Verbose = TRUE; + break; + + case SM_QUEUE: + case SM_DEFER: + queueonly: + if (e->e_nrcpts > 0) + e->e_flags |= EF_INQUEUE; + return; + + case SM_FORK: + if (e->e_xfp != NULL) + (void) fflush(e->e_xfp); + +# if !HASFLOCK + /* + ** Since fcntl locking has the interesting semantic that + ** the lock is owned by a process, not by an open file + ** descriptor, we have to flush this to the queue, and + ** then restart from scratch in the child. + */ + + { + /* save id for future use */ + char *qid = e->e_id; + + /* now drop the envelope in the parent */ + e->e_flags |= EF_INQUEUE; + dropenvelope(e); + + /* and reacquire in the child */ + (void) dowork(qid, TRUE, FALSE, e); + } + + return; + +# else /* HASFLOCK */ + + pid = fork(); + if (pid < 0) + { + goto queueonly; + } + else if (pid > 0) + { + /* be sure we leave the temp files to our child */ + /* can't call unlockqueue to avoid unlink of xfp */ + if (e->e_lockfp != NULL) + (void) xfclose(e->e_lockfp, "sendenvelope lockfp", e->e_id); + e->e_lockfp = NULL; + + /* close any random open files in the envelope */ + closexscript(e); + if (e->e_dfp != NULL) + (void) xfclose(e->e_dfp, "sendenvelope dfp", e->e_id); + e->e_dfp = NULL; + e->e_id = NULL; + e->e_flags &= ~EF_HAS_DF; + + /* catch intermediate zombie */ + (void) waitfor(pid); + return; + } + + /* double fork to avoid zombies */ + pid = fork(); + if (pid > 0) + exit(EX_OK); + + /* be sure we are immune from the terminal */ + disconnect(1, e); + + /* prevent parent from waiting if there was an error */ + if (pid < 0) + { + e->e_flags |= EF_INQUEUE; + finis(); + } + + /* + ** Close any cached connections. + ** + ** We don't send the QUIT protocol because the parent + ** still knows about the connection. + ** + ** This should only happen when delivering an error + ** message. + */ + + mci_flush(FALSE, NULL); + +# endif /* HASFLOCK */ + + break; + } + + if (splitenv != NULL) + { + if (tTd(13, 2)) + { + printf("\nsendall: Split queue; remaining queue:\n"); + printaddr(e->e_sendqueue, TRUE); + } + + for (ee = splitenv; ee != NULL; ee = ee->e_sibling) + { + CurEnv = ee; + if (mode != SM_VERIFY) + openxscript(ee); + sendenvelope(ee, mode); + dropenvelope(ee); + } + + CurEnv = e; + } + sendenvelope(e, mode); + Verbose = oldverbose; + if (mode == SM_FORK) + finis(); +} + +void +sendenvelope(e, mode) + register ENVELOPE *e; + char mode; +{ + register ADDRESS *q; + bool didany; + + if (tTd(13, 10)) + printf("sendenvelope(%s) e_flags=0x%x\n", + e->e_id == NULL ? "[NOQUEUE]" : e->e_id, + e->e_flags); +#ifdef LOG + if (LogLevel > 80) + syslog(LOG_DEBUG, "%s: sendenvelope, flags=0x%x", + e->e_id == NULL ? "[NOQUEUE]" : e->e_id, + e->e_flags); +#endif + + /* + ** If we have had global, fatal errors, don't bother sending + ** the message at all if we are in SMTP mode. Local errors + ** (e.g., a single address failing) will still cause the other + ** addresses to be sent. + */ + + if (bitset(EF_FATALERRS, e->e_flags) && + (OpMode == MD_SMTP || OpMode == MD_DAEMON)) + { + e->e_flags |= EF_CLRQUEUE; + return; + } + + /* + ** Run through the list and send everything. + ** + ** Set EF_GLOBALERRS so that error messages during delivery + ** result in returned mail. + */ + + e->e_nsent = 0; + e->e_flags |= EF_GLOBALERRS; + didany = FALSE; + + /* now run through the queue */ + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { +#if XDEBUG + char wbuf[MAXNAME + 20]; + + (void) sprintf(wbuf, "sendall(%.*s)", MAXNAME, q->q_paddr); + checkfd012(wbuf); +#endif + if (mode == SM_VERIFY) + { + e->e_to = q->q_paddr; + if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) + { + if (q->q_host != NULL && q->q_host[0] != '\0') + message("deliverable: mailer %s, host %s, user %s", + q->q_mailer->m_name, + q->q_host, + q->q_user); + else + message("deliverable: mailer %s, user %s", + q->q_mailer->m_name, + q->q_user); + } + } + else if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) + { +# ifdef QUEUE + /* + ** Checkpoint the send list every few addresses + */ + + if (e->e_nsent >= CheckpointInterval) + { + queueup(e, FALSE); + e->e_nsent = 0; + } +# endif /* QUEUE */ + (void) deliver(e, q); + didany = TRUE; + } + } + if (didany) + { + e->e_dtime = curtime(); + e->e_ntries++; + } + +#if XDEBUG + checkfd012("end of sendenvelope"); +#endif +} +/* +** DOFORK -- do a fork, retrying a couple of times on failure. +** +** This MUST be a macro, since after a vfork we are running +** two processes on the same stack!!! +** +** Parameters: +** none. +** +** Returns: +** From a macro??? You've got to be kidding! +** +** Side Effects: +** Modifies the ==> LOCAL <== variable 'pid', leaving: +** pid of child in parent, zero in child. +** -1 on unrecoverable error. +** +** Notes: +** I'm awfully sorry this looks so awful. That's +** vfork for you..... +*/ + +# define NFORKTRIES 5 + +# ifndef FORK +# define FORK fork +# endif + +# define DOFORK(fORKfN) \ +{\ + register int i;\ +\ + for (i = NFORKTRIES; --i >= 0; )\ + {\ + pid = fORKfN();\ + if (pid >= 0)\ + break;\ + if (i > 0)\ + sleep((unsigned) NFORKTRIES - i);\ + }\ +} +/* +** DOFORK -- simple fork interface to DOFORK. +** +** Parameters: +** none. +** +** Returns: +** pid of child in parent. +** zero in child. +** -1 on error. +** +** Side Effects: +** returns twice, once in parent and once in child. +*/ + +int +dofork() +{ + register int pid = -1; + + DOFORK(fork); + return (pid); +} +/* +** DELIVER -- Deliver a message to a list of addresses. +** +** This routine delivers to everyone on the same host as the +** user on the head of the list. It is clever about mailers +** that don't handle multiple users. It is NOT guaranteed +** that it will deliver to all these addresses however -- so +** deliver should be called once for each address on the +** list. +** +** Parameters: +** e -- the envelope to deliver. +** firstto -- head of the address list to deliver to. +** +** Returns: +** zero -- successfully delivered. +** else -- some failure, see ExitStat for more info. +** +** Side Effects: +** The standard input is passed off to someone. +*/ + +int +deliver(e, firstto) + register ENVELOPE *e; + ADDRESS *firstto; +{ + char *host; /* host being sent to */ + char *user; /* user being sent to */ + char **pvp; + register char **mvp; + register char *p; + register MAILER *m; /* mailer for this recipient */ + ADDRESS *volatile ctladdr; + register MCI *volatile mci; + register ADDRESS *to = firstto; + volatile bool clever = FALSE; /* running user smtp to this mailer */ + ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */ + int rcode; /* response code */ + char *firstsig; /* signature of firstto */ + int pid = -1; + char *volatile curhost; + time_t xstart; + int mpvect[2]; + int rpvect[2]; + char *pv[MAXPV+1]; + char tobuf[TOBUFSIZE]; /* text line of to people */ + char buf[MAXNAME + 1]; + char rpathbuf[MAXNAME + 1]; /* translated return path */ + extern int checkcompat(); + extern void markfailure __P((ENVELOPE *, ADDRESS *, MCI *, int)); + + errno = 0; + if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags)) + return (0); + +#if NAMED_BIND + /* unless interactive, try twice, over a minute */ + if (OpMode == MD_DAEMON || OpMode == MD_SMTP) + { + _res.retrans = 30; + _res.retry = 2; + } +#endif + + m = to->q_mailer; + host = to->q_host; + CurEnv = e; /* just in case */ + e->e_statmsg = NULL; +#ifdef SMTP + SmtpError[0] = '\0'; +#endif + xstart = curtime(); + + if (tTd(10, 1)) + printf("\n--deliver, id=%s, mailer=%s, host=`%s', first user=`%s'\n", + e->e_id, m->m_name, host, to->q_user); + if (tTd(10, 100)) + printopenfds(FALSE); + + /* + ** Do initial argv setup. + ** Insert the mailer name. Notice that $x expansion is + ** NOT done on the mailer name. Then, if the mailer has + ** a picky -f flag, we insert it as appropriate. This + ** code does not check for 'pv' overflow; this places a + ** manifest lower limit of 4 for MAXPV. + ** The from address rewrite is expected to make + ** the address relative to the other end. + */ + + /* rewrite from address, using rewriting rules */ + rcode = EX_OK; + if (bitnset(M_UDBENVELOPE, e->e_from.q_mailer->m_flags)) + p = e->e_sender; + else + p = e->e_from.q_paddr; + (void) strcpy(rpathbuf, remotename(p, m, + RF_SENDERADDR|RF_CANONICAL, + &rcode, e)); + define('g', rpathbuf, e); /* translated return path */ + define('h', host, e); /* to host */ + Errors = 0; + pvp = pv; + *pvp++ = m->m_argv[0]; + + /* insert -f or -r flag as appropriate */ + if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags))) + { + if (bitnset(M_FOPT, m->m_flags)) + *pvp++ = "-f"; + else + *pvp++ = "-r"; + *pvp++ = newstr(rpathbuf); + } + + /* + ** Append the other fixed parts of the argv. These run + ** up to the first entry containing "$u". There can only + ** be one of these, and there are only a few more slots + ** in the pv after it. + */ + + for (mvp = m->m_argv; (p = *++mvp) != NULL; ) + { + /* can't use strchr here because of sign extension problems */ + while (*p != '\0') + { + if ((*p++ & 0377) == MACROEXPAND) + { + if (*p == 'u') + break; + } + } + + if (*p != '\0') + break; + + /* this entry is safe -- go ahead and process it */ + expand(*mvp, buf, sizeof buf, e); + *pvp++ = newstr(buf); + if (pvp >= &pv[MAXPV - 3]) + { + syserr("554 Too many parameters to %s before $u", pv[0]); + return (-1); + } + } + + /* + ** If we have no substitution for the user name in the argument + ** list, we know that we must supply the names otherwise -- and + ** SMTP is the answer!! + */ + + if (*mvp == NULL) + { + /* running SMTP */ +# ifdef SMTP + clever = TRUE; + *pvp = NULL; +# else /* SMTP */ + /* oops! we don't implement SMTP */ + syserr("554 SMTP style mailer not implemented"); + return (EX_SOFTWARE); +# endif /* SMTP */ + } + + /* + ** At this point *mvp points to the argument with $u. We + ** run through our address list and append all the addresses + ** we can. If we run out of space, do not fret! We can + ** always send another copy later. + */ + + tobuf[0] = '\0'; + e->e_to = tobuf; + ctladdr = NULL; + firstsig = hostsignature(firstto->q_mailer, firstto->q_host, e); + for (; to != NULL; to = to->q_next) + { + /* avoid sending multiple recipients to dumb mailers */ + if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags)) + break; + + /* if already sent or not for this host, don't send */ + if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) || + to->q_mailer != firstto->q_mailer || + strcmp(hostsignature(to->q_mailer, to->q_host, e), firstsig) != 0) + continue; + + /* avoid overflowing tobuf */ + if (sizeof tobuf < (strlen(to->q_paddr) + strlen(tobuf) + 2)) + break; + + if (tTd(10, 1)) + { + printf("\nsend to "); + printaddr(to, FALSE); + } + + /* compute effective uid/gid when sending */ + if (bitnset(M_RUNASRCPT, to->q_mailer->m_flags)) + ctladdr = getctladdr(to); + + if (tTd(10, 2)) + { + printf("ctladdr="); + printaddr(ctladdr, FALSE); + } + + user = to->q_user; + e->e_to = to->q_paddr; + if (tTd(10, 5)) + { + printf("deliver: QDONTSEND "); + printaddr(to, FALSE); + } + to->q_flags |= QDONTSEND; + + /* + ** Check to see that these people are allowed to + ** talk to each other. + */ + + if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize) + { + e->e_flags |= EF_NO_BODY_RETN; + to->q_status = "5.2.3"; + usrerr("552 Message is too large; %ld bytes max", m->m_maxsize); + giveresponse(EX_UNAVAILABLE, m, NULL, ctladdr, xstart, e); + continue; + } +#if NAMED_BIND + h_errno = 0; +#endif + rcode = checkcompat(to, e); + if (rcode != EX_OK) + { + markfailure(e, to, NULL, rcode); + giveresponse(rcode, m, NULL, ctladdr, xstart, e); + continue; + } + + /* + ** Strip quote bits from names if the mailer is dumb + ** about them. + */ + + if (bitnset(M_STRIPQ, m->m_flags)) + { + stripquotes(user); + stripquotes(host); + } + + /* hack attack -- delivermail compatibility */ + if (m == ProgMailer && *user == '|') + user++; + + /* + ** If an error message has already been given, don't + ** bother to send to this address. + ** + ** >>>>>>>>>> This clause assumes that the local mailer + ** >> NOTE >> cannot do any further aliasing; that + ** >>>>>>>>>> function is subsumed by sendmail. + */ + + if (bitset(QBADADDR|QQUEUEUP, to->q_flags)) + continue; + + /* save statistics.... */ + markstats(e, to); + + /* + ** See if this user name is "special". + ** If the user name has a slash in it, assume that this + ** is a file -- send it off without further ado. Note + ** that this type of addresses is not processed along + ** with the others, so we fudge on the To person. + */ + + if (strcmp(m->m_mailer, "[FILE]") == 0) + { + rcode = mailfile(user, ctladdr, SFF_CREAT, e); + giveresponse(rcode, m, NULL, ctladdr, xstart, e); + e->e_nsent++; + if (rcode == EX_OK) + { + to->q_flags |= QSENT; + if (bitnset(M_LOCALMAILER, m->m_flags) && + (e->e_receiptto != NULL || + bitset(QPINGONSUCCESS, to->q_flags))) + { + to->q_flags |= QDELIVERED; + to->q_status = "2.1.5"; + fprintf(e->e_xfp, "%s... Successfully delivered\n", + to->q_paddr); + } + } + to->q_statdate = curtime(); + continue; + } + + /* + ** Address is verified -- add this user to mailer + ** argv, and add it to the print list of recipients. + */ + + /* link together the chain of recipients */ + to->q_tchain = tochain; + tochain = to; + + /* create list of users for error messages */ + (void) strcat(tobuf, ","); + (void) strcat(tobuf, to->q_paddr); + define('u', user, e); /* to user */ + p = to->q_home; + if (p == NULL && ctladdr != NULL) + p = ctladdr->q_home; + define('z', p, e); /* user's home */ + + /* + ** Expand out this user into argument list. + */ + + if (!clever) + { + expand(*mvp, buf, sizeof buf, e); + *pvp++ = newstr(buf); + if (pvp >= &pv[MAXPV - 2]) + { + /* allow some space for trailing parms */ + break; + } + } + } + + /* see if any addresses still exist */ + if (tobuf[0] == '\0') + { + define('g', (char *) NULL, e); + return (0); + } + + /* print out messages as full list */ + e->e_to = tobuf + 1; + + /* + ** Fill out any parameters after the $u parameter. + */ + + while (!clever && *++mvp != NULL) + { + expand(*mvp, buf, sizeof buf, e); + *pvp++ = newstr(buf); + if (pvp >= &pv[MAXPV]) + syserr("554 deliver: pv overflow after $u for %s", pv[0]); + } + *pvp++ = NULL; + + /* + ** Call the mailer. + ** The argument vector gets built, pipes + ** are created as necessary, and we fork & exec as + ** appropriate. + ** If we are running SMTP, we just need to clean up. + */ + + /*XXX this seems a bit wierd */ + if (ctladdr == NULL && m != ProgMailer && m != FileMailer && + bitset(QGOODUID, e->e_from.q_flags)) + ctladdr = &e->e_from; + +#if NAMED_BIND + if (ConfigLevel < 2) + _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */ +#endif + + if (tTd(11, 1)) + { + printf("openmailer:"); + printav(pv); + } + errno = 0; +#if NAMED_BIND + h_errno = 0; +#endif + + CurHostName = NULL; + + /* + ** Deal with the special case of mail handled through an IPC + ** connection. + ** In this case we don't actually fork. We must be + ** running SMTP for this to work. We will return a + ** zero pid to indicate that we are running IPC. + ** We also handle a debug version that just talks to stdin/out. + */ + + curhost = NULL; + SmtpPhase = NULL; + mci = NULL; + +#if XDEBUG + { + char wbuf[MAXLINE]; + + /* make absolutely certain 0, 1, and 2 are in use */ + sprintf(wbuf, "%s... openmailer(%s)", + shortenstring(e->e_to, 203), m->m_name); + checkfd012(wbuf); + } +#endif + + /* check for 8-bit available */ + if (bitset(EF_HAS8BIT, e->e_flags) && + bitnset(M_7BITS, m->m_flags) && + (bitset(EF_DONT_MIME, e->e_flags) || + !(bitset(MM_MIME8BIT, MimeMode) || + (bitset(EF_IS_MIME, e->e_flags) && + bitset(MM_CVTMIME, MimeMode))))) + { + usrerr("554 Cannot send 8-bit data to 7-bit destination"); + rcode = EX_DATAERR; + e->e_status = "5.6.3"; + goto give_up; + } + + /* check for Local Person Communication -- not for mortals!!! */ + if (strcmp(m->m_mailer, "[LPC]") == 0) + { + mci = (MCI *) xalloc(sizeof *mci); + bzero((char *) mci, sizeof *mci); + mci->mci_in = stdin; + mci->mci_out = stdout; + mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN; + mci->mci_mailer = m; + } + else if (strcmp(m->m_mailer, "[IPC]") == 0 || + strcmp(m->m_mailer, "[TCP]") == 0) + { +#ifdef DAEMON + register int i; + register volatile u_short port = 0; + + if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0') + { + syserr("null host name for %s mailer", m->m_mailer); + rcode = EX_CONFIG; + goto give_up; + } + + CurHostName = pv[1]; + curhost = hostsignature(m, pv[1], e); + + if (curhost == NULL || curhost[0] == '\0') + { + syserr("null host signature for %s", pv[1]); + rcode = EX_CONFIG; + goto give_up; + } + + if (!clever) + { + syserr("554 non-clever IPC"); + rcode = EX_CONFIG; + goto give_up; + } + if (pv[2] != NULL) + { + port = htons(atoi(pv[2])); + if (port == 0) + { + struct servent *sp = getservbyname(pv[2], "tcp"); + + if (sp == NULL) + syserr("Service %s unknown", pv[2]); + else + port = sp->s_port; + } + } +tryhost: + while (*curhost != '\0') + { + register char *p; + static char hostbuf[MAXNAME + 1]; + + /* pull the next host from the signature */ + p = strchr(curhost, ':'); + if (p == NULL) + p = &curhost[strlen(curhost)]; + if (p == curhost) + { + syserr("deliver: null host name in signature"); + curhost++; + continue; + } + strncpy(hostbuf, curhost, p - curhost); + hostbuf[p - curhost] = '\0'; + if (*p != '\0') + p++; + curhost = p; + + /* see if we already know that this host is fried */ + CurHostName = hostbuf; + mci = mci_get(hostbuf, m); + if (mci->mci_state != MCIS_CLOSED) + { + if (tTd(11, 1)) + { + printf("openmailer: "); + mci_dump(mci, FALSE); + } + CurHostName = mci->mci_host; + message("Using cached %sSMTP connection to %s via %s...", + bitset(MCIF_ESMTP, mci->mci_flags) ? "E" : "", + hostbuf, m->m_name); + break; + } + mci->mci_mailer = m; + if (mci->mci_exitstat != EX_OK) + continue; + + /* try the connection */ + setproctitle("%s %s: %s", e->e_id, hostbuf, "user open"); + message("Connecting to %s via %s...", + hostbuf, m->m_name); + i = makeconnection(hostbuf, port, mci, + bitnset(M_SECURE_PORT, m->m_flags)); + mci->mci_lastuse = curtime(); + mci->mci_exitstat = i; + mci->mci_errno = errno; +#if NAMED_BIND + mci->mci_herrno = h_errno; +#endif + if (i == EX_OK) + { + mci->mci_state = MCIS_OPENING; + mci_cache(mci); + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%05d == CONNECT %s\n", + getpid(), hostbuf); + break; + } + else if (tTd(11, 1)) + printf("openmailer: makeconnection => stat=%d, errno=%d\n", + i, errno); + + /* enter status of this host */ + setstat(i); + + /* should print some message here for -v mode */ + } + if (mci == NULL) + { + syserr("deliver: no host name"); + rcode = EX_OSERR; + goto give_up; + } + mci->mci_pid = 0; +#else /* no DAEMON */ + syserr("554 openmailer: no IPC"); + if (tTd(11, 1)) + printf("openmailer: NULL\n"); + rcode = EX_UNAVAILABLE; + goto give_up; +#endif /* DAEMON */ + } + else + { + /* flush any expired connections */ + (void) mci_scan(NULL); + + /* announce the connection to verbose listeners */ + if (host == NULL || host[0] == '\0') + message("Connecting to %s...", m->m_name); + else + message("Connecting to %s via %s...", host, m->m_name); + if (TrafficLogFile != NULL) + { + char **av; + + fprintf(TrafficLogFile, "%05d === EXEC", getpid()); + for (av = pv; *av != NULL; av++) + fprintf(TrafficLogFile, " %s", *av); + fprintf(TrafficLogFile, "\n"); + } + + /* create a pipe to shove the mail through */ + if (pipe(mpvect) < 0) + { + syserr("%s... openmailer(%s): pipe (to mailer)", + shortenstring(e->e_to, 203), m->m_name); + if (tTd(11, 1)) + printf("openmailer: NULL\n"); + rcode = EX_OSERR; + goto give_up; + } + + /* if this mailer speaks smtp, create a return pipe */ +#ifdef SMTP + if (clever && pipe(rpvect) < 0) + { + syserr("%s... openmailer(%s): pipe (from mailer)", + shortenstring(e->e_to, 203), m->m_name); + (void) close(mpvect[0]); + (void) close(mpvect[1]); + if (tTd(11, 1)) + printf("openmailer: NULL\n"); + rcode = EX_OSERR; + goto give_up; + } +#endif + + /* + ** Actually fork the mailer process. + ** DOFORK is clever about retrying. + ** + ** Dispose of SIGCHLD signal catchers that may be laying + ** around so that endmail will get it. + */ + + if (e->e_xfp != NULL) + (void) fflush(e->e_xfp); /* for debugging */ + (void) fflush(stdout); +# ifdef SIGCHLD + (void) setsignal(SIGCHLD, SIG_DFL); +# endif /* SIGCHLD */ + DOFORK(FORK); + /* pid is set by DOFORK */ + if (pid < 0) + { + /* failure */ + syserr("%s... openmailer(%s): cannot fork", + shortenstring(e->e_to, 203), m->m_name); + (void) close(mpvect[0]); + (void) close(mpvect[1]); +#ifdef SMTP + if (clever) + { + (void) close(rpvect[0]); + (void) close(rpvect[1]); + } +#endif + if (tTd(11, 1)) + printf("openmailer: NULL\n"); + rcode = EX_OSERR; + goto give_up; + } + else if (pid == 0) + { + int i; + int saveerrno; + struct stat stb; + extern int DtableSize; + + if (e->e_lockfp != NULL) + (void) close(fileno(e->e_lockfp)); + + /* child -- set up input & exec mailer */ + (void) setsignal(SIGINT, SIG_IGN); + (void) setsignal(SIGHUP, SIG_IGN); + (void) setsignal(SIGTERM, SIG_DFL); + + if (m != FileMailer || stat(tochain->q_user, &stb) < 0) + stb.st_mode = 0; + + /* tweak niceness */ + if (m->m_nice != 0) + nice(m->m_nice); + + /* reset group id */ + if (bitnset(M_SPECIFIC_UID, m->m_flags)) + (void) setgid(m->m_gid); + else if (bitset(S_ISGID, stb.st_mode)) + (void) setgid(stb.st_gid); + else if (ctladdr != NULL && ctladdr->q_gid != 0) + { + if (!DontInitGroups) + (void) initgroups(ctladdr->q_ruser != NULL ? + ctladdr->q_ruser : ctladdr->q_user, + ctladdr->q_gid); + (void) setgid(ctladdr->q_gid); + } + else + { + if (!DontInitGroups) + (void) initgroups(DefUser, DefGid); + if (m->m_gid == 0) + (void) setgid(DefGid); + else + (void) setgid(m->m_gid); + } + + /* reset user id */ + endpwent(); + if (bitnset(M_SPECIFIC_UID, m->m_flags)) + { +#if USESETEUID + (void) seteuid(m->m_uid); +#else +# if HASSETREUID + (void) setreuid(-1, m->m_uid); +# else + if (m->m_uid != geteuid()) + (void) setuid(m->m_uid); +# endif +#endif + } + else if (bitset(S_ISUID, stb.st_mode)) + (void) setuid(stb.st_uid); + else if (ctladdr != NULL && ctladdr->q_uid != 0) + (void) setuid(ctladdr->q_uid); + else + { + if (m->m_uid == 0) + (void) setuid(DefUid); + else + (void) setuid(m->m_uid); + } + + if (tTd(11, 2)) + printf("openmailer: running as r/euid=%d/%d\n", + getuid(), geteuid()); + + /* move into some "safe" directory */ + if (m->m_execdir != NULL) + { + char *p, *q; + char buf[MAXLINE + 1]; + + for (p = m->m_execdir; p != NULL; p = q) + { + q = strchr(p, ':'); + if (q != NULL) + *q = '\0'; + expand(p, buf, sizeof buf, e); + if (q != NULL) + *q++ = ':'; + if (tTd(11, 20)) + printf("openmailer: trydir %s\n", + buf); + if (buf[0] != '\0' && chdir(buf) >= 0) + break; + } + } + + /* arrange to filter std & diag output of command */ +#ifdef SMTP + if (clever) + { + (void) close(rpvect[0]); + if (dup2(rpvect[1], STDOUT_FILENO) < 0) + { + syserr("%s... openmailer(%s): cannot dup pipe %d for stdout", + shortenstring(e->e_to, 203), + m->m_name, rpvect[1]); + _exit(EX_OSERR); + } + (void) close(rpvect[1]); + } + else if (OpMode == MD_SMTP || OpMode == MD_DAEMON || + HoldErrs || DisConnected) + { + /* put mailer output in transcript */ + if (dup2(fileno(e->e_xfp), STDOUT_FILENO) < 0) + { + syserr("%s... openmailer(%s): cannot dup xscript %d for stdout", + shortenstring(e->e_to, 203), + m->m_name, fileno(e->e_xfp)); + _exit(EX_OSERR); + } + } +#endif + if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0) + { + syserr("%s... openmailer(%s): cannot dup stdout for stderr", + shortenstring(e->e_to, 203), m->m_name); + _exit(EX_OSERR); + } + + /* arrange to get standard input */ + (void) close(mpvect[1]); + if (dup2(mpvect[0], STDIN_FILENO) < 0) + { + syserr("%s... openmailer(%s): cannot dup pipe %d for stdin", + shortenstring(e->e_to, 203), + m->m_name, mpvect[0]); + _exit(EX_OSERR); + } + (void) close(mpvect[0]); + + /* arrange for all the files to be closed */ + for (i = 3; i < DtableSize; i++) + { + register int j; + + if ((j = fcntl(i, F_GETFD, 0)) != -1) + (void) fcntl(i, F_SETFD, j | 1); + } + + /* run disconnected from terminal */ + (void) setsid(); + + /* try to execute the mailer */ + execve(m->m_mailer, (ARGV_T) pv, (ARGV_T) UserEnviron); + saveerrno = errno; + syserr("Cannot exec %s", m->m_mailer); + if (bitnset(M_LOCALMAILER, m->m_flags) || + transienterror(saveerrno)) + _exit(EX_OSERR); + _exit(EX_UNAVAILABLE); + } + + /* + ** Set up return value. + */ + + mci = (MCI *) xalloc(sizeof *mci); + bzero((char *) mci, sizeof *mci); + mci->mci_mailer = m; + mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN; + mci->mci_pid = pid; + (void) close(mpvect[0]); + mci->mci_out = fdopen(mpvect[1], "w"); + if (mci->mci_out == NULL) + { + syserr("deliver: cannot create mailer output channel, fd=%d", + mpvect[1]); + (void) close(mpvect[1]); +#ifdef SMTP + if (clever) + { + (void) close(rpvect[0]); + (void) close(rpvect[1]); + } +#endif + rcode = EX_OSERR; + goto give_up; + } +#ifdef SMTP + if (clever) + { + (void) close(rpvect[1]); + mci->mci_in = fdopen(rpvect[0], "r"); + if (mci->mci_in == NULL) + { + syserr("deliver: cannot create mailer input channel, fd=%d", + mpvect[1]); + (void) close(rpvect[0]); + fclose(mci->mci_out); + mci->mci_out = NULL; + rcode = EX_OSERR; + goto give_up; + } + } + else +#endif + { + mci->mci_flags |= MCIF_TEMP; + mci->mci_in = NULL; + } + } + + /* + ** If we are in SMTP opening state, send initial protocol. + */ + + if (bitnset(M_7BITS, m->m_flags) && + (!clever || mci->mci_state == MCIS_CLOSED)) + mci->mci_flags |= MCIF_7BIT; +#ifdef SMTP + if (clever && mci->mci_state != MCIS_CLOSED) + smtpinit(m, mci, e); +#endif + + if (bitset(EF_HAS8BIT, e->e_flags) && + !bitset(EF_DONT_MIME, e->e_flags) && + bitnset(M_7BITS, m->m_flags)) + mci->mci_flags |= MCIF_CVT8TO7; + else + mci->mci_flags &= ~MCIF_CVT8TO7; + + if (tTd(11, 1)) + { + printf("openmailer: "); + mci_dump(mci, FALSE); + } + + if (mci->mci_state != MCIS_OPEN) + { + /* couldn't open the mailer */ + rcode = mci->mci_exitstat; + errno = mci->mci_errno; +#if NAMED_BIND + h_errno = mci->mci_herrno; +#endif + if (rcode == EX_OK) + { + /* shouldn't happen */ + syserr("554 deliver: rcode=%d, mci_state=%d, sig=%s", + rcode, mci->mci_state, firstsig); + rcode = EX_SOFTWARE; + } +#ifdef DAEMON + else if (curhost != NULL && *curhost != '\0') + { + /* try next MX site */ + goto tryhost; + } +#endif + } + else if (!clever) + { + /* + ** Format and send message. + */ + + putfromline(mci, e); + (*e->e_puthdr)(mci, e->e_header, e); + (*e->e_putbody)(mci, e, NULL); + + /* get the exit status */ + rcode = endmailer(mci, e, pv); + } + else +#ifdef SMTP + { + /* + ** Send the MAIL FROM: protocol + */ + + rcode = smtpmailfrom(m, mci, e); + if (rcode == EX_OK) + { + register char *t = tobuf; + register int i; + + /* send the recipient list */ + tobuf[0] = '\0'; + for (to = tochain; to != NULL; to = to->q_tchain) + { + e->e_to = to->q_paddr; + if ((i = smtprcpt(to, m, mci, e)) != EX_OK) + { + markfailure(e, to, mci, i); + giveresponse(i, m, mci, ctladdr, xstart, e); + } + else + { + *t++ = ','; + for (p = to->q_paddr; *p; *t++ = *p++) + continue; + *t = '\0'; + } + } + + /* now send the data */ + if (tobuf[0] == '\0') + { + rcode = EX_OK; + e->e_to = NULL; + if (bitset(MCIF_CACHED, mci->mci_flags)) + smtprset(m, mci, e); + } + else + { + e->e_to = tobuf + 1; + rcode = smtpdata(m, mci, e); + } + + /* now close the connection */ + if (!bitset(MCIF_CACHED, mci->mci_flags)) + smtpquit(m, mci, e); + } + if (rcode != EX_OK && curhost != NULL && *curhost != '\0') + { + /* try next MX site */ + goto tryhost; + } + } +#else /* not SMTP */ + { + syserr("554 deliver: need SMTP compiled to use clever mailer"); + rcode = EX_CONFIG; + goto give_up; + } +#endif /* SMTP */ +#if NAMED_BIND + if (ConfigLevel < 2) + _res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */ +#endif + + /* arrange a return receipt if requested */ + if (rcode == EX_OK && e->e_receiptto != NULL && + bitnset(M_LOCALMAILER, m->m_flags)) + { + e->e_flags |= EF_SENDRECEIPT; + /* do we want to send back more info? */ + } + + /* + ** Do final status disposal. + ** We check for something in tobuf for the SMTP case. + ** If we got a temporary failure, arrange to queue the + ** addressees. + */ + + give_up: + if (tobuf[0] != '\0') + giveresponse(rcode, m, mci, ctladdr, xstart, e); + for (to = tochain; to != NULL; to = to->q_tchain) + { + /* see if address already marked */ + if (bitset(QBADADDR|QQUEUEUP, to->q_flags)) + continue; + + /* mark bad addresses */ + if (rcode != EX_OK) + { + markfailure(e, to, mci, rcode); + continue; + } + + /* successful delivery */ + to->q_flags |= QSENT; + to->q_statdate = curtime(); + e->e_nsent++; + if (bitnset(M_LOCALMAILER, m->m_flags) && + (e->e_receiptto != NULL || + bitset(QPINGONSUCCESS, to->q_flags))) + { + to->q_flags |= QDELIVERED; + to->q_status = "2.1.5"; + fprintf(e->e_xfp, "%s... Successfully delivered\n", + to->q_paddr); + } + else if (bitset(QPINGONSUCCESS, to->q_flags) && + bitset(QPRIMARY, to->q_flags) && + !bitset(MCIF_DSN, mci->mci_flags)) + { + to->q_flags |= QRELAYED; + fprintf(e->e_xfp, "%s... relayed; expect no further notifications\n", + to->q_paddr); + } + } + + /* + ** Restore state and return. + */ + +#if XDEBUG + { + char wbuf[MAXLINE]; + + /* make absolutely certain 0, 1, and 2 are in use */ + sprintf(wbuf, "%s... end of deliver(%s)", + e->e_to == NULL ? "NO-TO-LIST" + : shortenstring(e->e_to, 203), + m->m_name); + checkfd012(wbuf); + } +#endif + + errno = 0; + define('g', (char *) NULL, e); + return (rcode); +} +/* +** MARKFAILURE -- mark a failure on a specific address. +** +** Parameters: +** e -- the envelope we are sending. +** q -- the address to mark. +** mci -- mailer connection information. +** rcode -- the code signifying the particular failure. +** +** Returns: +** none. +** +** Side Effects: +** marks the address (and possibly the envelope) with the +** failure so that an error will be returned or +** the message will be queued, as appropriate. +*/ + +void +markfailure(e, q, mci, rcode) + register ENVELOPE *e; + register ADDRESS *q; + register MCI *mci; + int rcode; +{ + char *stat = NULL; + + switch (rcode) + { + case EX_OK: + break; + + case EX_TEMPFAIL: + case EX_IOERR: + case EX_OSERR: + q->q_flags |= QQUEUEUP; + break; + + default: + q->q_flags |= QBADADDR; + break; + } + + /* find most specific error code possible */ + if (q->q_status == NULL && mci != NULL) + q->q_status = mci->mci_status; + if (q->q_status == NULL) + q->q_status = e->e_status; + if (q->q_status == NULL) + { + switch (rcode) + { + case EX_USAGE: + stat = "5.5.4"; + break; + + case EX_DATAERR: + stat = "5.5.2"; + break; + + case EX_NOUSER: + stat = "5.1.1"; + break; + + case EX_NOHOST: + stat = "5.1.2"; + break; + + case EX_NOINPUT: + case EX_CANTCREAT: + case EX_NOPERM: + stat = "5.3.0"; + break; + + case EX_UNAVAILABLE: + case EX_SOFTWARE: + case EX_OSFILE: + case EX_PROTOCOL: + case EX_CONFIG: + stat = "5.5.0"; + break; + + case EX_OSERR: + case EX_IOERR: + stat = "4.5.0"; + break; + + case EX_TEMPFAIL: + stat = "4.2.0"; + break; + } + if (stat != NULL) + q->q_status = stat; + } + + q->q_statdate = curtime(); + if (CurHostName != NULL && CurHostName[0] != '\0') + q->q_statmta = newstr(CurHostName); + if (rcode != EX_OK && q->q_rstatus == NULL && + q->q_mailer != NULL && q->q_mailer->m_diagtype != NULL && + strcasecmp(q->q_mailer->m_diagtype, "UNIX") == 0) + { + char buf[30]; + + (void) sprintf(buf, "%d", rcode); + q->q_rstatus = newstr(buf); + } +} +/* +** ENDMAILER -- Wait for mailer to terminate. +** +** We should never get fatal errors (e.g., segmentation +** violation), so we report those specially. For other +** errors, we choose a status message (into statmsg), +** and if it represents an error, we print it. +** +** Parameters: +** pid -- pid of mailer. +** e -- the current envelope. +** pv -- the parameter vector that invoked the mailer +** (for error messages). +** +** Returns: +** exit code of mailer. +** +** Side Effects: +** none. +*/ + +int +endmailer(mci, e, pv) + register MCI *mci; + register ENVELOPE *e; + char **pv; +{ + int st; + + /* close any connections */ + if (mci->mci_in != NULL) + (void) xfclose(mci->mci_in, mci->mci_mailer->m_name, "mci_in"); + if (mci->mci_out != NULL) + (void) xfclose(mci->mci_out, mci->mci_mailer->m_name, "mci_out"); + mci->mci_in = mci->mci_out = NULL; + mci->mci_state = MCIS_CLOSED; + + /* in the IPC case there is nothing to wait for */ + if (mci->mci_pid == 0) + return (EX_OK); + + /* wait for the mailer process to die and collect status */ + st = waitfor(mci->mci_pid); + if (st == -1) + { + syserr("endmailer %s: wait", pv[0]); + return (EX_SOFTWARE); + } + + if (WIFEXITED(st)) + { + /* normal death -- return status */ + return (WEXITSTATUS(st)); + } + + /* it died a horrid death */ + syserr("451 mailer %s died with signal %o", + mci->mci_mailer->m_name, st); + + /* log the arguments */ + if (pv != NULL && e->e_xfp != NULL) + { + register char **av; + + fprintf(e->e_xfp, "Arguments:"); + for (av = pv; *av != NULL; av++) + fprintf(e->e_xfp, " %s", *av); + fprintf(e->e_xfp, "\n"); + } + + ExitStat = EX_TEMPFAIL; + return (EX_TEMPFAIL); +} +/* +** GIVERESPONSE -- Interpret an error response from a mailer +** +** Parameters: +** stat -- the status code from the mailer (high byte +** only; core dumps must have been taken care of +** already). +** m -- the mailer info for this mailer. +** mci -- the mailer connection info -- can be NULL if the +** response is given before the connection is made. +** ctladdr -- the controlling address for the recipient +** address(es). +** xstart -- the transaction start time, for computing +** transaction delays. +** e -- the current envelope. +** +** Returns: +** none. +** +** Side Effects: +** Errors may be incremented. +** ExitStat may be set. +*/ + +void +giveresponse(stat, m, mci, ctladdr, xstart, e) + int stat; + register MAILER *m; + register MCI *mci; + ADDRESS *ctladdr; + time_t xstart; + ENVELOPE *e; +{ + register const char *statmsg; + extern char *SysExMsg[]; + register int i; + extern int N_SysEx; + char buf[MAXLINE]; + + /* + ** Compute status message from code. + */ + + i = stat - EX__BASE; + if (stat == 0) + { + statmsg = "250 Sent"; + if (e->e_statmsg != NULL) + { + (void) sprintf(buf, "%s (%s)", + statmsg, shortenstring(e->e_statmsg, 403)); + statmsg = buf; + } + } + else if (i < 0 || i > N_SysEx) + { + (void) sprintf(buf, "554 unknown mailer error %d", stat); + stat = EX_UNAVAILABLE; + statmsg = buf; + } + else if (stat == EX_TEMPFAIL) + { + (void) strcpy(buf, SysExMsg[i] + 1); +#if NAMED_BIND + if (h_errno == TRY_AGAIN) + statmsg = errstring(h_errno+E_DNSBASE); + else +#endif + { + if (errno != 0) + statmsg = errstring(errno); + else + { +#ifdef SMTP + statmsg = SmtpError; +#else /* SMTP */ + statmsg = NULL; +#endif /* SMTP */ + } + } + if (statmsg != NULL && statmsg[0] != '\0') + { + (void) strcat(buf, ": "); + (void) strcat(buf, statmsg); + } + statmsg = buf; + } +#if NAMED_BIND + else if (stat == EX_NOHOST && h_errno != 0) + { + statmsg = errstring(h_errno + E_DNSBASE); + (void) sprintf(buf, "%s (%s)", SysExMsg[i] + 1, statmsg); + statmsg = buf; + } +#endif + else + { + statmsg = SysExMsg[i]; + if (*statmsg++ == ':') + { + (void) sprintf(buf, "%s: %s", statmsg, errstring(errno)); + statmsg = buf; + } + } + + /* + ** Print the message as appropriate + */ + + if (stat == EX_OK || stat == EX_TEMPFAIL) + { + extern char MsgBuf[]; + + message("%s", &statmsg[4]); + if (stat == EX_TEMPFAIL && e->e_xfp != NULL) + fprintf(e->e_xfp, "%s\n", &MsgBuf[4]); + } + else + { + char mbuf[8]; + + Errors++; + sprintf(mbuf, "%.3s %%s", statmsg); + usrerr(mbuf, &statmsg[4]); + } + + /* + ** Final cleanup. + ** Log a record of the transaction. Compute the new + ** ExitStat -- if we already had an error, stick with + ** that. + */ + + if (LogLevel > ((stat == EX_TEMPFAIL) ? 8 : (stat == EX_OK) ? 7 : 6)) + logdelivery(m, mci, &statmsg[4], ctladdr, xstart, e); + + if (tTd(11, 2)) + printf("giveresponse: stat=%d, e->e_message=%s\n", + stat, e->e_message == NULL ? "<NULL>" : e->e_message); + + if (stat != EX_TEMPFAIL) + setstat(stat); + if (stat != EX_OK && (stat != EX_TEMPFAIL || e->e_message == NULL)) + { + if (e->e_message != NULL) + free(e->e_message); + e->e_message = newstr(&statmsg[4]); + } + errno = 0; +#if NAMED_BIND + h_errno = 0; +#endif +} +/* +** LOGDELIVERY -- log the delivery in the system log +** +** Care is taken to avoid logging lines that are too long, because +** some versions of syslog have an unfortunate proclivity for core +** dumping. This is a hack, to be sure, that is at best empirical. +** +** Parameters: +** m -- the mailer info. Can be NULL for initial queue. +** mci -- the mailer connection info -- can be NULL if the +** log is occuring when no connection is active. +** stat -- the message to print for the status. +** ctladdr -- the controlling address for the to list. +** xstart -- the transaction start time, used for +** computing transaction delay. +** e -- the current envelope. +** +** Returns: +** none +** +** Side Effects: +** none +*/ + +#define SPACELEFT(bp) (sizeof buf - ((bp) - buf)) + +void +logdelivery(m, mci, stat, ctladdr, xstart, e) + MAILER *m; + register MCI *mci; + const char *stat; + ADDRESS *ctladdr; + time_t xstart; + register ENVELOPE *e; +{ +# ifdef LOG + register char *bp; + register char *p; + int l; + char buf[1024]; + +# if (SYSLOG_BUFSIZE) >= 256 + /* ctladdr: max 106 bytes */ + bp = buf; + if (ctladdr != NULL) + { + strcpy(bp, ", ctladdr="); + strcat(bp, shortenstring(ctladdr->q_paddr, 83)); + bp += strlen(bp); + if (bitset(QGOODUID, ctladdr->q_flags)) + { + (void) snprintf(bp, SPACELEFT(bp), " (%d/%d)", + ctladdr->q_uid, ctladdr->q_gid); + bp += strlen(bp); + } + } + + /* delay & xdelay: max 41 bytes */ + snprintf(bp, SPACELEFT(bp), ", delay=%s", + pintvl(curtime() - e->e_ctime, TRUE)); + bp += strlen(bp); + + if (xstart != (time_t) 0) + { + snprintf(bp, SPACELEFT(bp), ", xdelay=%s", + pintvl(curtime() - xstart, TRUE)); + bp += strlen(bp); + } + + /* mailer: assume about 19 bytes (max 10 byte mailer name) */ + if (m != NULL) + { + snprintf(bp, SPACELEFT(bp), ", mailer=%s", m->m_name); + bp += strlen(bp); + } + + /* relay: max 66 bytes for IPv4 addresses */ + if (mci != NULL && mci->mci_host != NULL) + { +# ifdef DAEMON + extern SOCKADDR CurHostAddr; +# endif + + snprintf(bp, SPACELEFT(bp), ", relay=%s", + shortenstring(mci->mci_host, 40)); + bp += strlen(bp); + +# ifdef DAEMON + if (CurHostAddr.sa.sa_family != 0) + { + snprintf(bp, SPACELEFT(bp), " [%s]", + anynet_ntoa(&CurHostAddr)); + } +# endif + } + else if (strcmp(stat, "queued") != 0) + { + char *p = macvalue('h', e); + + if (p != NULL && p[0] != '\0') + { + snprintf(bp, SPACELEFT(bp), ", relay=%s", + shortenstring(p, 40)); + } + } + bp += strlen(bp); + +#define STATLEN (((SYSLOG_BUFSIZE) - 100) / 4) +#if (STATLEN) < 63 +# undef STATLEN +# define STATLEN 63 +#endif +#if (STATLEN) > 203 +# undef STATLEN +# define STATLEN 203 +#endif + + /* stat: max 210 bytes */ + if ((bp - buf) > (sizeof buf - ((STATLEN) + 20))) + { + /* desperation move -- truncate data */ + bp = buf + sizeof buf - ((STATLEN) + 17); + strcpy(bp, "..."); + bp += 3; + } + + (void) strcpy(bp, ", stat="); + bp += strlen(bp); + + (void) strcpy(bp, shortenstring(stat, (STATLEN))); + + /* id, to: max 13 + TOBUFSIZE bytes */ + l = SYSLOG_BUFSIZE - 100 - strlen(buf); + p = e->e_to; + while (strlen(p) >= (SIZE_T) l) + { + register char *q = strchr(p + l, ','); + + if (q == NULL) + break; + syslog(LOG_INFO, "%s: to=%.*s [more]%s", + e->e_id, ++q - p, p, buf); + p = q; + } + syslog(LOG_INFO, "%s: to=%s%s", e->e_id, p, buf); + +# else /* we have a very short log buffer size */ + + l = SYSLOG_BUFSIZE - 85; + p = e->e_to; + while (strlen(p) >= l) + { + register char *q = strchr(p + l, ','); + + if (q == NULL) + break; + syslog(LOG_INFO, "%s: to=%.*s [more]", + e->e_id, ++q - p, p); + p = q; + } + syslog(LOG_INFO, "%s: to=%s", e->e_id, p); + + if (ctladdr != NULL) + { + bp = buf; + strcpy(buf, "ctladdr="); + bp += strlen(buf); + strcpy(bp, shortenstring(ctladdr->q_paddr, 83)); + bp += strlen(buf); + if (bitset(QGOODUID, ctladdr->q_flags)) + { + (void) sprintf(bp, " (%d/%d)", + ctladdr->q_uid, ctladdr->q_gid); + bp += strlen(bp); + } + syslog(LOG_INFO, "%s: %s", e->e_id, buf); + } + bp = buf; + sprintf(bp, "delay=%s", pintvl(curtime() - e->e_ctime, TRUE)); + bp += strlen(bp); + if (xstart != (time_t) 0) + { + sprintf(bp, ", xdelay=%s", pintvl(curtime() - xstart, TRUE)); + bp += strlen(bp); + } + + if (m != NULL) + { + sprintf(bp, ", mailer=%s", m->m_name); + bp += strlen(bp); + } + syslog(LOG_INFO, "%s: %.1000s", e->e_id, buf); + + buf[0] = '\0'; + if (mci != NULL && mci->mci_host != NULL) + { +# ifdef DAEMON + extern SOCKADDR CurHostAddr; +# endif + + sprintf(buf, "relay=%.100s", mci->mci_host); + +# ifdef DAEMON + if (CurHostAddr.sa.sa_family != 0) + sprintf(bp, " [%.100s]", anynet_ntoa(&CurHostAddr)); +# endif + } + else if (strcmp(stat, "queued") != 0) + { + char *p = macvalue('h', e); + + if (p != NULL && p[0] != '\0') + sprintf(buf, "relay=%.100s", p); + } + if (buf[0] != '\0') + syslog(LOG_INFO, "%s: %.1000s", e->e_id, buf); + + syslog(LOG_INFO, "%s: stat=%s", e->e_id, shortenstring(stat, 63)); +# endif /* short log buffer */ +# endif /* LOG */ +} + +#undef SPACELEFT +/* +** PUTFROMLINE -- output a UNIX-style from line (or whatever) +** +** This can be made an arbitrary message separator by changing $l +** +** One of the ugliest hacks seen by human eyes is contained herein: +** UUCP wants those stupid "remote from <host>" lines. Why oh why +** does a well-meaning programmer such as myself have to deal with +** this kind of antique garbage???? +** +** Parameters: +** mci -- the connection information. +** e -- the envelope. +** +** Returns: +** none +** +** Side Effects: +** outputs some text to fp. +*/ + +void +putfromline(mci, e) + register MCI *mci; + ENVELOPE *e; +{ + char *template = UnixFromLine; + char buf[MAXLINE]; + + if (bitnset(M_NHDR, mci->mci_mailer->m_flags)) + return; + + if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags)) + { + char *bang; + char xbuf[MAXLINE]; + + expand("\201g", buf, sizeof buf, e); + bang = strchr(buf, '!'); + if (bang == NULL) + { + errno = 0; + syserr("554 No ! in UUCP From address! (%s given)", buf); + } + else + { + *bang++ = '\0'; + (void) sprintf(xbuf, "From %.800s \201d remote from %.100s\n", + bang, buf); + template = xbuf; + } + } + expand(template, buf, sizeof buf, e); + putxline(buf, mci, PXLF_NOTHINGSPECIAL); +} +/* +** PUTBODY -- put the body of a message. +** +** Parameters: +** mci -- the connection information. +** e -- the envelope to put out. +** separator -- if non-NULL, a message separator that must +** not be permitted in the resulting message. +** +** Returns: +** none. +** +** Side Effects: +** The message is written onto fp. +*/ + +/* values for output state variable */ +#define OS_HEAD 0 /* at beginning of line */ +#define OS_CR 1 /* read a carriage return */ +#define OS_INLINE 2 /* putting rest of line */ + +void +putbody(mci, e, separator) + register MCI *mci; + register ENVELOPE *e; + char *separator; +{ + char buf[MAXLINE]; + + /* + ** Output the body of the message + */ + + if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags)) + { + char *df = queuename(e, 'd'); + + e->e_dfp = fopen(df, "r"); + if (e->e_dfp == NULL) + syserr("putbody: Cannot open %s for %s from %s", + df, e->e_to, e->e_from.q_paddr); + } + if (e->e_dfp == NULL) + { + if (bitset(MCIF_INHEADER, mci->mci_flags)) + { + putline("", mci); + mci->mci_flags &= ~MCIF_INHEADER; + } + putline("<<< No Message Collected >>>", mci); + goto endofmessage; + } + if (e->e_dfino == (ino_t) 0) + { + struct stat stbuf; + + if (fstat(fileno(e->e_dfp), &stbuf) < 0) + e->e_dfino = -1; + else + { + e->e_dfdev = stbuf.st_dev; + e->e_dfino = stbuf.st_ino; + } + } + rewind(e->e_dfp); + +#if MIME8TO7 + if (bitset(MCIF_CVT8TO7, mci->mci_flags)) + { + char *boundaries[MAXMIMENESTING + 1]; + + /* + ** Do 8 to 7 bit MIME conversion. + */ + + /* make sure it looks like a MIME message */ + if (hvalue("MIME-Version", e->e_header) == NULL) + putline("MIME-Version: 1.0", mci); + + if (hvalue("Content-Type", e->e_header) == NULL) + { + sprintf(buf, "Content-Type: text/plain; charset=%s", + defcharset(e)); + putline(buf, mci); + } + + /* now do the hard work */ + boundaries[0] = NULL; + mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER); + } + else +#endif + { + int ostate; + register char *bp; + register char *pbp; + register int c; + int padc; + char *buflim; + int pos = 0; + char peekbuf[10]; + + /* we can pass it through unmodified */ + if (bitset(MCIF_INHEADER, mci->mci_flags)) + { + putline("", mci); + mci->mci_flags &= ~MCIF_INHEADER; + } + + /* determine end of buffer; allow for short mailer lines */ + buflim = &buf[sizeof buf - 1]; + if (mci->mci_mailer->m_linelimit > 0 && + mci->mci_mailer->m_linelimit < sizeof buf - 1) + buflim = &buf[mci->mci_mailer->m_linelimit - 1]; + + /* copy temp file to output with mapping */ + ostate = OS_HEAD; + bp = buf; + pbp = peekbuf; + while (!ferror(mci->mci_out)) + { + register char *xp; + + if (pbp > peekbuf) + c = *--pbp; + else if ((c = getc(e->e_dfp)) == EOF) + break; + if (bitset(MCIF_7BIT, mci->mci_flags)) + c &= 0x7f; + switch (ostate) + { + case OS_HEAD: + if (c != '\r' && c != '\n' && bp < buflim) + { + *bp++ = c; + break; + } + + /* check beginning of line for special cases */ + *bp = '\0'; + pos = 0; + padc = EOF; + if (buf[0] == 'F' && + bitnset(M_ESCFROM, mci->mci_mailer->m_flags) && + strncmp(buf, "From ", 5) == 0) + { + padc = '>'; + } + if (buf[0] == '-' && buf[1] == '-' && + separator != NULL) + { + /* possible separator */ + int sl = strlen(separator); + + if (strncmp(&buf[2], separator, sl) == 0) + padc = ' '; + } + if (buf[0] == '.' && + bitnset(M_XDOT, mci->mci_mailer->m_flags)) + { + padc = '.'; + } + + /* now copy out saved line */ + if (TrafficLogFile != NULL) + { + fprintf(TrafficLogFile, "%05d >>> ", getpid()); + if (padc != EOF) + putc(padc, TrafficLogFile); + for (xp = buf; xp < bp; xp++) + putc(*xp, TrafficLogFile); + if (c == '\n') + fputs(mci->mci_mailer->m_eol, + TrafficLogFile); + } + if (padc != EOF) + { + putc(padc, mci->mci_out); + pos++; + } + for (xp = buf; xp < bp; xp++) + putc(*xp, mci->mci_out); + if (c == '\n') + { + fputs(mci->mci_mailer->m_eol, + mci->mci_out); + pos = 0; + } + else + { + pos += bp - buf; + if (c != '\r') + *pbp++ = c; + } + bp = buf; + + /* determine next state */ + if (c == '\n') + ostate = OS_HEAD; + else if (c == '\r') + ostate = OS_CR; + else + ostate = OS_INLINE; + continue; + + case OS_CR: + if (c == '\n') + { + /* got CRLF */ + fputs(mci->mci_mailer->m_eol, mci->mci_out); + if (TrafficLogFile != NULL) + { + fputs(mci->mci_mailer->m_eol, + TrafficLogFile); + } + ostate = OS_HEAD; + continue; + } + + /* had a naked carriage return */ + *pbp++ = c; + c = '\r'; + goto putch; + + case OS_INLINE: + if (c == '\r') + { + ostate = OS_CR; + continue; + } +putch: + if (mci->mci_mailer->m_linelimit > 0 && + pos > mci->mci_mailer->m_linelimit && + c != '\n') + { + putc('!', mci->mci_out); + fputs(mci->mci_mailer->m_eol, mci->mci_out); + if (TrafficLogFile != NULL) + { + fprintf(TrafficLogFile, "!%s", + mci->mci_mailer->m_eol); + } + ostate = OS_HEAD; + *pbp++ = c; + continue; + } + if (TrafficLogFile != NULL) + putc(c, TrafficLogFile); + putc(c, mci->mci_out); + pos++; + ostate = c == '\n' ? OS_HEAD : OS_INLINE; + break; + } + } + + /* make sure we are at the beginning of a line */ + if (bp > buf) + { + *bp = '\0'; + fputs(buf, mci->mci_out); + fputs(mci->mci_mailer->m_eol, mci->mci_out); + } + } + + if (ferror(e->e_dfp)) + { + syserr("putbody: df%s: read error", e->e_id); + ExitStat = EX_IOERR; + } + +endofmessage: + /* some mailers want extra blank line at end of message */ + if (bitnset(M_BLANKEND, mci->mci_mailer->m_flags) && + buf[0] != '\0' && buf[0] != '\n') + putline("", mci); + + (void) fflush(mci->mci_out); + if (ferror(mci->mci_out) && errno != EPIPE) + { + syserr("putbody: write error"); + ExitStat = EX_IOERR; + } + errno = 0; +} +/* +** MAILFILE -- Send a message to a file. +** +** If the file has the setuid/setgid bits set, but NO execute +** bits, sendmail will try to become the owner of that file +** rather than the real user. Obviously, this only works if +** sendmail runs as root. +** +** This could be done as a subordinate mailer, except that it +** is used implicitly to save messages in ~/dead.letter. We +** view this as being sufficiently important as to include it +** here. For example, if the system is dying, we shouldn't have +** to create another process plus some pipes to save the message. +** +** Parameters: +** filename -- the name of the file to send to. +** ctladdr -- the controlling address header -- includes +** the userid/groupid to be when sending. +** sfflags -- flags for opening. +** e -- the current envelope. +** +** Returns: +** The exit code associated with the operation. +** +** Side Effects: +** none. +*/ + +int +mailfile(filename, ctladdr, sfflags, e) + char *filename; + ADDRESS *ctladdr; + int sfflags; + register ENVELOPE *e; +{ + register FILE *f; + register int pid = -1; + int mode; + + if (tTd(11, 1)) + { + printf("mailfile %s\n ctladdr=", filename); + printaddr(ctladdr, FALSE); + } + + if (e->e_xfp != NULL) + fflush(e->e_xfp); + + /* + ** Fork so we can change permissions here. + ** Note that we MUST use fork, not vfork, because of + ** the complications of calling subroutines, etc. + */ + + DOFORK(fork); + + if (pid < 0) + return (EX_OSERR); + else if (pid == 0) + { + /* child -- actually write to file */ + struct stat stb; + struct stat fsb; + MCI mcibuf; + int oflags = O_WRONLY|O_APPEND; + + if (e->e_lockfp != NULL) + (void) close(fileno(e->e_lockfp)); + + (void) setsignal(SIGINT, SIG_DFL); + (void) setsignal(SIGHUP, SIG_DFL); + (void) setsignal(SIGTERM, SIG_DFL); + (void) umask(OldUmask); + e->e_to = filename; + ExitStat = EX_OK; + +#ifdef HASLSTAT + if ((SafeFileEnv != NULL ? lstat(filename, &stb) + : stat(filename, &stb)) < 0) +#else + if (stat(filename, &stb) < 0) +#endif + { + stb.st_mode = FileMode; + oflags |= O_CREAT|O_EXCL; + } + else if (bitset(0111, stb.st_mode) || stb.st_nlink != 1 || + (SafeFileEnv != NULL && !S_ISREG(stb.st_mode))) + exit(EX_CANTCREAT); + mode = stb.st_mode; + + /* limit the errors to those actually caused in the child */ + errno = 0; + ExitStat = EX_OK; + + if (ctladdr != NULL || bitset(SFF_RUNASREALUID, sfflags)) + { + /* ignore setuid and setgid bits */ + mode &= ~(S_ISGID|S_ISUID); + } + + /* we have to open the dfile BEFORE setuid */ + if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags)) + { + char *df = queuename(e, 'd'); + + e->e_dfp = fopen(df, "r"); + if (e->e_dfp == NULL) + { + syserr("mailfile: Cannot open %s for %s from %s", + df, e->e_to, e->e_from.q_paddr); + } + } + + /* select a new user to run as */ + if (!bitset(SFF_RUNASREALUID, sfflags)) + { + if (bitset(S_ISUID, mode)) + { + RealUserName = NULL; + RealUid = stb.st_uid; + } + else if (ctladdr != NULL && ctladdr->q_uid != 0) + { + if (ctladdr->q_ruser != NULL) + RealUserName = ctladdr->q_ruser; + else + RealUserName = ctladdr->q_user; + RealUid = ctladdr->q_uid; + } + else if (FileMailer != NULL && FileMailer->m_uid != 0) + { + RealUserName = DefUser; + RealUid = FileMailer->m_uid; + } + else + { + RealUserName = DefUser; + RealUid = DefUid; + } + + /* select a new group to run as */ + if (bitset(S_ISGID, mode)) + RealGid = stb.st_gid; + else if (ctladdr != NULL && ctladdr->q_uid != 0) + RealGid = ctladdr->q_gid; + else if (FileMailer != NULL && FileMailer->m_gid != 0) + RealGid = FileMailer->m_gid; + else + RealGid = DefGid; + } + + /* last ditch */ + if (!bitset(SFF_ROOTOK, sfflags)) + { + if (RealUid == 0) + RealUid = DefUid; + if (RealGid == 0) + RealGid = DefGid; + } + + /* now set the group and user ids */ + endpwent(); + if (RealUserName != NULL && !DontInitGroups) + (void) initgroups(RealUserName, RealGid); + (void) setgid(RealGid); + (void) setuid(RealUid); + + /* if you have a safe environment, go into it */ + if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0') + { + int i; + + if (chroot(SafeFileEnv) < 0) + { + syserr("mailfile: Cannot chroot(%s)", + SafeFileEnv); + exit(EX_CANTCREAT); + } + i = strlen(SafeFileEnv); + if (strncmp(SafeFileEnv, filename, i) == 0) + filename += i; + } + if (chdir("/") < 0) + syserr("mailfile: cannot chdir(/)"); + + sfflags |= SFF_NOPATHCHECK; + sfflags &= ~SFF_OPENASROOT; + f = safefopen(filename, oflags, FileMode, sfflags); + if (f == NULL) + { + message("554 cannot open: %s", errstring(errno)); + exit(EX_CANTCREAT); + } + if (fstat(fileno(f), &stb) < 0) + { + message("554 cannot fstat %s", errstring(errno)); + exit(EX_CANTCREAT); + } + + bzero(&mcibuf, sizeof mcibuf); + mcibuf.mci_mailer = FileMailer; + mcibuf.mci_out = f; + if (bitnset(M_7BITS, FileMailer->m_flags)) + mcibuf.mci_flags |= MCIF_7BIT; + + putfromline(&mcibuf, e); + (*e->e_puthdr)(&mcibuf, e->e_header, e); + (*e->e_putbody)(&mcibuf, e, NULL); + putline("\n", &mcibuf); + if (fflush(f) < 0 || ferror(f)) + { + message("451 I/O error: %s", errstring(errno)); + setstat(EX_IOERR); + } + + /* reset ISUID & ISGID bits for paranoid systems */ +#if HASFCHMOD + (void) fchmod(fileno(f), (int) stb.st_mode); +#else + (void) chmod(filename, (int) stb.st_mode); +#endif + (void) xfclose(f, "mailfile", filename); + (void) fflush(stdout); + exit(ExitStat); + /*NOTREACHED*/ + } + else + { + /* parent -- wait for exit status */ + int st; + + st = waitfor(pid); + if (WIFEXITED(st)) + return (WEXITSTATUS(st)); + else + { + syserr("child died on signal %d", st); + return (EX_UNAVAILABLE); + } + /*NOTREACHED*/ + } +} +/* +** HOSTSIGNATURE -- return the "signature" for a host. +** +** The signature describes how we are going to send this -- it +** can be just the hostname (for non-Internet hosts) or can be +** an ordered list of MX hosts. +** +** Parameters: +** m -- the mailer describing this host. +** host -- the host name. +** e -- the current envelope. +** +** Returns: +** The signature for this host. +** +** Side Effects: +** Can tweak the symbol table. +*/ + +char * +hostsignature(m, host, e) + register MAILER *m; + char *host; + ENVELOPE *e; +{ + register char *p; + register STAB *s; + int i; + int len; +#if NAMED_BIND + int nmx; + auto int rcode; + char *hp; + char *endp; + int oldoptions = _res.options; + char *mxhosts[MAXMXHOSTS + 1]; +#endif + + /* + ** Check to see if this uses IPC -- if not, it can't have MX records. + */ + + p = m->m_mailer; + if (strcmp(p, "[IPC]") != 0 && strcmp(p, "[TCP]") != 0) + { + /* just an ordinary mailer */ + return host; + } + + /* + ** Look it up in the symbol table. + */ + + s = stab(host, ST_HOSTSIG, ST_ENTER); + if (s->s_hostsig != NULL) + return s->s_hostsig; + + /* + ** Not already there -- create a signature. + */ + +#if NAMED_BIND + if (ConfigLevel < 2) + _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */ + + for (hp = host; hp != NULL; hp = endp) + { + endp = strchr(hp, ':'); + if (endp != NULL) + *endp = '\0'; + + nmx = getmxrr(hp, mxhosts, TRUE, &rcode); + + if (nmx <= 0) + { + register MCI *mci; + + /* update the connection info for this host */ + mci = mci_get(hp, m); + mci->mci_lastuse = curtime(); + mci->mci_exitstat = rcode; + mci->mci_errno = errno; + mci->mci_herrno = h_errno; + + /* and return the original host name as the signature */ + nmx = 1; + mxhosts[0] = hp; + } + + len = 0; + for (i = 0; i < nmx; i++) + { + len += strlen(mxhosts[i]) + 1; + } + if (s->s_hostsig != NULL) + len += strlen(s->s_hostsig) + 1; + p = xalloc(len); + if (s->s_hostsig != NULL) + { + (void) strcpy(p, s->s_hostsig); + free(s->s_hostsig); + s->s_hostsig = p; + p += strlen(p); + *p++ = ':'; + } + else + s->s_hostsig = p; + for (i = 0; i < nmx; i++) + { + if (i != 0) + *p++ = ':'; + strcpy(p, mxhosts[i]); + p += strlen(p); + } + if (endp != NULL) + *endp++ = ':'; + } + makelower(s->s_hostsig); + if (ConfigLevel < 2) + _res.options = oldoptions; +#else + /* not using BIND -- the signature is just the host name */ + s->s_hostsig = host; +#endif + if (tTd(17, 1)) + printf("hostsignature(%s) = %s\n", host, s->s_hostsig); + return s->s_hostsig; +} diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c new file mode 100644 index 000000000000..2f94508da1ea --- /dev/null +++ b/usr.sbin/sendmail/src/domain.c @@ -0,0 +1,871 @@ +/* + * Copyright (c) 1986, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sendmail.h" + +#ifndef lint +#if NAMED_BIND +static char sccsid[] = "@(#)domain.c 8.54 (Berkeley) 9/28/95 (with name server)"; +#else +static char sccsid[] = "@(#)domain.c 8.54 (Berkeley) 9/28/95 (without name server)"; +#endif +#endif /* not lint */ + +#if NAMED_BIND + +#include <errno.h> +#include <resolv.h> + +typedef union +{ + HEADER qb1; + u_char qb2[PACKETSZ]; +} querybuf; + +static char MXHostBuf[MAXMXHOSTS*PACKETSZ]; + +#ifndef MAXDNSRCH +#define MAXDNSRCH 6 /* number of possible domains to search */ +#endif + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef NO_DATA +# define NO_DATA NO_ADDRESS +#endif + +#ifndef HFIXEDSZ +# define HFIXEDSZ 12 /* sizeof(HEADER) */ +#endif + +#define MAXCNAMEDEPTH 10 /* maximum depth of CNAME recursion */ + +#if defined(__RES) && (__RES >= 19940415) +# define RES_UNC_T char * +#else +# define RES_UNC_T u_char * +#endif +/* +** GETMXRR -- get MX resource records for a domain +** +** Parameters: +** host -- the name of the host to MX. +** mxhosts -- a pointer to a return buffer of MX records. +** droplocalhost -- If TRUE, all MX records less preferred +** than the local host (as determined by $=w) will +** be discarded. +** rcode -- a pointer to an EX_ status code. +** +** Returns: +** The number of MX records found. +** -1 if there is an internal failure. +** If no MX records are found, mxhosts[0] is set to host +** and 1 is returned. +*/ + +int +getmxrr(host, mxhosts, droplocalhost, rcode) + char *host; + char **mxhosts; + bool droplocalhost; + int *rcode; +{ + register u_char *eom, *cp; + register int i, j, n; + int nmx = 0; + register char *bp; + HEADER *hp; + querybuf answer; + int ancount, qdcount, buflen; + bool seenlocal = FALSE; + u_short pref, type; + u_short localpref = 256; + char *fallbackMX = FallBackMX; + static bool firsttime = TRUE; + bool trycanon = FALSE; + int (*resfunc)(); + extern int res_query(), res_search(); + u_short prefer[MAXMXHOSTS]; + int weight[MAXMXHOSTS]; + extern bool getcanonname(); + + if (tTd(8, 2)) + printf("getmxrr(%s, droplocalhost=%d)\n", host, droplocalhost); + + if (fallbackMX != NULL) + { + if (firsttime && + res_query(FallBackMX, C_IN, T_A, + (u_char *) &answer, sizeof answer) < 0) + { + /* this entry is bogus */ + fallbackMX = FallBackMX = NULL; + } + else if (droplocalhost && wordinclass(fallbackMX, 'w')) + { + /* don't use fallback for this pass */ + fallbackMX = NULL; + } + firsttime = FALSE; + } + + *rcode = EX_OK; + + /* efficiency hack -- numeric or non-MX lookups */ + if (host[0] == '[') + goto punt; + + /* + ** If we don't have MX records in our host switch, don't + ** try for MX records. Note that this really isn't "right", + ** since we might be set up to try NIS first and then DNS; + ** if the host is found in NIS we really shouldn't be doing + ** MX lookups. However, that should be a degenerate case. + */ + + if (!UseNameServer) + goto punt; + if (HasWildcardMX && ConfigLevel >= 6) + resfunc = res_query; + else + resfunc = res_search; + + errno = 0; + n = (*resfunc)(host, C_IN, T_MX, (u_char *) &answer, sizeof(answer)); + if (n < 0) + { + if (tTd(8, 1)) + printf("getmxrr: res_search(%s) failed (errno=%d, h_errno=%d)\n", + (host == NULL) ? "<NULL>" : host, errno, h_errno); + switch (h_errno) + { + case NO_DATA: + trycanon = TRUE; + /* fall through */ + + case NO_RECOVERY: + /* no MX data on this host */ + goto punt; + + case HOST_NOT_FOUND: +#if BROKEN_RES_SEARCH + case 0: /* Ultrix resolver retns failure w/ h_errno=0 */ +#endif + /* host doesn't exist in DNS; might be in /etc/hosts */ + trycanon = TRUE; + *rcode = EX_NOHOST; + goto punt; + + case TRY_AGAIN: + /* couldn't connect to the name server */ + if (fallbackMX != NULL) + { + /* name server is hosed -- push to fallback */ + mxhosts[nmx++] = fallbackMX; + return nmx; + } + /* it might come up later; better queue it up */ + *rcode = EX_TEMPFAIL; + break; + + default: + syserr("getmxrr: res_search (%s) failed with impossible h_errno (%d)\n", + host, h_errno); + *rcode = EX_OSERR; + break; + } + + /* irreconcilable differences */ + return (-1); + } + + /* find first satisfactory answer */ + hp = (HEADER *)&answer; + cp = (u_char *)&answer + HFIXEDSZ; + eom = (u_char *)&answer + n; + for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ) + if ((n = dn_skipname(cp, eom)) < 0) + goto punt; + buflen = sizeof(MXHostBuf) - 1; + bp = MXHostBuf; + ancount = ntohs(hp->ancount); + while (--ancount >= 0 && cp < eom && nmx < MAXMXHOSTS - 1) + { + if ((n = dn_expand((u_char *)&answer, + eom, cp, (RES_UNC_T) bp, buflen)) < 0) + break; + cp += n; + GETSHORT(type, cp); + cp += INT16SZ + INT32SZ; + GETSHORT(n, cp); + if (type != T_MX) + { + if (tTd(8, 8) || _res.options & RES_DEBUG) + printf("unexpected answer type %d, size %d\n", + type, n); + cp += n; + continue; + } + GETSHORT(pref, cp); + if ((n = dn_expand((u_char *)&answer, eom, cp, + (RES_UNC_T) bp, buflen)) < 0) + break; + cp += n; + if (wordinclass(bp, 'w')) + { + if (tTd(8, 3)) + printf("found localhost (%s) in MX list, pref=%d\n", + bp, pref); + if (droplocalhost) + { + if (!seenlocal || pref < localpref) + localpref = pref; + seenlocal = TRUE; + continue; + } + weight[nmx] = 0; + } + else + weight[nmx] = mxrand(bp); + prefer[nmx] = pref; + mxhosts[nmx++] = bp; + n = strlen(bp); + bp += n; + if (bp[-1] != '.') + { + *bp++ = '.'; + n++; + } + *bp++ = '\0'; + buflen -= n + 1; + } + + /* sort the records */ + for (i = 0; i < nmx; i++) + { + for (j = i + 1; j < nmx; j++) + { + if (prefer[i] > prefer[j] || + (prefer[i] == prefer[j] && weight[i] > weight[j])) + { + register int temp; + register char *temp1; + + temp = prefer[i]; + prefer[i] = prefer[j]; + prefer[j] = temp; + temp1 = mxhosts[i]; + mxhosts[i] = mxhosts[j]; + mxhosts[j] = temp1; + temp = weight[i]; + weight[i] = weight[j]; + weight[j] = temp; + } + } + if (seenlocal && prefer[i] >= localpref) + { + /* truncate higher preference part of list */ + nmx = i; + } + } + + /* delete duplicates from list (yes, some bozos have duplicates) */ + for (i = 0; i < nmx - 1; ) + { + if (strcasecmp(mxhosts[i], mxhosts[i + 1]) != 0) + i++; + else + { + /* compress out duplicate */ + for (j = i + 1; j < nmx; j++) + mxhosts[j] = mxhosts[j + 1]; + nmx--; + } + } + + if (nmx == 0) + { +punt: + if (seenlocal && + (!TryNullMXList || sm_gethostbyname(host) == NULL)) + { + /* + ** If we have deleted all MX entries, this is + ** an error -- we should NEVER send to a host that + ** has an MX, and this should have been caught + ** earlier in the config file. + ** + ** Some sites prefer to go ahead and try the + ** A record anyway; that case is handled by + ** setting TryNullMXList. I believe this is a + ** bad idea, but it's up to you.... + */ + + *rcode = EX_CONFIG; + syserr("MX list for %s points back to %s", + host, MyHostName); + return -1; + } + strcpy(MXHostBuf, host); + mxhosts[0] = MXHostBuf; + if (host[0] == '[') + { + register char *p; + + /* this may be an MX suppression-style address */ + p = strchr(MXHostBuf, ']'); + if (p != NULL) + { + *p = '\0'; + if (inet_addr(&MXHostBuf[1]) != -1) + *p = ']'; + else + { + trycanon = TRUE; + mxhosts[0]++; + } + } + } + if (trycanon && + getcanonname(mxhosts[0], sizeof MXHostBuf - 2, FALSE)) + { + bp = &MXHostBuf[strlen(MXHostBuf)]; + if (bp[-1] != '.') + { + *bp++ = '.'; + *bp = '\0'; + } + nmx = 1; + } + } + + /* if we have a default lowest preference, include that */ + if (fallbackMX != NULL && !seenlocal) + mxhosts[nmx++] = fallbackMX; + + return (nmx); +} +/* +** MXRAND -- create a randomizer for equal MX preferences +** +** If two MX hosts have equal preferences we want to randomize +** the selection. But in order for signatures to be the same, +** we need to randomize the same way each time. This function +** computes a pseudo-random hash function from the host name. +** +** Parameters: +** host -- the name of the host. +** +** Returns: +** A random but repeatable value based on the host name. +** +** Side Effects: +** none. +*/ + +int +mxrand(host) + register char *host; +{ + int hfunc; + static unsigned int seed; + + if (seed == 0) + { + seed = (int) curtime() & 0xffff; + if (seed == 0) + seed++; + } + + if (tTd(17, 9)) + printf("mxrand(%s)", host); + + hfunc = seed; + while (*host != '\0') + { + int c = *host++; + + if (isascii(c) && isupper(c)) + c = tolower(c); + hfunc = ((hfunc << 1) ^ c) % 2003; + } + + hfunc &= 0xff; + hfunc++; + + if (tTd(17, 9)) + printf(" = %d\n", hfunc); + return hfunc; +} +/* +** BESTMX -- find the best MX for a name +** +** This is really a hack, but I don't see any obvious way +** to generalize it at the moment. +*/ + +char * +bestmx_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + int nmx; + auto int rcode; + int saveopts = _res.options; + char *mxhosts[MAXMXHOSTS + 1]; + + _res.options &= ~(RES_DNSRCH|RES_DEFNAMES); + nmx = getmxrr(name, mxhosts, FALSE, &rcode); + _res.options = saveopts; + if (nmx <= 0) + return NULL; + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, name, strlen(name), NULL); + else + return map_rewrite(map, mxhosts[0], strlen(mxhosts[0]), av); +} +/* +** DNS_GETCANONNAME -- get the canonical name for named host using DNS +** +** This algorithm tries to be smart about wildcard MX records. +** This is hard to do because DNS doesn't tell is if we matched +** against a wildcard or a specific MX. +** +** We always prefer A & CNAME records, since these are presumed +** to be specific. +** +** If we match an MX in one pass and lose it in the next, we use +** the old one. For example, consider an MX matching *.FOO.BAR.COM. +** A hostname bletch.foo.bar.com will match against this MX, but +** will stop matching when we try bletch.bar.com -- so we know +** that bletch.foo.bar.com must have been right. This fails if +** there was also an MX record matching *.BAR.COM, but there are +** some things that just can't be fixed. +** +** Parameters: +** host -- a buffer containing the name of the host. +** This is a value-result parameter. +** hbsize -- the size of the host buffer. +** trymx -- if set, try MX records as well as A and CNAME. +** statp -- pointer to place to store status. +** +** Returns: +** TRUE -- if the host matched. +** FALSE -- otherwise. +*/ + +bool +dns_getcanonname(host, hbsize, trymx, statp) + char *host; + int hbsize; + bool trymx; + int *statp; +{ + register u_char *eom, *ap; + register char *cp; + register int n; + HEADER *hp; + querybuf answer; + int ancount, qdcount; + int ret; + char **domain; + int type; + char **dp; + char *mxmatch; + bool amatch; + bool gotmx = FALSE; + int qtype; + int loopcnt; + char *xp; + char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)]; + char *searchlist[MAXDNSRCH+2]; + extern char *gethostalias(); + + if (tTd(8, 2)) + printf("dns_getcanonname(%s, trymx=%d)\n", host, trymx); + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) + { + *statp = EX_UNAVAILABLE; + return FALSE; + } + + /* + ** Initialize domain search list. If there is at least one + ** dot in the name, search the unmodified name first so we + ** find "vse.CS" in Czechoslovakia instead of in the local + ** domain (e.g., vse.CS.Berkeley.EDU). + ** + ** Older versions of the resolver could create this + ** list by tearing apart the host name. + */ + + loopcnt = 0; +cnameloop: + /* Check for dots in the name */ + for (cp = host, n = 0; *cp != '\0'; cp++) + if (*cp == '.') + n++; + + /* + ** If this is a simple name, determine whether it matches an + ** alias in the file defined by the environment variable HOSTALIASES. + */ + if (n == 0 && (xp = gethostalias(host)) != NULL) + { + if (loopcnt++ > MAXCNAMEDEPTH) + { + syserr("loop in ${HOSTALIASES} file"); + } + else + { + strncpy(host, xp, hbsize); + host[hbsize - 1] = '\0'; + goto cnameloop; + } + } + + /* + ** Build the search list. + ** If there is at least one dot in name, start with a null + ** domain to search the unmodified name first. + ** If name does not end with a dot and search up local domain + ** tree desired, append each local domain component to the + ** search list; if name contains no dots and default domain + ** name is desired, append default domain name to search list; + ** else if name ends in a dot, remove that dot. + */ + + dp = searchlist; + if (n > 0) + *dp++ = ""; + if (n >= 0 && *--cp != '.' && bitset(RES_DNSRCH, _res.options)) + { + for (domain = _res.dnsrch; *domain != NULL; ) + *dp++ = *domain++; + } + else if (n == 0 && bitset(RES_DEFNAMES, _res.options)) + { + *dp++ = _res.defdname; + } + else if (*cp == '.') + { + *cp = '\0'; + } + *dp = NULL; + + /* + ** Now loop through the search list, appending each domain in turn + ** name and searching for a match. + */ + + mxmatch = NULL; + qtype = T_ANY; + + for (dp = searchlist; *dp != NULL; ) + { + if (qtype == T_ANY) + gotmx = FALSE; + if (tTd(8, 5)) + printf("dns_getcanonname: trying %s.%s (%s)\n", + host, *dp, + qtype == T_ANY ? "ANY" : qtype == T_A ? "A" : + qtype == T_MX ? "MX" : "???"); + ret = res_querydomain(host, *dp, C_IN, qtype, + answer.qb2, sizeof(answer.qb2)); + if (ret <= 0) + { + if (tTd(8, 7)) + printf("\tNO: errno=%d, h_errno=%d\n", + errno, h_errno); + + if (errno == ECONNREFUSED || h_errno == TRY_AGAIN) + { + /* the name server seems to be down */ + h_errno = TRY_AGAIN; + *statp = EX_TEMPFAIL; + return FALSE; + } + + if (h_errno != HOST_NOT_FOUND) + { + /* might have another type of interest */ + if (qtype == T_ANY) + { + qtype = T_A; + continue; + } + else if (qtype == T_A && !gotmx && trymx) + { + qtype = T_MX; + continue; + } + } + + /* definite no -- try the next domain */ + dp++; + qtype = T_ANY; + continue; + } + else if (tTd(8, 7)) + printf("\tYES\n"); + + /* + ** Appear to have a match. Confirm it by searching for A or + ** CNAME records. If we don't have a local domain + ** wild card MX record, we will accept MX as well. + */ + + hp = (HEADER *) &answer; + ap = (u_char *) &answer + HFIXEDSZ; + eom = (u_char *) &answer + ret; + + /* skip question part of response -- we know what we asked */ + for (qdcount = ntohs(hp->qdcount); qdcount--; ap += ret + QFIXEDSZ) + { + if ((ret = dn_skipname(ap, eom)) < 0) + { + if (tTd(8, 20)) + printf("qdcount failure (%d)\n", + ntohs(hp->qdcount)); + *statp = EX_SOFTWARE; + return FALSE; /* ???XXX??? */ + } + } + + amatch = FALSE; + for (ancount = ntohs(hp->ancount); --ancount >= 0 && ap < eom; + ap += n) + { + n = dn_expand((u_char *) &answer, eom, ap, + (RES_UNC_T) nbuf, sizeof nbuf); + if (n < 0) + break; + ap += n; + GETSHORT(type, ap); + ap += INT16SZ + INT32SZ; + GETSHORT(n, ap); + switch (type) + { + case T_MX: + gotmx = TRUE; + if (**dp != '\0' && HasWildcardMX) + { + /* + ** If we are using MX matches and have + ** not yet gotten one, save this one + ** but keep searching for an A or + ** CNAME match. + */ + + if (trymx && mxmatch == NULL) + mxmatch = *dp; + continue; + } + + /* + ** If we did not append a domain name, this + ** must have been a canonical name to start + ** with. Even if we did append a domain name, + ** in the absence of a wildcard MX this must + ** still be a real MX match. + ** Such MX matches are as good as an A match, + ** fall through. + */ + + case T_A: + /* Flag that a good match was found */ + amatch = TRUE; + + /* continue in case a CNAME also exists */ + continue; + + case T_CNAME: + if (DontExpandCnames) + { + /* got CNAME -- guaranteed canonical */ + amatch = TRUE; + break; + } + + if (loopcnt++ > MAXCNAMEDEPTH) + { + /*XXX should notify postmaster XXX*/ + message("DNS failure: CNAME loop for %s", + host); + if (CurEnv->e_message == NULL) + { + char ebuf[MAXLINE]; + + sprintf(ebuf, "Deferred: DNS failure: CNAME loop for %.100s", + host); + CurEnv->e_message = newstr(ebuf); + } + h_errno = NO_RECOVERY; + *statp = EX_CONFIG; + return FALSE; + } + + /* value points at name */ + if ((ret = dn_expand((u_char *)&answer, + eom, ap, (RES_UNC_T) nbuf, sizeof(nbuf))) < 0) + break; + (void)strncpy(host, nbuf, hbsize); /* XXX */ + host[hbsize - 1] = '\0'; + + /* + ** RFC 1034 section 3.6 specifies that CNAME + ** should point at the canonical name -- but + ** urges software to try again anyway. + */ + + goto cnameloop; + + default: + /* not a record of interest */ + continue; + } + } + + if (amatch) + { + /* + ** Got a good match -- either an A, CNAME, or an + ** exact MX record. Save it and get out of here. + */ + + mxmatch = *dp; + break; + } + + /* + ** Nothing definitive yet. + ** If this was a T_ANY query, we don't really know what + ** was returned -- it might have been a T_NS, + ** for example. Try T_A to be more specific + ** during the next pass. + ** If this was a T_A query and we haven't yet found a MX + ** match, try T_MX if allowed to do so. + ** Otherwise, try the next domain. + */ + + if (qtype == T_ANY) + qtype = T_A; + else if (qtype == T_A && !gotmx && trymx) + qtype = T_MX; + else + { + qtype = T_ANY; + dp++; + } + } + + /* if nothing was found, we are done */ + if (mxmatch == NULL) + { + *statp = EX_NOHOST; + return FALSE; + } + + /* + ** Create canonical name and return. + ** If saved domain name is null, name was already canonical. + ** Otherwise append the saved domain name. + */ + + (void) sprintf(nbuf, "%.*s%s%.*s", MAXDNAME, host, + *mxmatch == '\0' ? "" : ".", + MAXDNAME, mxmatch); + strncpy(host, nbuf, hbsize); + host[hbsize - 1] = '\0'; + if (tTd(8, 5)) + printf("dns_getcanonname: %s\n", host); + *statp = EX_OK; + return TRUE; +} + + + +char * +gethostalias(host) + char *host; +{ + char *fname; + FILE *fp; + register char *p = NULL; + char buf[MAXLINE]; + static char hbuf[MAXDNAME]; + + fname = getenv("HOSTALIASES"); + if (fname == NULL || + (fp = safefopen(fname, O_RDONLY, 0, SFF_REGONLY)) == NULL) + return NULL; + while (fgets(buf, sizeof buf, fp) != NULL) + { + for (p = buf; p != '\0' && !(isascii(*p) && isspace(*p)); p++) + continue; + if (*p == 0) + { + /* syntax error */ + continue; + } + *p++ = '\0'; + if (strcasecmp(buf, host) == 0) + break; + } + + if (feof(fp)) + { + /* no match */ + fclose(fp); + return NULL; + } + + /* got a match; extract the equivalent name */ + while (*p != '\0' && isascii(*p) && isspace(*p)) + p++; + host = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + *p = '\0'; + strncpy(hbuf, host, sizeof hbuf - 1); + hbuf[sizeof hbuf - 1] = '\0'; + return hbuf; +} + +#endif /* NAMED_BIND */ diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c new file mode 100644 index 000000000000..4bf7ac231ddf --- /dev/null +++ b/usr.sbin/sendmail/src/envelope.c @@ -0,0 +1,924 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)envelope.c 8.76 (Berkeley) 11/11/95"; +#endif /* not lint */ + +#include "sendmail.h" + +/* +** NEWENVELOPE -- allocate a new envelope +** +** Supports inheritance. +** +** Parameters: +** e -- the new envelope to fill in. +** parent -- the envelope to be the parent of e. +** +** Returns: +** e. +** +** Side Effects: +** none. +*/ + +ENVELOPE * +newenvelope(e, parent) + register ENVELOPE *e; + register ENVELOPE *parent; +{ + if (e == parent && e->e_parent != NULL) + parent = e->e_parent; + clearenvelope(e, TRUE); + if (e == CurEnv) + bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from); + else + bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from); + e->e_parent = parent; + e->e_ctime = curtime(); + if (parent != NULL) + e->e_msgpriority = parent->e_msgsize; + e->e_puthdr = putheader; + e->e_putbody = putbody; + if (CurEnv->e_xfp != NULL) + (void) fflush(CurEnv->e_xfp); + + return (e); +} +/* +** DROPENVELOPE -- deallocate an envelope. +** +** Parameters: +** e -- the envelope to deallocate. +** +** Returns: +** none. +** +** Side Effects: +** housekeeping necessary to dispose of an envelope. +** Unlocks this queue file. +*/ + +void +dropenvelope(e) + register ENVELOPE *e; +{ + bool queueit = FALSE; + bool failure_return = FALSE; + bool success_return = FALSE; + register ADDRESS *q; + char *id = e->e_id; + char buf[MAXLINE]; + + if (tTd(50, 1)) + { + extern void printenvflags(); + + printf("dropenvelope %x: id=", e); + xputs(e->e_id); + printf(", flags="); + printenvflags(e); + if (tTd(50, 10)) + { + printf("sendq="); + printaddr(e->e_sendqueue, TRUE); + } + } + +#ifdef LOG + if (LogLevel > 84) + syslog(LOG_DEBUG, "%s: dropenvelope, e_flags=0x%x, OpMode=%c, pid=%d", + id == NULL ? "[NOQUEUE]" : id, + e->e_flags, OpMode, getpid()); +#endif + + /* we must have an id to remove disk files */ + if (id == NULL) + return; + + /* if verify-only mode, we can skip most of this */ + if (OpMode == MD_VERIFY) + goto simpledrop; + + if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) + logsender(e, NULL); + e->e_flags &= ~EF_LOGSENDER; + + /* post statistics */ + poststats(StatFile); + + /* + ** Extract state information from dregs of send list. + */ + + e->e_flags &= ~EF_QUEUERUN; + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags) || + bitset(QQUEUEUP, q->q_flags)) + queueit = TRUE; + + /* see if a notification is needed */ + if (bitset(QBADADDR, q->q_flags) && + bitset(QPINGONFAILURE, q->q_flags)) + { + failure_return = TRUE; + if (q->q_owner == NULL && !emptyaddr(&e->e_from)) + (void) sendtolist(e->e_from.q_paddr, NULL, + &e->e_errorqueue, 0, e); + } + else if (bitset(QPINGONSUCCESS, q->q_flags) && + ((bitset(QSENT, q->q_flags) && + bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) || + bitset(QRELAYED|QEXPANDED|QDELIVERED, q->q_flags))) + { + success_return = TRUE; + } + } + + if (e->e_class < 0) + e->e_flags |= EF_NO_BODY_RETN; + + /* + ** See if the message timed out. + */ + + if (!queueit) + /* nothing to do */ ; + else if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) + { + (void) sprintf(buf, "Cannot send message for %s", + pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); + if (e->e_message != NULL) + free(e->e_message); + e->e_message = newstr(buf); + message(buf); + e->e_flags |= EF_CLRQUEUE; + failure_return = TRUE; + fprintf(e->e_xfp, "Message could not be delivered for %s\n", + pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); + fprintf(e->e_xfp, "Message will be deleted from queue\n"); + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (bitset(QQUEUEUP, q->q_flags) || + !bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) + { + q->q_flags |= QBADADDR; + q->q_status = "4.4.7"; + } + } + } + else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && + curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) + { + bool delay_return = FALSE; + + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (bitset(QQUEUEUP, q->q_flags) && + bitset(QPINGONDELAY, q->q_flags)) + { + q->q_flags |= QDELAYED; + delay_return = TRUE; + } + } + if (delay_return && + !bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && + e->e_class >= 0 && + e->e_from.q_paddr != NULL && + strcmp(e->e_from.q_paddr, "<>") != 0 && + strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && + (strlen(e->e_from.q_paddr) <= (SIZE_T) 8 || + strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0)) + { + (void) sprintf(buf, + "Warning: could not send message for past %s", + pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); + if (e->e_message != NULL) + free(e->e_message); + e->e_message = newstr(buf); + message(buf); + e->e_flags |= EF_WARNING; + failure_return = TRUE; + } + fprintf(e->e_xfp, + "Warning: message still undelivered after %s\n", + pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); + fprintf(e->e_xfp, "Will keep trying until message is %s old\n", + pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); + } + + if (tTd(50, 2)) + printf("failure_return=%d success_return=%d queueit=%d\n", + failure_return, success_return, queueit); + + /* + ** If we had some fatal error, but no addresses are marked as + ** bad, mark them _all_ as bad. + */ + + if (bitset(EF_FATALERRS, e->e_flags) && !failure_return) + { + failure_return = TRUE; + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (!bitset(QDONTSEND, q->q_flags)) + q->q_flags |= QBADADDR; + } + } + + /* + ** Send back return receipts as requested. + */ + +/* + if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags) + && !bitset(PRIV_NORECEIPTS, PrivacyFlags)) +*/ + if (e->e_receiptto == NULL) + e->e_receiptto = e->e_from.q_paddr; + if (success_return && !failure_return && + !bitset(PRIV_NORECEIPTS, PrivacyFlags) && + strcmp(e->e_receiptto, "<>") != 0) + { + auto ADDRESS *rlist = NULL; + + e->e_flags |= EF_SENDRECEIPT; + (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, 0, e); + (void) returntosender("Return receipt", rlist, FALSE, e); + } + e->e_flags &= ~EF_SENDRECEIPT; + + /* + ** Arrange to send error messages if there are fatal errors. + */ + + if (failure_return && e->e_errormode != EM_QUIET) + savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); + + /* + ** Arrange to send warning messages to postmaster as requested. + */ + + if ((failure_return || bitset(EF_PM_NOTIFY, e->e_flags)) && + PostMasterCopy != NULL && + !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0) + { + auto ADDRESS *rlist = NULL; + + (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, 0, e); + (void) returntosender(e->e_message, rlist, FALSE, e); + } + + /* + ** Instantiate or deinstantiate the queue. + */ + +simpledrop: + if (!queueit || bitset(EF_CLRQUEUE, e->e_flags)) + { + if (tTd(50, 1)) + { + extern void printenvflags(); + + printf("\n===== Dropping [dq]f%s... queueit=%d, e_flags=", + e->e_id, queueit); + printenvflags(e); + } + xunlink(queuename(e, 'd')); + xunlink(queuename(e, 'q')); + +#ifdef LOG + if (LogLevel > 10) + syslog(LOG_INFO, "%s: done", id); +#endif + } + else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) + { +#ifdef QUEUE + queueup(e, FALSE); +#else /* QUEUE */ + syserr("554 dropenvelope: queueup"); +#endif /* QUEUE */ + } + + /* now unlock the job */ + closexscript(e); + unlockqueue(e); + + /* make sure that this envelope is marked unused */ + if (e->e_dfp != NULL) + (void) xfclose(e->e_dfp, "dropenvelope df", e->e_id); + e->e_dfp = NULL; + e->e_id = NULL; + e->e_flags &= ~EF_HAS_DF; +} +/* +** CLEARENVELOPE -- clear an envelope without unlocking +** +** This is normally used by a child process to get a clean +** envelope without disturbing the parent. +** +** Parameters: +** e -- the envelope to clear. +** fullclear - if set, the current envelope is total +** garbage and should be ignored; otherwise, +** release any resources it may indicate. +** +** Returns: +** none. +** +** Side Effects: +** Closes files associated with the envelope. +** Marks the envelope as unallocated. +*/ + +void +clearenvelope(e, fullclear) + register ENVELOPE *e; + bool fullclear; +{ + register HDR *bh; + register HDR **nhp; + extern ENVELOPE BlankEnvelope; + + if (!fullclear) + { + /* clear out any file information */ + if (e->e_xfp != NULL) + (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); + if (e->e_dfp != NULL) + (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_id); + e->e_xfp = e->e_dfp = NULL; + } + + /* now clear out the data */ + STRUCTCOPY(BlankEnvelope, *e); + if (Verbose) + e->e_sendmode = SM_DELIVER; + bh = BlankEnvelope.e_header; + nhp = &e->e_header; + while (bh != NULL) + { + *nhp = (HDR *) xalloc(sizeof *bh); + bcopy((char *) bh, (char *) *nhp, sizeof *bh); + bh = bh->h_link; + nhp = &(*nhp)->h_link; + } +} +/* +** INITSYS -- initialize instantiation of system +** +** In Daemon mode, this is done in the child. +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Initializes the system macros, some global variables, +** etc. In particular, the current time in various +** forms is set. +*/ + +void +initsys(e) + register ENVELOPE *e; +{ + char cbuf[5]; /* holds hop count */ + char pbuf[10]; /* holds pid */ +#ifdef TTYNAME + static char ybuf[60]; /* holds tty id */ + register char *p; +#endif /* TTYNAME */ + extern char *ttyname(); + extern void settime(); + + /* + ** Give this envelope a reality. + ** I.e., an id, a transcript, and a creation time. + */ + + openxscript(e); + e->e_ctime = curtime(); + + /* + ** Set OutChannel to something useful if stdout isn't it. + ** This arranges that any extra stuff the mailer produces + ** gets sent back to the user on error (because it is + ** tucked away in the transcript). + */ + + if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && + e->e_xfp != NULL) + OutChannel = e->e_xfp; + + /* + ** Set up some basic system macros. + */ + + /* process id */ + (void) sprintf(pbuf, "%d", getpid()); + define('p', newstr(pbuf), e); + + /* hop count */ + (void) sprintf(cbuf, "%d", e->e_hopcount); + define('c', newstr(cbuf), e); + + /* time as integer, unix time, arpa time */ + settime(e); + +#ifdef TTYNAME + /* tty name */ + if (macvalue('y', e) == NULL) + { + p = ttyname(2); + if (p != NULL) + { + if (strrchr(p, '/') != NULL) + p = strrchr(p, '/') + 1; + (void) strcpy(ybuf, p); + define('y', ybuf, e); + } + } +#endif /* TTYNAME */ +} +/* +** SETTIME -- set the current time. +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Sets the various time macros -- $a, $b, $d, $t. +*/ + +void +settime(e) + register ENVELOPE *e; +{ + register char *p; + auto time_t now; + char tbuf[20]; /* holds "current" time */ + char dbuf[30]; /* holds ctime(tbuf) */ + register struct tm *tm; + extern char *arpadate(); + extern struct tm *gmtime(); + + now = curtime(); + tm = gmtime(&now); + (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, + tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); + define('t', newstr(tbuf), e); + (void) strcpy(dbuf, ctime(&now)); + p = strchr(dbuf, '\n'); + if (p != NULL) + *p = '\0'; + define('d', newstr(dbuf), e); + p = arpadate(dbuf); + p = newstr(p); + if (macvalue('a', e) == NULL) + define('a', p, e); + define('b', p, e); +} +/* +** OPENXSCRIPT -- Open transcript file +** +** Creates a transcript file for possible eventual mailing or +** sending back. +** +** Parameters: +** e -- the envelope to create the transcript in/for. +** +** Returns: +** none +** +** Side Effects: +** Creates the transcript file. +*/ + +#ifndef O_APPEND +#define O_APPEND 0 +#endif + +void +openxscript(e) + register ENVELOPE *e; +{ + register char *p; + int fd; + + if (e->e_xfp != NULL) + return; + p = queuename(e, 'x'); + fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); + if (fd < 0) + { + syserr("Can't create transcript file %s", p); + fd = open("/dev/null", O_WRONLY, 0644); + if (fd < 0) + syserr("!Can't open /dev/null"); + } + e->e_xfp = fdopen(fd, "a"); + if (e->e_xfp == NULL) + syserr("!Can't create transcript stream %s", p); +#ifdef HASSETVBUF + setvbuf(e->e_xfp, NULL, _IOLBF, 0); +#else + setlinebuf(e->e_xfp); +#endif + if (tTd(46, 9)) + { + printf("openxscript(%s):\n ", p); + dumpfd(fileno(e->e_xfp), TRUE, FALSE); + } +} +/* +** CLOSEXSCRIPT -- close the transcript file. +** +** Parameters: +** e -- the envelope containing the transcript to close. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +void +closexscript(e) + register ENVELOPE *e; +{ + if (e->e_xfp == NULL) + return; + (void) xfclose(e->e_xfp, "closexscript", e->e_id); + e->e_xfp = NULL; +} +/* +** SETSENDER -- set the person who this message is from +** +** Under certain circumstances allow the user to say who +** s/he is (using -f or -r). These are: +** 1. The user's uid is zero (root). +** 2. The user's login name is in an approved list (typically +** from a network server). +** 3. The address the user is trying to claim has a +** "!" character in it (since #2 doesn't do it for +** us if we are dialing out for UUCP). +** A better check to replace #3 would be if the +** effective uid is "UUCP" -- this would require me +** to rewrite getpwent to "grab" uucp as it went by, +** make getname more nasty, do another passwd file +** scan, or compile the UID of "UUCP" into the code, +** all of which are reprehensible. +** +** Assuming all of these fail, we figure out something +** ourselves. +** +** Parameters: +** from -- the person we would like to believe this message +** is from, as specified on the command line. +** e -- the envelope in which we would like the sender set. +** delimptr -- if non-NULL, set to the location of the +** trailing delimiter. +** internal -- set if this address is coming from an internal +** source such as an owner alias. +** +** Returns: +** none. +** +** Side Effects: +** sets sendmail's notion of who the from person is. +*/ + +void +setsender(from, e, delimptr, internal) + char *from; + register ENVELOPE *e; + char **delimptr; + bool internal; +{ + register char **pvp; + char *realname = NULL; + register struct passwd *pw; + char delimchar; + char *bp; + char buf[MAXNAME + 2]; + char pvpbuf[PSBUFSIZE]; + extern char *FullName; + + if (tTd(45, 1)) + printf("setsender(%s)\n", from == NULL ? "" : from); + + /* + ** Figure out the real user executing us. + ** Username can return errno != 0 on non-errors. + */ + + if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || + OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) + realname = from; + if (realname == NULL || realname[0] == '\0') + realname = username(); + + if (ConfigLevel < 2) + SuprErrs = TRUE; + + delimchar = internal ? '\0' : ' '; + e->e_from.q_flags = QBADADDR; + if (from == NULL || + parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, + delimchar, delimptr, e) == NULL || + bitset(QBADADDR, e->e_from.q_flags) || + e->e_from.q_mailer == ProgMailer || + e->e_from.q_mailer == FileMailer || + e->e_from.q_mailer == InclMailer) + { + /* log garbage addresses for traceback */ +# ifdef LOG + if (from != NULL && LogLevel > 2) + { + char *p; + char ebuf[MAXNAME * 2 + 2]; + + p = macvalue('_', e); + if (p == NULL) + { + char *host = RealHostName; + + if (host == NULL) + host = MyHostName; + (void) sprintf(ebuf, "%.*s@%.*s", + MAXNAME, realname, + MAXNAME, host); + p = ebuf; + } + syslog(LOG_NOTICE, + "setsender: %s: invalid or unparseable, received from %s", + shortenstring(from, 83), p); + } +# endif /* LOG */ + if (from != NULL) + { + if (!bitset(QBADADDR, e->e_from.q_flags)) + { + /* it was a bogus mailer in the from addr */ + e->e_status = "5.1.7"; + usrerr("553 Invalid sender address"); + } + SuprErrs = TRUE; + } + if (from == realname || + parseaddr(from = newstr(realname), &e->e_from, + RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL) + { + char nbuf[100]; + + SuprErrs = TRUE; + expand("\201n", nbuf, sizeof nbuf, e); + if (parseaddr(from = newstr(nbuf), &e->e_from, + RF_COPYALL, ' ', NULL, e) == NULL && + parseaddr(from = "postmaster", &e->e_from, + RF_COPYALL, ' ', NULL, e) == NULL) + syserr("553 setsender: can't even parse postmaster!"); + } + } + else + FromFlag = TRUE; + e->e_from.q_flags |= QDONTSEND; + if (tTd(45, 5)) + { + printf("setsender: QDONTSEND "); + printaddr(&e->e_from, FALSE); + } + SuprErrs = FALSE; + +# if USERDB + if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) + { + register char *p; + extern char *udbsender(); + + p = udbsender(e->e_from.q_user); + if (p != NULL) + from = p; + } +# endif /* USERDB */ + + if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) + { + if (!internal) + { + /* if the user already given fullname don't redefine */ + if (FullName == NULL) + FullName = macvalue('x', e); + if (FullName != NULL && FullName[0] == '\0') + FullName = NULL; + } + + if ((pw = sm_getpwnam(e->e_from.q_user)) != NULL) + { + /* + ** Process passwd file entry. + */ + + /* extract home directory */ + if (strcmp(pw->pw_dir, "/") == 0) + e->e_from.q_home = newstr(""); + else + e->e_from.q_home = newstr(pw->pw_dir); + define('z', e->e_from.q_home, e); + + /* extract user and group id */ + e->e_from.q_uid = pw->pw_uid; + e->e_from.q_gid = pw->pw_gid; + e->e_from.q_flags |= QGOODUID; + + /* extract full name from passwd file */ + if (FullName == NULL && pw->pw_gecos != NULL && + strcmp(pw->pw_name, e->e_from.q_user) == 0 && + !internal) + { + buildfname(pw->pw_gecos, e->e_from.q_user, buf); + if (buf[0] != '\0') + FullName = newstr(buf); + } + } + if (FullName != NULL && !internal) + define('x', FullName, e); + } + else if (!internal && OpMode != MD_DAEMON) + { + if (e->e_from.q_home == NULL) + { + e->e_from.q_home = getenv("HOME"); + if (e->e_from.q_home != NULL && + strcmp(e->e_from.q_home, "/") == 0) + e->e_from.q_home++; + } + e->e_from.q_uid = RealUid; + e->e_from.q_gid = RealGid; + e->e_from.q_flags |= QGOODUID; + } + + /* + ** Rewrite the from person to dispose of possible implicit + ** links in the net. + */ + + pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL); + if (pvp == NULL) + { + /* don't need to give error -- prescan did that already */ +# ifdef LOG + if (LogLevel > 2) + syslog(LOG_NOTICE, "cannot prescan from (%s)", + shortenstring(from, 203)); +# endif + finis(); + } + (void) rewrite(pvp, 3, 0, e); + (void) rewrite(pvp, 1, 0, e); + (void) rewrite(pvp, 4, 0, e); + bp = buf + 1; + cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); + if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) + { + /* heuristic: route-addr: add angle brackets */ + strcat(bp, ">"); + *--bp = '<'; + } + e->e_sender = newstr(bp); + define('f', e->e_sender, e); + + /* save the domain spec if this mailer wants it */ + if (e->e_from.q_mailer != NULL && + bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) + { + char **lastat; + extern char **copyplist(); + + /* get rid of any pesky angle brackets */ + (void) rewrite(pvp, 3, 0, e); + (void) rewrite(pvp, 1, 0, e); + (void) rewrite(pvp, 4, 0, e); + + /* strip off to the last "@" sign */ + for (lastat = NULL; *pvp != NULL; pvp++) + if (strcmp(*pvp, "@") == 0) + lastat = pvp; + if (lastat != NULL) + { + e->e_fromdomain = copyplist(lastat, TRUE); + if (tTd(45, 3)) + { + printf("Saving from domain: "); + printav(e->e_fromdomain); + } + } + } +} +/* +** PRINTENVFLAGS -- print envelope flags for debugging +** +** Parameters: +** e -- the envelope with the flags to be printed. +** +** Returns: +** none. +*/ + +struct eflags +{ + char *ef_name; + u_long ef_bit; +}; + +struct eflags EnvelopeFlags[] = +{ + "OLDSTYLE", EF_OLDSTYLE, + "INQUEUE", EF_INQUEUE, + "NO_BODY_RETN", EF_NO_BODY_RETN, + "CLRQUEUE", EF_CLRQUEUE, + "SENDRECEIPT", EF_SENDRECEIPT, + "FATALERRS", EF_FATALERRS, + "DELETE_BCC", EF_DELETE_BCC, + "RESPONSE", EF_RESPONSE, + "RESENT", EF_RESENT, + "VRFYONLY", EF_VRFYONLY, + "WARNING", EF_WARNING, + "QUEUERUN", EF_QUEUERUN, + "GLOBALERRS", EF_GLOBALERRS, + "PM_NOTIFY", EF_PM_NOTIFY, + "METOO", EF_METOO, + "LOGSENDER", EF_LOGSENDER, + "NORECEIPT", EF_NORECEIPT, + "HAS8BIT", EF_HAS8BIT, + "NL_NOT_EOL", EF_NL_NOT_EOL, + "CRLF_NOT_EOL", EF_CRLF_NOT_EOL, + "RET_PARAM", EF_RET_PARAM, + "HAS_DF", EF_HAS_DF, + "IS_MIME", EF_IS_MIME, + "DONT_MIME", EF_DONT_MIME, + NULL +}; + +void +printenvflags(e) + register ENVELOPE *e; +{ + register struct eflags *ef; + bool first = TRUE; + + printf("%lx", e->e_flags); + for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++) + { + if (!bitset(ef->ef_bit, e->e_flags)) + continue; + if (first) + printf("<%s", ef->ef_name); + else + printf(",%s", ef->ef_name); + first = FALSE; + } + if (!first) + printf(">\n"); +} diff --git a/usr.sbin/sendmail/src/err.c b/usr.sbin/sendmail/src/err.c new file mode 100644 index 000000000000..6acb8fbeed27 --- /dev/null +++ b/usr.sbin/sendmail/src/err.c @@ -0,0 +1,695 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)err.c 8.41 (Berkeley) 10/8/95"; +#endif /* not lint */ + +# include "sendmail.h" +# include <errno.h> + +/* +** SYSERR -- Print error message. +** +** Prints an error message via printf to the diagnostic +** output. If LOG is defined, it logs it also. +** +** If the first character of the syserr message is `!' it will +** log this as an ALERT message and exit immediately. This can +** leave queue files in an indeterminate state, so it should not +** be used lightly. +** +** Parameters: +** fmt -- the format string. If it does not begin with +** a three-digit SMTP reply code, either 554 or +** 451 is assumed depending on whether errno +** is set. +** (others) -- parameters +** +** Returns: +** none +** Through TopFrame if QuickAbort is set. +** +** Side Effects: +** increments Errors. +** sets ExitStat. +*/ + +char MsgBuf[BUFSIZ*2]; /* text of most recent message */ +char HeldMessageBuf[sizeof MsgBuf]; /* for held messages */ + +extern void putoutmsg __P((char *, bool, bool)); +extern void puterrmsg __P((char *)); +static void fmtmsg __P((char *, const char *, const char *, int, const char *, va_list)); + +#if NAMED_BIND && !defined(NO_DATA) +# define NO_DATA NO_ADDRESS +#endif + +void +/*VARARGS1*/ +#ifdef __STDC__ +syserr(const char *fmt, ...) +#else +syserr(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + register char *p; + int olderrno = errno; + bool panic; +#ifdef LOG + char *uname; + struct passwd *pw; + char ubuf[80]; +#endif + VA_LOCAL_DECL + + panic = *fmt == '!'; + if (panic) + fmt++; + + /* format and output the error message */ + if (olderrno == 0) + p = "554"; + else + p = "451"; + VA_START(fmt); + fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, ap); + VA_END; + puterrmsg(MsgBuf); + + /* save this message for mailq printing */ + if (!panic) + { + if (CurEnv->e_message != NULL) + free(CurEnv->e_message); + CurEnv->e_message = newstr(MsgBuf + 4); + } + + /* determine exit status if not already set */ + if (ExitStat == EX_OK) + { + if (olderrno == 0) + ExitStat = EX_SOFTWARE; + else + ExitStat = EX_OSERR; + if (tTd(54, 1)) + printf("syserr: ExitStat = %d\n", ExitStat); + } + +# ifdef LOG + pw = sm_getpwuid(getuid()); + if (pw != NULL) + uname = pw->pw_name; + else + { + uname = ubuf; + sprintf(ubuf, "UID%d", getuid()); + } + + if (LogLevel > 0) + syslog(panic ? LOG_ALERT : LOG_CRIT, "%s: SYSERR(%s): %.900s", + CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id, + uname, &MsgBuf[4]); +# endif /* LOG */ + if (olderrno == EMFILE) + { + printopenfds(TRUE); + mci_dump_all(TRUE); + } + if (panic) + { +#ifdef XLA + xla_all_end(); +#endif + if (tTd(0, 1)) + abort(); + exit(EX_OSERR); + } + errno = 0; + if (QuickAbort) + longjmp(TopFrame, 2); +} +/* +** USRERR -- Signal user error. +** +** This is much like syserr except it is for user errors. +** +** Parameters: +** fmt -- the format string. If it does not begin with +** a three-digit SMTP reply code, 501 is assumed. +** (others) -- printf strings +** +** Returns: +** none +** Through TopFrame if QuickAbort is set. +** +** Side Effects: +** increments Errors. +*/ + +/*VARARGS1*/ +void +#ifdef __STDC__ +usrerr(const char *fmt, ...) +#else +usrerr(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + VA_LOCAL_DECL + + if (SuprErrs) + return; + + VA_START(fmt); + fmtmsg(MsgBuf, CurEnv->e_to, "501", 0, fmt, ap); + VA_END; + + /* save this message for mailq printing */ + switch (MsgBuf[0]) + { + case '4': + case '8': + if (CurEnv->e_message != NULL) + break; + + /* fall through.... */ + + case '5': + case '6': + if (CurEnv->e_message != NULL) + free(CurEnv->e_message); + if (MsgBuf[0] == '6') + { + char buf[MAXLINE]; + + sprintf(buf, "Postmaster warning: %.*s", + sizeof buf - 22, MsgBuf + 4); + CurEnv->e_message = newstr(buf); + } + else + { + CurEnv->e_message = newstr(MsgBuf + 4); + } + break; + } + + puterrmsg(MsgBuf); + +# ifdef LOG + if (LogLevel > 3 && LogUsrErrs) + syslog(LOG_NOTICE, "%s: %.900s", + CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id, + &MsgBuf[4]); +# endif /* LOG */ + + if (QuickAbort) + longjmp(TopFrame, 1); +} +/* +** MESSAGE -- print message (not necessarily an error) +** +** Parameters: +** msg -- the message (printf fmt) -- it can begin with +** an SMTP reply code. If not, 050 is assumed. +** (others) -- printf arguments +** +** Returns: +** none +** +** Side Effects: +** none. +*/ + +/*VARARGS2*/ +void +#ifdef __STDC__ +message(const char *msg, ...) +#else +message(msg, va_alist) + const char *msg; + va_dcl +#endif +{ + VA_LOCAL_DECL + + errno = 0; + VA_START(msg); + fmtmsg(MsgBuf, CurEnv->e_to, "050", 0, msg, ap); + VA_END; + putoutmsg(MsgBuf, FALSE, FALSE); + + /* save this message for mailq printing */ + switch (MsgBuf[0]) + { + case '4': + case '8': + if (CurEnv->e_message != NULL) + break; + /* fall through.... */ + + case '5': + if (CurEnv->e_message != NULL) + free(CurEnv->e_message); + CurEnv->e_message = newstr(MsgBuf + 4); + break; + } +} +/* +** NMESSAGE -- print message (not necessarily an error) +** +** Just like "message" except it never puts the to... tag on. +** +** Parameters: +** msg -- the message (printf fmt) -- if it begins +** with a three digit SMTP reply code, that is used, +** otherwise 050 is assumed. +** (others) -- printf arguments +** +** Returns: +** none +** +** Side Effects: +** none. +*/ + +/*VARARGS2*/ +void +#ifdef __STDC__ +nmessage(const char *msg, ...) +#else +nmessage(msg, va_alist) + const char *msg; + va_dcl +#endif +{ + VA_LOCAL_DECL + + errno = 0; + VA_START(msg); + fmtmsg(MsgBuf, (char *) NULL, "050", 0, msg, ap); + VA_END; + putoutmsg(MsgBuf, FALSE, FALSE); + + /* save this message for mailq printing */ + switch (MsgBuf[0]) + { + case '4': + case '8': + if (CurEnv->e_message != NULL) + break; + /* fall through.... */ + + case '5': + if (CurEnv->e_message != NULL) + free(CurEnv->e_message); + CurEnv->e_message = newstr(MsgBuf + 4); + break; + } +} +/* +** PUTOUTMSG -- output error message to transcript and channel +** +** Parameters: +** msg -- message to output (in SMTP format). +** holdmsg -- if TRUE, don't output a copy of the message to +** our output channel. +** heldmsg -- if TRUE, this is a previously held message; +** don't log it to the transcript file. +** +** Returns: +** none. +** +** Side Effects: +** Outputs msg to the transcript. +** If appropriate, outputs it to the channel. +** Deletes SMTP reply code number as appropriate. +*/ + +void +putoutmsg(msg, holdmsg, heldmsg) + char *msg; + bool holdmsg; + bool heldmsg; +{ + char msgcode = msg[0]; + + /* display for debugging */ + if (tTd(54, 8)) + printf("--- %s%s%s\n", msg, holdmsg ? " (hold)" : "", + heldmsg ? " (held)" : ""); + + /* map warnings to something SMTP can handle */ + if (msgcode == '6') + msg[0] = '5'; + else if (msgcode == '8') + msg[0] = '4'; + + /* output to transcript if serious */ + if (!heldmsg && CurEnv->e_xfp != NULL && strchr("45", msg[0]) != NULL) + fprintf(CurEnv->e_xfp, "%s\n", msg); + + if (msgcode == '8') + msg[0] == '0'; + + /* output to channel if appropriate */ + if (!Verbose && msg[0] == '0') + return; + if (holdmsg) + { + /* save for possible future display */ + msg[0] = msgcode; + strcpy(HeldMessageBuf, msg); + return; + } + + (void) fflush(stdout); + + /* if DisConnected, OutChannel now points to the transcript */ + if (!DisConnected && + (OpMode == MD_SMTP || OpMode == MD_DAEMON || OpMode == MD_ARPAFTP)) + fprintf(OutChannel, "%s\r\n", msg); + else + fprintf(OutChannel, "%s\n", &msg[4]); + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%05d >>> %s\n", getpid(), + (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : &msg[4]); + if (msg[3] == ' ') + (void) fflush(OutChannel); + if (!ferror(OutChannel) || DisConnected) + return; + + /* + ** Error on output -- if reporting lost channel, just ignore it. + ** Also, ignore errors from QUIT response (221 message) -- some + ** rude servers don't read result. + */ + + if (feof(InChannel) || ferror(InChannel) || strncmp(msg, "221", 3) == 0) + return; + + /* can't call syserr, 'cause we are using MsgBuf */ + HoldErrs = TRUE; +#ifdef LOG + if (LogLevel > 0) + syslog(LOG_CRIT, + "%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s", + CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id, + CurHostName == NULL ? "NO-HOST" : CurHostName, + shortenstring(msg, 203), errstring(errno)); +#endif +} +/* +** PUTERRMSG -- like putoutmsg, but does special processing for error messages +** +** Parameters: +** msg -- the message to output. +** +** Returns: +** none. +** +** Side Effects: +** Sets the fatal error bit in the envelope as appropriate. +*/ + +void +puterrmsg(msg) + char *msg; +{ + char msgcode = msg[0]; + + /* output the message as usual */ + putoutmsg(msg, HoldErrs, FALSE); + + /* signal the error */ + Errors++; + if (msgcode == '6') + { + /* notify the postmaster */ + CurEnv->e_flags |= EF_PM_NOTIFY; + } + else if (msgcode == '5' && bitset(EF_GLOBALERRS, CurEnv->e_flags)) + { + /* mark long-term fatal errors */ + CurEnv->e_flags |= EF_FATALERRS; + } +} +/* +** FMTMSG -- format a message into buffer. +** +** Parameters: +** eb -- error buffer to get result. +** to -- the recipient tag for this message. +** num -- arpanet error number. +** en -- the error number to display. +** fmt -- format of string. +** a, b, c, d, e -- arguments. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +static void +fmtmsg(eb, to, num, eno, fmt, ap) + register char *eb; + const char *to; + const char *num; + int eno; + const char *fmt; + va_list ap; +{ + char del; + char *meb; + int l; + int spaceleft = sizeof MsgBuf; + + /* output the reply code */ + if (isdigit(fmt[0]) && isdigit(fmt[1]) && isdigit(fmt[2])) + { + num = fmt; + fmt += 4; + } + if (num[3] == '-') + del = '-'; + else + del = ' '; + (void) sprintf(eb, "%3.3s%c", num, del); + eb += 4; + spaceleft -= 4; + + /* output the file name and line number */ + if (FileName != NULL) + { + (void) snprintf(eb, spaceleft, "%s: line %d: ", + shortenstring(FileName, 83), LineNumber); + eb += (l = strlen(eb)); + spaceleft -= l; + } + + /* output the "to" person */ + if (to != NULL && to[0] != '\0') + { + (void) snprintf(eb, spaceleft, "%s... ", + shortenstring(to, 203)); + spaceleft -= strlen(eb); + while (*eb != '\0') + *eb++ &= 0177; + } + + meb = eb; + + /* output the message */ + (void) vsnprintf(eb, spaceleft, fmt, ap); + spaceleft -= strlen(eb); + while (*eb != '\0') + *eb++ &= 0177; + + /* output the error code, if any */ + if (eno != 0) + (void) snprintf(eb, spaceleft, ": %s", errstring(eno)); +} +/* +** BUFFER_ERRORS -- arrange to buffer future error messages +** +** Parameters: +** none +** +** Returns: +** none. +*/ + +void +buffer_errors() +{ + HeldMessageBuf[0] = '\0'; + HoldErrs = TRUE; +} +/* +** FLUSH_ERRORS -- flush the held error message buffer +** +** Parameters: +** print -- if set, print the message, otherwise just +** delete it. +** +** Returns: +** none. +*/ + +void +flush_errors(print) + bool print; +{ + if (print && HeldMessageBuf[0] != '\0') + putoutmsg(HeldMessageBuf, FALSE, TRUE); + HeldMessageBuf[0] = '\0'; + HoldErrs = FALSE; +} +/* +** ERRSTRING -- return string description of error code +** +** Parameters: +** errnum -- the error number to translate +** +** Returns: +** A string description of errnum. +** +** Side Effects: +** none. +*/ + +const char * +errstring(errnum) + int errnum; +{ + char *dnsmsg; + static char buf[MAXLINE]; +# ifndef ERRLIST_PREDEFINED + extern char *sys_errlist[]; + extern int sys_nerr; +# endif +# ifdef SMTP + extern char *SmtpPhase; +# endif /* SMTP */ + + /* + ** Handle special network error codes. + ** + ** These are 4.2/4.3bsd specific; they should be in daemon.c. + */ + + dnsmsg = NULL; + switch (errnum) + { +# if defined(DAEMON) && defined(ETIMEDOUT) + case ETIMEDOUT: + case ECONNRESET: + (void) strcpy(buf, sys_errlist[errnum]); + if (SmtpPhase != NULL) + { + (void) strcat(buf, " during "); + (void) strcat(buf, SmtpPhase); + } + if (CurHostName != NULL) + { + (void) strcat(buf, " with "); + (void) strcat(buf, CurHostName); + } + return (buf); + + case EHOSTDOWN: + if (CurHostName == NULL) + break; + (void) sprintf(buf, "Host %s is down", + shortenstring(CurHostName, 203)); + return (buf); + + case ECONNREFUSED: + if (CurHostName == NULL) + break; + (void) sprintf(buf, "Connection refused by %s", + shortenstring(CurHostName, 203)); + return (buf); +# endif + + case EOPENTIMEOUT: + return "Timeout on file open"; + +# if NAMED_BIND + case HOST_NOT_FOUND + E_DNSBASE: + dnsmsg = "host not found"; + break; + + case TRY_AGAIN + E_DNSBASE: + dnsmsg = "host name lookup failure"; + break; + + case NO_RECOVERY + E_DNSBASE: + dnsmsg = "non-recoverable error"; + break; + + case NO_DATA + E_DNSBASE: + dnsmsg = "no data known"; + break; +# endif + + case EPERM: + /* SunOS gives "Not owner" -- this is the POSIX message */ + return "Operation not permitted"; + } + + if (dnsmsg != NULL) + { + (void) strcpy(buf, "Name server: "); + if (CurHostName != NULL) + { + (void) strcat(buf, CurHostName); + (void) strcat(buf, ": "); + } + (void) strcat(buf, dnsmsg); + return buf; + } + + if (errnum > 0 && errnum < sys_nerr) + return (sys_errlist[errnum]); + + (void) sprintf(buf, "Error %d", errnum); + return (buf); +} diff --git a/usr.sbin/sendmail/src/headers.c b/usr.sbin/sendmail/src/headers.c new file mode 100644 index 000000000000..ae242b1e258a --- /dev/null +++ b/usr.sbin/sendmail/src/headers.c @@ -0,0 +1,1477 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)headers.c 8.82 (Berkeley) 10/28/95"; +#endif /* not lint */ + +# include <errno.h> +# include "sendmail.h" + +/* +** CHOMPHEADER -- process and save a header line. +** +** Called by collect and by readcf to deal with header lines. +** +** Parameters: +** line -- header as a text line. +** def -- if set, this is a default value. +** hdrp -- a pointer to the place to save the header. +** e -- the envelope including this header. +** +** Returns: +** flags for this header. +** +** Side Effects: +** The header is saved on the header list. +** Contents of 'line' are destroyed. +*/ + +int +chompheader(line, def, hdrp, e) + char *line; + bool def; + HDR **hdrp; + register ENVELOPE *e; +{ + register char *p; + register HDR *h; + HDR **hp; + char *fname; + char *fvalue; + struct hdrinfo *hi; + bool cond = FALSE; + bool headeronly; + BITMAP mopts; + char buf[MAXNAME + 1]; + + if (tTd(31, 6)) + { + printf("chompheader: "); + xputs(line); + printf("\n"); + } + + headeronly = hdrp != NULL; + if (!headeronly) + hdrp = &e->e_header; + + /* strip off options */ + clrbitmap(mopts); + p = line; + if (*p == '?') + { + /* have some */ + register char *q = strchr(p + 1, *p); + + if (q != NULL) + { + *q++ = '\0'; + while (*++p != '\0') + setbitn(*p, mopts); + p = q; + } + else + syserr("553 header syntax error, line \"%s\"", line); + cond = TRUE; + } + + /* find canonical name */ + fname = p; + while (isascii(*p) && isgraph(*p) && *p != ':') + p++; + fvalue = p; + while (isascii(*p) && isspace(*p)) + p++; + if (*p++ != ':' || fname == fvalue) + { + syserr("553 header syntax error, line \"%s\"", line); + return (0); + } + *fvalue = '\0'; + fvalue = p; + + /* strip field value on front */ + if (*fvalue == ' ') + fvalue++; + + /* security scan: long field names are end-of-header */ + if (strlen(fname) > 100) + return H_EOH; + + /* see if it is a known type */ + for (hi = HdrInfo; hi->hi_field != NULL; hi++) + { + if (strcasecmp(hi->hi_field, fname) == 0) + break; + } + + if (tTd(31, 9)) + { + if (hi->hi_field == NULL) + printf("no header match\n"); + else + printf("header match, hi_flags=%x\n", hi->hi_flags); + } + + /* see if this is a resent message */ + if (!def && !headeronly && bitset(H_RESENT, hi->hi_flags)) + e->e_flags |= EF_RESENT; + + /* if this is an Errors-To: header keep track of it now */ + if (UseErrorsTo && !def && !headeronly && + bitset(H_ERRORSTO, hi->hi_flags)) + (void) sendtolist(fvalue, NULLADDR, &e->e_errorqueue, 0, e); + + /* if this means "end of header" quit now */ + if (bitset(H_EOH, hi->hi_flags)) + return (hi->hi_flags); + +#ifdef LOTUS_NOTES_HACK + /* + ** Horrible hack to work around problem with Lotus Notes SMTP + ** mail gateway, which generates From: headers with newlines in + ** them and the <address> on the second line. Although this is + ** legal RFC 822, many MUAs don't handle this properly and thus + ** never find the actual address. + */ + + if (bitset(H_FROM, hi->hi_flags) && SingleLineFromHeader) + { + while ((p = strchr(fvalue, '\n')) != NULL) + *p = ' '; + } +#endif + + /* + ** Drop explicit From: if same as what we would generate. + ** This is to make MH (which doesn't always give a full name) + ** insert the full name information in all circumstances. + */ + + p = "resent-from"; + if (!bitset(EF_RESENT, e->e_flags)) + p += 7; + if (!def && !headeronly && !bitset(EF_QUEUERUN, e->e_flags) && + strcasecmp(fname, p) == 0) + { + if (tTd(31, 2)) + { + printf("comparing header from (%s) against default (%s or %s)\n", + fvalue, e->e_from.q_paddr, e->e_from.q_user); + } + if (e->e_from.q_paddr != NULL && + (strcmp(fvalue, e->e_from.q_paddr) == 0 || + strcmp(fvalue, e->e_from.q_user) == 0)) + return (hi->hi_flags); +#ifdef MAYBENEXTRELEASE /* XXX UNTESTED XXX UNTESTED XXX UNTESTED XXX */ +#if USERDB + else + { + auto ADDRESS a; + char *fancy; + bool oldSuprErrs = SuprErrs; + extern char *crackaddr(); + extern char *udbsender(); + + /* + ** Try doing USERDB rewriting even on fully commented + ** names; this saves the "comment" information (such + ** as full name) and rewrites the electronic part. + ** + ** XXX This code doesn't belong here -- parsing should + ** XXX not be done during collect() phase because + ** XXX error messages can confuse the SMTP phase. + ** XXX Setting SuprErrs is a crude hack around this + ** XXX problem. + */ + + if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP) + SuprErrs = TRUE; + fancy = crackaddr(fvalue); + if (parseaddr(fvalue, &a, RF_COPYNONE, '\0', NULL, e) != NULL && + bitnset(M_CHECKUDB, a.q_mailer->m_flags) && + (p = udbsender(a.q_user)) != NULL) + { + char *oldg = macvalue('g', e); + + define('g', p, e); + expand(fancy, buf, sizeof buf, e); + define('g', oldg, e); + fvalue = buf; + } + SuprErrs = oldSuprErrs; + } +#endif +#endif + } + + /* delete default value for this header */ + for (hp = hdrp; (h = *hp) != NULL; hp = &h->h_link) + { + if (strcasecmp(fname, h->h_field) == 0 && + bitset(H_DEFAULT, h->h_flags) && + !bitset(H_FORCE, h->h_flags)) + { + h->h_value = NULL; + if (!cond) + { + /* copy conditions from default case */ + bcopy((char *)h->h_mflags, (char *)mopts, + sizeof mopts); + } + } + } + + /* create a new node */ + h = (HDR *) xalloc(sizeof *h); + h->h_field = newstr(fname); + h->h_value = newstr(fvalue); + h->h_link = NULL; + bcopy((char *) mopts, (char *) h->h_mflags, sizeof mopts); + *hp = h; + h->h_flags = hi->hi_flags; + if (def) + h->h_flags |= H_DEFAULT; + if (cond) + h->h_flags |= H_CHECK; + + /* hack to see if this is a new format message */ + if (!def && !headeronly && bitset(H_RCPT|H_FROM, h->h_flags) && + (strchr(fvalue, ',') != NULL || strchr(fvalue, '(') != NULL || + strchr(fvalue, '<') != NULL || strchr(fvalue, ';') != NULL)) + { + e->e_flags &= ~EF_OLDSTYLE; + } + + return (h->h_flags); +} +/* +** ADDHEADER -- add a header entry to the end of the queue. +** +** This bypasses the special checking of chompheader. +** +** Parameters: +** field -- the name of the header field. +** value -- the value of the field. +** hp -- an indirect pointer to the header structure list. +** +** Returns: +** none. +** +** Side Effects: +** adds the field on the list of headers for this envelope. +*/ + +void +addheader(field, value, hdrlist) + char *field; + char *value; + HDR **hdrlist; +{ + register HDR *h; + register struct hdrinfo *hi; + HDR **hp; + + /* find info struct */ + for (hi = HdrInfo; hi->hi_field != NULL; hi++) + { + if (strcasecmp(field, hi->hi_field) == 0) + break; + } + + /* find current place in list -- keep back pointer? */ + for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link) + { + if (strcasecmp(field, h->h_field) == 0) + break; + } + + /* allocate space for new header */ + h = (HDR *) xalloc(sizeof *h); + h->h_field = field; + h->h_value = newstr(value); + h->h_link = *hp; + h->h_flags = hi->hi_flags | H_DEFAULT; + clrbitmap(h->h_mflags); + *hp = h; +} +/* +** HVALUE -- return value of a header. +** +** Only "real" fields (i.e., ones that have not been supplied +** as a default) are used. +** +** Parameters: +** field -- the field name. +** header -- the header list. +** +** Returns: +** pointer to the value part. +** NULL if not found. +** +** Side Effects: +** none. +*/ + +char * +hvalue(field, header) + char *field; + HDR *header; +{ + register HDR *h; + + for (h = header; h != NULL; h = h->h_link) + { + if (!bitset(H_DEFAULT, h->h_flags) && + strcasecmp(h->h_field, field) == 0) + return (h->h_value); + } + return (NULL); +} +/* +** ISHEADER -- predicate telling if argument is a header. +** +** A line is a header if it has a single word followed by +** optional white space followed by a colon. +** +** Header fields beginning with two dashes, although technically +** permitted by RFC822, are automatically rejected in order +** to make MIME work out. Without this we could have a technically +** legal header such as ``--"foo:bar"'' that would also be a legal +** MIME separator. +** +** Parameters: +** h -- string to check for possible headerness. +** +** Returns: +** TRUE if h is a header. +** FALSE otherwise. +** +** Side Effects: +** none. +*/ + +bool +isheader(h) + char *h; +{ + register char *s = h; + + if (s[0] == '-' && s[1] == '-') + return FALSE; + + while (*s > ' ' && *s != ':' && *s != '\0') + s++; + + if (h == s) + return FALSE; + + /* following technically violates RFC822 */ + while (isascii(*s) && isspace(*s)) + s++; + + return (*s == ':'); +} +/* +** EATHEADER -- run through the stored header and extract info. +** +** Parameters: +** e -- the envelope to process. +** full -- if set, do full processing (e.g., compute +** message priority). This should not be set +** when reading a queue file because some info +** needed to compute the priority is wrong. +** +** Returns: +** none. +** +** Side Effects: +** Sets a bunch of global variables from information +** in the collected header. +** Aborts the message if the hop count is exceeded. +*/ + +void +eatheader(e, full) + register ENVELOPE *e; + bool full; +{ + register HDR *h; + register char *p; + int hopcnt = 0; + char *msgid; + char buf[MAXLINE]; + + /* + ** Set up macros for possible expansion in headers. + */ + + define('f', e->e_sender, e); + define('g', e->e_sender, e); + if (e->e_origrcpt != NULL && *e->e_origrcpt != '\0') + define('u', e->e_origrcpt, e); + else + define('u', NULL, e); + + /* full name of from person */ + p = hvalue("full-name", e->e_header); + if (p != NULL) + define('x', p, e); + + if (tTd(32, 1)) + printf("----- collected header -----\n"); + msgid = NULL; + for (h = e->e_header; h != NULL; h = h->h_link) + { + if (tTd(32, 1)) + printf("%s: ", h->h_field); + if (h->h_value == NULL) + { + if (tTd(32, 1)) + printf("<NULL>\n"); + continue; + } + + /* do early binding */ + if (bitset(H_DEFAULT, h->h_flags)) + { + if (tTd(32, 1)) + { + printf("("); + xputs(h->h_value); + printf(") "); + } + expand(h->h_value, buf, sizeof buf, e); + if (buf[0] != '\0') + { + if (bitset(H_FROM, h->h_flags)) + { + extern char *crackaddr(); + + expand(crackaddr(buf), buf, sizeof buf, e); + } + h->h_value = newstr(buf); + h->h_flags &= ~H_DEFAULT; + } + } + + if (tTd(32, 1)) + { + xputs(h->h_value); + printf("\n"); + } + + /* count the number of times it has been processed */ + if (bitset(H_TRACE, h->h_flags)) + hopcnt++; + + /* send to this person if we so desire */ + if (GrabTo && bitset(H_RCPT, h->h_flags) && + !bitset(H_DEFAULT, h->h_flags) && + (!bitset(EF_RESENT, e->e_flags) || bitset(H_RESENT, h->h_flags))) + { + int saveflags = e->e_flags; + + (void) sendtolist(h->h_value, NULLADDR, + &e->e_sendqueue, 0, e); + + /* delete fatal errors generated by this address */ + if (!GrabTo && !bitset(EF_FATALERRS, saveflags)) + e->e_flags &= ~EF_FATALERRS; + } + + /* save the message-id for logging */ + p = "resent-message-id"; + if (!bitset(EF_RESENT, e->e_flags)) + p += 7; + if (strcasecmp(h->h_field, p) == 0) + { + msgid = h->h_value; + while (isascii(*msgid) && isspace(*msgid)) + msgid++; + } + + /* see if this is a return-receipt header */ + if (bitset(H_RECEIPTTO, h->h_flags)) + e->e_receiptto = h->h_value; + } + if (tTd(32, 1)) + printf("----------------------------\n"); + + /* if we are just verifying (that is, sendmail -t -bv), drop out now */ + if (OpMode == MD_VERIFY) + return; + + /* store hop count */ + if (hopcnt > e->e_hopcount) + e->e_hopcount = hopcnt; + + /* message priority */ + p = hvalue("precedence", e->e_header); + if (p != NULL) + e->e_class = priencode(p); + if (e->e_class < 0) + e->e_timeoutclass = TOC_NONURGENT; + else if (e->e_class > 0) + e->e_timeoutclass = TOC_URGENT; + if (full) + { + e->e_msgpriority = e->e_msgsize + - e->e_class * WkClassFact + + e->e_nrcpts * WkRecipFact; + } + + /* message timeout priority */ + p = hvalue("priority", e->e_header); + if (p != NULL) + { + /* (this should be in the configuration file) */ + if (strcasecmp(p, "urgent")) + e->e_timeoutclass = TOC_URGENT; + else if (strcasecmp(p, "normal")) + e->e_timeoutclass = TOC_NORMAL; + else if (strcasecmp(p, "non-urgent")) + e->e_timeoutclass = TOC_NONURGENT; + } + + /* date message originated */ + p = hvalue("posted-date", e->e_header); + if (p == NULL) + p = hvalue("date", e->e_header); + if (p != NULL) + define('a', p, e); + + /* check to see if this is a MIME message */ + if ((e->e_bodytype != NULL && + strcasecmp(e->e_bodytype, "8BITMIME") == 0) || + hvalue("MIME-Version", e->e_header) != NULL) + { + e->e_flags |= EF_IS_MIME; + if (HasEightBits) + e->e_bodytype = "8BITMIME"; + } + else if ((p = hvalue("Content-Type", e->e_header)) != NULL) + { + /* this may be an RFC 1049 message */ + p = strpbrk(p, ";/"); + if (p == NULL || *p == ';') + { + /* yep, it is */ + e->e_flags |= EF_DONT_MIME; + } + } + + /* + ** From person in antiquated ARPANET mode + ** required by UK Grey Book e-mail gateways (sigh) + */ + + if (OpMode == MD_ARPAFTP) + { + register struct hdrinfo *hi; + + for (hi = HdrInfo; hi->hi_field != NULL; hi++) + { + if (bitset(H_FROM, hi->hi_flags) && + (!bitset(H_RESENT, hi->hi_flags) || + bitset(EF_RESENT, e->e_flags)) && + (p = hvalue(hi->hi_field, e->e_header)) != NULL) + break; + } + if (hi->hi_field != NULL) + { + if (tTd(32, 2)) + printf("eatheader: setsender(*%s == %s)\n", + hi->hi_field, p); + setsender(p, e, NULL, TRUE); + } + } + + /* + ** Log collection information. + */ + +# ifdef LOG + if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4) + logsender(e, msgid); +# endif /* LOG */ + e->e_flags &= ~EF_LOGSENDER; +} +/* +** LOGSENDER -- log sender information +** +** Parameters: +** e -- the envelope to log +** msgid -- the message id +** +** Returns: +** none +*/ + +void +logsender(e, msgid) + register ENVELOPE *e; + char *msgid; +{ +# ifdef LOG + char *name; + register char *sbp; + register char *p; + int l; + char hbuf[MAXNAME + 1]; + char sbuf[MAXLINE + 1]; + char mbuf[MAXNAME + 1]; + + /* don't allow newlines in the message-id */ + if (msgid != NULL) + { + l = strlen(msgid); + if (l > sizeof mbuf - 1) + l = sizeof mbuf - 1; + bcopy(msgid, mbuf, l); + mbuf[l] = '\0'; + p = mbuf; + while ((p = strchr(p, '\n')) != NULL) + *p++ = ' '; + } + + if (bitset(EF_RESPONSE, e->e_flags)) + name = "[RESPONSE]"; + else if ((name = macvalue('_', e)) != NULL) + ; + else if (RealHostName == NULL) + name = "localhost"; + else if (RealHostName[0] == '[') + name = RealHostName; + else + { + name = hbuf; + (void) sprintf(hbuf, "%.80s", RealHostName); + if (RealHostAddr.sa.sa_family != 0) + { + p = &hbuf[strlen(hbuf)]; + (void) sprintf(p, " (%.100s)", + anynet_ntoa(&RealHostAddr)); + } + } + + /* some versions of syslog only take 5 printf args */ +# if (SYSLOG_BUFSIZE) >= 256 + sbp = sbuf; + sprintf(sbp, "from=%.200s, size=%ld, class=%d, pri=%ld, nrcpts=%d", + e->e_from.q_paddr == NULL ? "<NONE>" : e->e_from.q_paddr, + e->e_msgsize, e->e_class, e->e_msgpriority, e->e_nrcpts); + sbp += strlen(sbp); + if (msgid != NULL) + { + sprintf(sbp, ", msgid=%.100s", mbuf); + sbp += strlen(sbp); + } + if (e->e_bodytype != NULL) + { + (void) sprintf(sbp, ", bodytype=%.20s", e->e_bodytype); + sbp += strlen(sbp); + } + p = macvalue('r', e); + if (p != NULL) + (void) sprintf(sbp, ", proto=%.20s", p); + syslog(LOG_INFO, "%s: %.850s, relay=%.100s", + e->e_id, sbuf, name); + +# else /* short syslog buffer */ + + syslog(LOG_INFO, "%s: from=%s", + e->e_id, e->e_from.q_paddr == NULL ? "<NONE>" : + shortenstring(e->e_from.q_paddr, 83)); + syslog(LOG_INFO, "%s: size=%ld, class=%ld, pri=%ld, nrcpts=%d", + e->e_id, e->e_msgsize, e->e_class, + e->e_msgpriority, e->e_nrcpts); + if (msgid != NULL) + syslog(LOG_INFO, "%s: msgid=%s", + e->e_id, shortenstring(mbuf, 83)); + sbp = sbuf; + sprintf(sbp, "%s:", e->e_id); + sbp += strlen(sbp); + if (e->e_bodytype != NULL) + { + sprintf(sbp, " bodytype=%.20s,", e->e_bodytype); + sbp += strlen(sbp); + } + p = macvalue('r', e); + if (p != NULL) + { + sprintf(sbp, " proto=%.20s,", p); + sbp += strlen(sbp); + } + syslog(LOG_INFO, "%.400s relay=%.100s", sbuf, name); +# endif +# endif +} +/* +** PRIENCODE -- encode external priority names into internal values. +** +** Parameters: +** p -- priority in ascii. +** +** Returns: +** priority as a numeric level. +** +** Side Effects: +** none. +*/ + +int +priencode(p) + char *p; +{ + register int i; + + for (i = 0; i < NumPriorities; i++) + { + if (!strcasecmp(p, Priorities[i].pri_name)) + return (Priorities[i].pri_val); + } + + /* unknown priority */ + return (0); +} +/* +** CRACKADDR -- parse an address and turn it into a macro +** +** This doesn't actually parse the address -- it just extracts +** it and replaces it with "$g". The parse is totally ad hoc +** and isn't even guaranteed to leave something syntactically +** identical to what it started with. However, it does leave +** something semantically identical. +** +** This algorithm has been cleaned up to handle a wider range +** of cases -- notably quoted and backslash escaped strings. +** This modification makes it substantially better at preserving +** the original syntax. +** +** Parameters: +** addr -- the address to be cracked. +** +** Returns: +** a pointer to the new version. +** +** Side Effects: +** none. +** +** Warning: +** The return value is saved in local storage and should +** be copied if it is to be reused. +*/ + +char * +crackaddr(addr) + register char *addr; +{ + register char *p; + register char c; + int cmtlev; + int realcmtlev; + int anglelev, realanglelev; + int copylev; + bool qmode; + bool realqmode; + bool skipping; + bool putgmac = FALSE; + bool quoteit = FALSE; + bool gotangle = FALSE; + bool gotcolon = FALSE; + register char *bp; + char *buflim; + char *bufhead; + char *addrhead; + static char buf[MAXNAME + 1]; + + if (tTd(33, 1)) + printf("crackaddr(%s)\n", addr); + + /* strip leading spaces */ + while (*addr != '\0' && isascii(*addr) && isspace(*addr)) + addr++; + + /* + ** Start by assuming we have no angle brackets. This will be + ** adjusted later if we find them. + */ + + bp = bufhead = buf; + buflim = &buf[sizeof buf - 5]; + p = addrhead = addr; + copylev = anglelev = realanglelev = cmtlev = realcmtlev = 0; + qmode = realqmode = FALSE; + + while ((c = *p++) != '\0') + { + /* + ** If the buffer is overful, go into a special "skipping" + ** mode that tries to keep legal syntax but doesn't actually + ** output things. + */ + + skipping = bp >= buflim; + + if (copylev > 0 && !skipping) + *bp++ = c; + + /* check for backslash escapes */ + if (c == '\\') + { + /* arrange to quote the address */ + if (cmtlev <= 0 && !qmode) + quoteit = TRUE; + + if ((c = *p++) == '\0') + { + /* too far */ + p--; + goto putg; + } + if (copylev > 0 && !skipping) + *bp++ = c; + goto putg; + } + + /* check for quoted strings */ + if (c == '"' && cmtlev <= 0) + { + qmode = !qmode; + if (copylev > 0 && !skipping) + realqmode = !realqmode; + continue; + } + if (qmode) + goto putg; + + /* check for comments */ + if (c == '(') + { + cmtlev++; + + /* allow space for closing paren */ + if (!skipping) + { + buflim--; + realcmtlev++; + if (copylev++ <= 0) + { + *bp++ = ' '; + *bp++ = c; + } + } + } + if (cmtlev > 0) + { + if (c == ')') + { + cmtlev--; + copylev--; + if (!skipping) + { + realcmtlev--; + buflim++; + } + } + continue; + } + else if (c == ')') + { + /* syntax error: unmatched ) */ + if (copylev > 0 && !skipping) + bp--; + } + + /* check for group: list; syntax */ + if (c == ':' && anglelev <= 0 && !gotcolon && !ColonOkInAddr) + { + register char *q; + + if (*p == ':') + { + /* special case -- :: syntax */ + if (cmtlev <= 0 && !qmode) + quoteit = TRUE; + if (copylev > 0 && !skipping) + { + *bp++ = c; + *bp++ = c; + } + p++; + goto putg; + } + + gotcolon = TRUE; + + bp = bufhead; + if (quoteit) + { + *bp++ = '"'; + + /* back up over the ':' and any spaces */ + --p; + while (isascii(*--p) && isspace(*p)) + continue; + p++; + } + for (q = addrhead; q < p; ) + { + c = *q++; + if (bp < buflim) + { + if (quoteit && c == '"') + *bp++ = '\\'; + *bp++ = c; + } + } + if (quoteit) + { + if (bp == &bufhead[1]) + bp--; + else + *bp++ = '"'; + while ((c = *p++) != ':') + { + if (bp < buflim) + *bp++ = c; + } + *bp++ = c; + } + + /* any trailing white space is part of group: */ + while (isascii(*p) && isspace(*p) && bp < buflim) + *bp++ = *p++; + copylev = 0; + putgmac = quoteit = FALSE; + bufhead = bp; + addrhead = p; + continue; + } + + if (c == ';' && copylev <= 0 && !ColonOkInAddr) + { + if (bp < buflim) + *bp++ = c; + } + + /* check for characters that may have to be quoted */ + if (strchr(MustQuoteChars, c) != NULL) + { + /* + ** If these occur as the phrase part of a <> + ** construct, but are not inside of () or already + ** quoted, they will have to be quoted. Note that + ** now (but don't actually do the quoting). + */ + + if (cmtlev <= 0 && !qmode) + quoteit = TRUE; + } + + /* check for angle brackets */ + if (c == '<') + { + register char *q; + + /* assume first of two angles is bogus */ + if (gotangle) + quoteit = TRUE; + gotangle = TRUE; + + /* oops -- have to change our mind */ + anglelev = 1; + if (!skipping) + realanglelev = 1; + + bp = bufhead; + if (quoteit) + { + *bp++ = '"'; + + /* back up over the '<' and any spaces */ + --p; + while (isascii(*--p) && isspace(*p)) + continue; + p++; + } + for (q = addrhead; q < p; ) + { + c = *q++; + if (bp < buflim) + { + if (quoteit && c == '"') + *bp++ = '\\'; + *bp++ = c; + } + } + if (quoteit) + { + if (bp == &buf[1]) + bp--; + else + *bp++ = '"'; + while ((c = *p++) != '<') + { + if (bp < buflim) + *bp++ = c; + } + *bp++ = c; + } + copylev = 0; + putgmac = quoteit = FALSE; + continue; + } + + if (c == '>') + { + if (anglelev > 0) + { + anglelev--; + if (!skipping) + { + realanglelev--; + buflim++; + } + } + else if (!skipping) + { + /* syntax error: unmatched > */ + if (copylev > 0) + bp--; + quoteit = TRUE; + continue; + } + if (copylev++ <= 0) + *bp++ = c; + continue; + } + + /* must be a real address character */ + putg: + if (copylev <= 0 && !putgmac) + { + *bp++ = MACROEXPAND; + *bp++ = 'g'; + putgmac = TRUE; + } + } + + /* repair any syntactic damage */ + if (realqmode) + *bp++ = '"'; + while (realcmtlev-- > 0) + *bp++ = ')'; + while (realanglelev-- > 0) + *bp++ = '>'; + *bp++ = '\0'; + + if (tTd(33, 1)) + printf("crackaddr=>`%s'\n", buf); + + return (buf); +} +/* +** PUTHEADER -- put the header part of a message from the in-core copy +** +** Parameters: +** mci -- the connection information. +** h -- the header to put. +** e -- envelope to use. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +/* + * Macro for fast max (not available in e.g. DG/UX, 386/ix). + */ +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +void +putheader(mci, h, e) + register MCI *mci; + register HDR *h; + register ENVELOPE *e; +{ + char buf[MAX(MAXLINE,BUFSIZ)]; + char obuf[MAXLINE]; + + if (tTd(34, 1)) + printf("--- putheader, mailer = %s ---\n", + mci->mci_mailer->m_name); + + mci->mci_flags |= MCIF_INHEADER; + for (; h != NULL; h = h->h_link) + { + register char *p = h->h_value; + extern bool bitintersect(); + + if (tTd(34, 11)) + { + printf(" %s: ", h->h_field); + xputs(p); + } + + /* suppress Content-Transfer-Encoding: if we are MIMEing */ + if (bitset(H_CTE, h->h_flags) && + bitset(MCIF_CVT8TO7|MCIF_INMIME, mci->mci_flags)) + { + if (tTd(34, 11)) + printf(" (skipped (content-transfer-encoding))\n"); + continue; + } + + if (bitset(MCIF_INMIME, mci->mci_flags)) + { + if (tTd(34, 11)) + printf("\n"); + goto vanilla; + } + + if (bitset(H_CHECK|H_ACHECK, h->h_flags) && + !bitintersect(h->h_mflags, mci->mci_mailer->m_flags)) + { + if (tTd(34, 11)) + printf(" (skipped)\n"); + continue; + } + + /* handle Resent-... headers specially */ + if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags)) + { + if (tTd(34, 11)) + printf(" (skipped (resent))\n"); + continue; + } + + /* suppress return receipts if requested */ + if (bitset(H_RECEIPTTO, h->h_flags) && + bitset(EF_NORECEIPT, e->e_flags)) + { + if (tTd(34, 11)) + printf(" (skipped (receipt))\n"); + continue; + } + + /* macro expand value if generated internally */ + if (bitset(H_DEFAULT, h->h_flags)) + { + expand(p, buf, sizeof buf, e); + p = buf; + if (p == NULL || *p == '\0') + { + if (tTd(34, 11)) + printf(" (skipped -- null value)\n"); + continue; + } + } + + if (bitset(H_BCC, h->h_flags)) + { + /* Bcc: field -- either truncate or delete */ + if (bitset(EF_DELETE_BCC, e->e_flags)) + { + if (tTd(34, 11)) + printf(" (skipped -- bcc)\n"); + } + else + { + /* no other recipient headers: truncate value */ + (void) sprintf(obuf, "%s:", h->h_field); + putline(obuf, mci); + } + continue; + } + + if (tTd(34, 11)) + printf("\n"); + + if (bitset(H_FROM|H_RCPT, h->h_flags)) + { + /* address field */ + bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags); + + if (bitset(H_FROM, h->h_flags)) + oldstyle = FALSE; + commaize(h, p, oldstyle, mci, e); + } + else + { + /* vanilla header line */ + register char *nlp; + register char *obp; + +vanilla: + (void) sprintf(obuf, "%.200s: ", h->h_field); + obp = obuf + strlen(obuf); + while ((nlp = strchr(p, '\n')) != NULL) + { + + *nlp = '\0'; + sprintf(obp, "%.*s", + sizeof obuf - (obp - obuf) - 1, p); + *nlp = '\n'; + putline(obuf, mci); + p = ++nlp; + obp = obuf; + } + sprintf(obp, "%.*s", sizeof obuf - (obp - obuf) - 1, p); + putline(obuf, mci); + } + } + + /* + ** If we are converting this to a MIME message, add the + ** MIME headers. + */ + +#if MIME8TO7 + if (bitset(MM_MIME8BIT, MimeMode) && + bitset(EF_HAS8BIT, e->e_flags) && + !bitset(EF_DONT_MIME, e->e_flags) && + !bitnset(M_8BITS, mci->mci_mailer->m_flags) && + !bitset(MCIF_CVT8TO7, mci->mci_flags)) + { + if (hvalue("MIME-Version", e->e_header) == NULL) + putline("MIME-Version: 1.0", mci); + if (hvalue("Content-Type", e->e_header) == NULL) + { + sprintf(obuf, "Content-Type: text/plain; charset=%s", + defcharset(e)); + putline(obuf, mci); + } + if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL) + putline("Content-Transfer-Encoding: 8bit", mci); + } +#endif +} +/* +** COMMAIZE -- output a header field, making a comma-translated list. +** +** Parameters: +** h -- the header field to output. +** p -- the value to put in it. +** oldstyle -- TRUE if this is an old style header. +** mci -- the connection information. +** e -- the envelope containing the message. +** +** Returns: +** none. +** +** Side Effects: +** outputs "p" to file "fp". +*/ + +void +commaize(h, p, oldstyle, mci, e) + register HDR *h; + register char *p; + bool oldstyle; + register MCI *mci; + register ENVELOPE *e; +{ + register char *obp; + int opos; + int omax; + bool firstone = TRUE; + char obuf[MAXLINE + 3]; + + /* + ** Output the address list translated by the + ** mailer and with commas. + */ + + if (tTd(14, 2)) + printf("commaize(%s: %s)\n", h->h_field, p); + + obp = obuf; + (void) sprintf(obp, "%.200s: ", h->h_field); + opos = strlen(h->h_field) + 2; + obp += opos; + omax = mci->mci_mailer->m_linelimit - 2; + if (omax < 0 || omax > 78) + omax = 78; + + /* + ** Run through the list of values. + */ + + while (*p != '\0') + { + register char *name; + register int c; + char savechar; + int flags; + auto int stat; + + /* + ** Find the end of the name. New style names + ** end with a comma, old style names end with + ** a space character. However, spaces do not + ** necessarily delimit an old-style name -- at + ** signs mean keep going. + */ + + /* find end of name */ + while ((isascii(*p) && isspace(*p)) || *p == ',') + p++; + name = p; + for (;;) + { + auto char *oldp; + char pvpbuf[PSBUFSIZE]; + + (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf, + sizeof pvpbuf, &oldp, NULL); + p = oldp; + + /* look to see if we have an at sign */ + while (*p != '\0' && isascii(*p) && isspace(*p)) + p++; + + if (*p != '@') + { + p = oldp; + break; + } + p += *p == '@' ? 1 : 2; + while (*p != '\0' && isascii(*p) && isspace(*p)) + p++; + } + /* at the end of one complete name */ + + /* strip off trailing white space */ + while (p >= name && + ((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0')) + p--; + if (++p == name) + continue; + savechar = *p; + *p = '\0'; + + /* translate the name to be relative */ + flags = RF_HEADERADDR|RF_ADDDOMAIN; + if (bitset(H_FROM, h->h_flags)) + flags |= RF_SENDERADDR; +#if USERDB + else if (e->e_from.q_mailer != NULL && + bitnset(M_UDBRECIPIENT, e->e_from.q_mailer->m_flags)) + { + extern char *udbsender(); + char *q; + + q = udbsender(name); + if (q != NULL) + name = q; + } +#endif + stat = EX_OK; + name = remotename(name, mci->mci_mailer, flags, &stat, e); + if (*name == '\0') + { + *p = savechar; + continue; + } + + /* output the name with nice formatting */ + opos += strlen(name); + if (!firstone) + opos += 2; + if (opos > omax && !firstone) + { + (void) strcpy(obp, ",\n"); + putline(obuf, mci); + obp = obuf; + (void) strcpy(obp, " "); + opos = strlen(obp); + obp += opos; + opos += strlen(name); + } + else if (!firstone) + { + (void) strcpy(obp, ", "); + obp += 2; + } + + while ((c = *name++) != '\0' && obp < &obuf[MAXLINE]) + *obp++ = c; + firstone = FALSE; + *p = savechar; + } + (void) strcpy(obp, "\n"); + putline(obuf, mci); +} +/* +** COPYHEADER -- copy header list +** +** This routine is the equivalent of newstr for header lists +** +** Parameters: +** header -- list of header structures to copy. +** +** Returns: +** a copy of 'header'. +** +** Side Effects: +** none. +*/ + +HDR * +copyheader(header) + register HDR *header; +{ + register HDR *newhdr; + HDR *ret; + register HDR **tail = &ret; + + while (header != NULL) + { + newhdr = (HDR *) xalloc(sizeof(HDR)); + STRUCTCOPY(*header, *newhdr); + *tail = newhdr; + tail = &newhdr->h_link; + header = header->h_link; + } + *tail = NULL; + + return ret; +} diff --git a/usr.sbin/sendmail/src/macro.c b/usr.sbin/sendmail/src/macro.c new file mode 100644 index 000000000000..94ef834bb082 --- /dev/null +++ b/usr.sbin/sendmail/src/macro.c @@ -0,0 +1,441 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)macro.c 8.13 (Berkeley) 7/10/95"; +#endif /* not lint */ + +# include "sendmail.h" + +char *MacroName[256]; /* macro id to name table */ +int NextMacroId = 0240; /* codes for long named macros */ + + +/* +** EXPAND -- macro expand a string using $x escapes. +** +** Parameters: +** s -- the string to expand. +** buf -- the place to put the expansion. +** bufsize -- the size of the buffer. +** e -- envelope in which to work. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +void +expand(s, buf, bufsize, e) + register char *s; + register char *buf; + size_t bufsize; + register ENVELOPE *e; +{ + register char *xp; + register char *q; + bool skipping; /* set if conditionally skipping output */ + bool recurse = FALSE; /* set if recursion required */ + int i; + int iflev; /* if nesting level */ + char xbuf[BUFSIZ]; + + if (tTd(35, 24)) + { + printf("expand("); + xputs(s); + printf(")\n"); + } + + skipping = FALSE; + iflev = 0; + if (s == NULL) + s = ""; + for (xp = xbuf; *s != '\0'; s++) + { + int c; + + /* + ** Check for non-ordinary (special?) character. + ** 'q' will be the interpolated quantity. + */ + + q = NULL; + c = *s; + switch (c & 0377) + { + case CONDIF: /* see if var set */ + c = *++s; + if (skipping) + iflev++; + else + skipping = macvalue(c, e) == NULL; + continue; + + case CONDELSE: /* change state of skipping */ + if (iflev == 0) + skipping = !skipping; + continue; + + case CONDFI: /* stop skipping */ + if (iflev == 0) + skipping = FALSE; + if (skipping) + iflev--; + continue; + + case MACROEXPAND: /* macro interpolation */ + c = *++s & 0377; + if (c != '\0') + q = macvalue(c, e); + else + { + s--; + q = NULL; + } + if (q == NULL) + continue; + break; + } + + /* + ** Interpolate q or output one character + */ + + if (skipping || xp >= &xbuf[sizeof xbuf]) + continue; + if (q == NULL) + *xp++ = c; + else + { + /* copy to end of q or max space remaining in buf */ + while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1]) + { + /* check for any sendmail metacharacters */ + if ((c & 0340) == 0200) + recurse = TRUE; + *xp++ = c; + } + } + } + *xp = '\0'; + + if (tTd(35, 24)) + { + printf("expand ==> "); + xputs(xbuf); + printf("\n"); + } + + /* recurse as appropriate */ + if (recurse) + { + expand(xbuf, buf, bufsize, e); + return; + } + + /* copy results out */ + i = xp - xbuf; + if (i >= bufsize) + i = bufsize - 1; + bcopy(xbuf, buf, i); + buf[i] = '\0'; +} +/* +** DEFINE -- define a macro. +** +** this would be better done using a #define macro. +** +** Parameters: +** n -- the macro name. +** v -- the macro value. +** e -- the envelope to store the definition in. +** +** Returns: +** none. +** +** Side Effects: +** e->e_macro[n] is defined. +** +** Notes: +** There is one macro for each ASCII character, +** although they are not all used. The currently +** defined macros are: +** +** $a date in ARPANET format (preferring the Date: line +** of the message) +** $b the current date (as opposed to the date as found +** the message) in ARPANET format +** $c hop count +** $d (current) date in UNIX (ctime) format +** $e the SMTP entry message+ +** $f raw from address +** $g translated from address +** $h to host +** $i queue id +** $j official SMTP hostname, used in messages+ +** $k UUCP node name +** $l UNIX-style from line+ +** $m The domain part of our full name. +** $n name of sendmail ("MAILER-DAEMON" on local +** net typically)+ +** $o delimiters ("operators") for address tokens+ +** $p my process id in decimal +** $q the string that becomes an address -- this is +** normally used to combine $g & $x. +** $r protocol used to talk to sender +** $s sender's host name +** $t the current time in seconds since 1/1/1970 +** $u to user +** $v version number of sendmail +** $w our host name (if it can be determined) +** $x signature (full name) of from person +** $y the tty id of our terminal +** $z home directory of to person +** $_ RFC1413 authenticated sender address +** +** Macros marked with + must be defined in the +** configuration file and are used internally, but +** are not set. +** +** There are also some macros that can be used +** arbitrarily to make the configuration file +** cleaner. In general all upper-case letters +** are available. +*/ + +void +define(n, v, e) + int n; + char *v; + register ENVELOPE *e; +{ + if (tTd(35, 9)) + { + printf("%sdefine(%s as ", + (e->e_macro[n & 0377] == NULL) ? "" : "re", macname(n)); + xputs(v); + printf(")\n"); + } + e->e_macro[n & 0377] = v; +} +/* +** MACVALUE -- return uninterpreted value of a macro. +** +** Parameters: +** n -- the name of the macro. +** +** Returns: +** The value of n. +** +** Side Effects: +** none. +*/ + +char * +macvalue(n, e) + int n; + register ENVELOPE *e; +{ + n &= 0377; + while (e != NULL) + { + register char *p = e->e_macro[n]; + + if (p != NULL) + return (p); + e = e->e_parent; + } + return (NULL); +} +/* +** MACNAME -- return the name of a macro given its internal id +** +** Parameter: +** n -- the id of the macro +** +** Returns: +** The name of n. +** +** Side Effects: +** none. +*/ + +char * +macname(n) + int n; +{ + static char mbuf[2]; + + n &= 0377; + if (bitset(0200, n)) + { + char *p = MacroName[n]; + + if (p != NULL) + return p; + return "***UNDEFINED MACRO***"; + } + mbuf[0] = n; + mbuf[1] = '\0'; + return mbuf; +} +/* +** MACID -- return id of macro identified by its name +** +** Parameters: +** p -- pointer to name string -- either a single +** character or {name}. +** ep -- filled in with the pointer to the byte +** after the name. +** +** Returns: +** The internal id code for this macro. This will +** fit into a single byte. +** +** Side Effects: +** If this is a new macro name, a new id is allocated. +*/ + +int +macid(p, ep) + register char *p; + char **ep; +{ + int mid; + register char *bp; + char mbuf[21]; + + if (tTd(35, 14)) + { + printf("macid("); + xputs(p); + printf(") => "); + } + + if (*p == '\0' || (p[0] == '{' && p[1] == '}')) + { + syserr("Name required for macro/class"); + if (ep != NULL) + *ep = p; + if (tTd(35, 14)) + printf("NULL\n"); + return '\0'; + } + if (*p != '{') + { + /* the macro is its own code */ + if (ep != NULL) + *ep = p + 1; + if (tTd(35, 14)) + printf("%c\n", *p); + return *p; + } + bp = mbuf; + while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof mbuf]) + { + if (isascii(*p) && (isalnum(*p) || *p == '_')) + *bp++ = *p; + else + syserr("Invalid macro/class character %c", *p); + } + *bp = '\0'; + mid = -1; + if (*p == '\0') + { + syserr("Unbalanced { on %s", mbuf); /* missing } */ + } + else if (*p != '}') + { + syserr("Macro/class name ({%s}) too long (%d chars max)", + mbuf, sizeof mbuf - 1); + } + else if (mbuf[1] == '\0') + { + /* ${x} == $x */ + mid = mbuf[0]; + p++; + } + else + { + register STAB *s; + + s = stab(mbuf, ST_MACRO, ST_ENTER); + if (s->s_macro != 0) + mid = s->s_macro; + else + { + if (NextMacroId > 0377) + { + syserr("Macro/class {%s}: too many long names", mbuf); + s->s_macro = -1; + } + else + { + MacroName[NextMacroId] = s->s_name; + s->s_macro = mid = NextMacroId++; + } + } + p++; + } + if (ep != NULL) + *ep = p; + if (tTd(35, 14)) + printf("0x%x\n", mid); + return mid; +} +/* +** WORDINCLASS -- tell if a word is in a specific class +** +** Parameters: +** str -- the name of the word to look up. +** cl -- the class name. +** +** Returns: +** TRUE if str can be found in cl. +** FALSE otherwise. +*/ + +bool +wordinclass(str, cl) + char *str; + int cl; +{ + register STAB *s; + + s = stab(str, ST_CLASS, ST_FIND); + return s != NULL && bitnset(cl & 0xff, s->s_class); +} diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c new file mode 100644 index 000000000000..5e352f2b9fba --- /dev/null +++ b/usr.sbin/sendmail/src/main.c @@ -0,0 +1,2113 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)main.c 8.162 (Berkeley) 11/18/95"; +#endif /* not lint */ + +#define _DEFINE + +#include "sendmail.h" +#if NAMED_BIND +#include <resolv.h> +#endif + +# ifdef lint +char edata, end; +# endif /* lint */ + +/* +** SENDMAIL -- Post mail to a set of destinations. +** +** This is the basic mail router. All user mail programs should +** call this routine to actually deliver mail. Sendmail in +** turn calls a bunch of mail servers that do the real work of +** delivering the mail. +** +** Sendmail is driven by tables read in from /usr/lib/sendmail.cf +** (read by readcf.c). Some more static configuration info, +** including some code that you may want to tailor for your +** installation, is in conf.c. You may also want to touch +** daemon.c (if you have some other IPC mechanism), acct.c +** (to change your accounting), names.c (to adjust the name +** server mechanism). +** +** Usage: +** /usr/lib/sendmail [flags] addr ... +** +** See the associated documentation for details. +** +** Author: +** Eric Allman, UCB/INGRES (until 10/81) +** Britton-Lee, Inc., purveyors of fine +** database computers (from 11/81) +** Now back at UCB at the Mammoth project. +** The support of the INGRES Project and Britton-Lee is +** gratefully acknowledged. Britton-Lee in +** particular had absolutely nothing to gain from +** my involvement in this project. +*/ + + +int NextMailer; /* "free" index into Mailer struct */ +char *FullName; /* sender's full name */ +ENVELOPE BlankEnvelope; /* a "blank" envelope */ +ENVELOPE MainEnvelope; /* the envelope around the basic letter */ +ADDRESS NullAddress = /* a null address */ + { "", "", NULL, "" }; +char *CommandLineArgs; /* command line args for pid file */ +bool Warn_Q_option = FALSE; /* warn about Q option use */ +char **SaveArgv; /* argument vector for re-execing */ + +static void obsolete(); + +#ifdef DAEMON +#ifndef SMTP +ERROR %%%% Cannot have daemon mode without SMTP %%%% ERROR +#endif /* SMTP */ +#endif /* DAEMON */ + +#define MAXCONFIGLEVEL 6 /* highest config version level known */ + +int +main(argc, argv, envp) + int argc; + char **argv; + char **envp; +{ + register char *p; + char **av; + extern char Version[]; + char *ep, *from; + typedef int (*fnptr)(); + STAB *st; + register int i; + int j; + bool queuemode = FALSE; /* process queue requests */ + bool safecf = TRUE; + bool warn_C_flag = FALSE; + char warn_f_flag = '\0'; + static bool reenter = FALSE; + struct passwd *pw; + struct stat stb; + struct hostent *hp; + char jbuf[MAXHOSTNAMELEN]; /* holds MyHostName */ + static char rnamebuf[MAXNAME]; /* holds RealUserName */ + extern int DtableSize; + extern int optind; + extern int opterr; + extern time_t convtime(); + extern void intsig(); + extern struct hostent *myhostname(); + extern char *arpadate(); + extern char *getauthinfo(); + extern char *getcfname(); + extern char *optarg; + extern char **environ; + extern void sigusr1(); + extern void sighup(); + extern void initmacros __P((ENVELOPE *)); + + /* + ** Check to see if we reentered. + ** This would normally happen if e_putheader or e_putbody + ** were NULL when invoked. + */ + + if (reenter) + { + syserr("main: reentered!"); + abort(); + } + reenter = TRUE; + + /* do machine-dependent initializations */ + init_md(argc, argv); + +#ifdef SIGUSR1 + /* arrange to dump state on user-1 signal */ + setsignal(SIGUSR1, sigusr1); +#endif + + /* in 4.4BSD, the table can be huge; impose a reasonable limit */ + DtableSize = getdtsize(); + if (DtableSize > 256) + DtableSize = 256; + + /* + ** Be sure we have enough file descriptors. + ** But also be sure that 0, 1, & 2 are open. + */ + + i = open("/dev/null", O_RDWR, 0); + if (fstat(STDIN_FILENO, &stb) < 0 && errno != EOPNOTSUPP) + (void) dup2(i, STDIN_FILENO); + if (fstat(STDOUT_FILENO, &stb) < 0 && errno != EOPNOTSUPP) + (void) dup2(i, STDOUT_FILENO); + if (fstat(STDERR_FILENO, &stb) < 0 && errno != EOPNOTSUPP) + (void) dup2(i, STDERR_FILENO); + if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO) + (void) close(i); + + i = DtableSize; + while (--i > 0) + { + if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO) + (void) close(i); + } + errno = 0; + +#ifdef LOG +# ifdef LOG_MAIL + openlog("sendmail", LOG_PID, LOG_MAIL); +# else + openlog("sendmail", LOG_PID); +# endif +#endif + + tTsetup(tTdvect, sizeof tTdvect, "0-99.1"); + + /* set up the blank envelope */ + BlankEnvelope.e_puthdr = putheader; + BlankEnvelope.e_putbody = putbody; + BlankEnvelope.e_xfp = NULL; + STRUCTCOPY(NullAddress, BlankEnvelope.e_from); + CurEnv = &BlankEnvelope; + STRUCTCOPY(NullAddress, MainEnvelope.e_from); + + /* + ** Set default values for variables. + ** These cannot be in initialized data space. + */ + + setdefaults(&BlankEnvelope); + + RealUid = getuid(); + RealGid = getgid(); + + pw = sm_getpwuid(RealUid); + if (pw != NULL) + (void) strcpy(rnamebuf, pw->pw_name); + else + (void) sprintf(rnamebuf, "Unknown UID %d", RealUid); + RealUserName = rnamebuf; + + /* save command line arguments */ + i = 0; + for (av = argv; *av != NULL; ) + i += strlen(*av++) + 1; + SaveArgv = (char **) xalloc(sizeof (char *) * (argc + 1)); + CommandLineArgs = xalloc(i); + p = CommandLineArgs; + for (av = argv, i = 0; *av != NULL; ) + { + SaveArgv[i++] = newstr(*av); + if (av != argv) + *p++ = ' '; + strcpy(p, *av++); + p += strlen(p); + } + SaveArgv[i] = NULL; + + /* Handle any non-getoptable constructions. */ + obsolete(argv); + + /* + ** Do a quick prescan of the argument list. + */ + +#if defined(__osf__) || defined(_AIX3) +# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mnO:o:p:q:r:sTtvX:x" +#endif +#if defined(sony_news) +# define OPTIONS "B:b:C:cd:E:e:F:f:h:IiJ:M:mnO:o:p:q:r:sTtvX:" +#endif +#ifndef OPTIONS +# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mnO:o:p:q:r:sTtvX:" +#endif + opterr = 0; + while ((j = getopt(argc, argv, OPTIONS)) != EOF) + { + switch (j) + { + case 'd': + tTflag(optarg); + setbuf(stdout, (char *) NULL); + break; + } + } + opterr = 1; + + if (tTd(0, 1)) + { + int ll; + extern char *CompileOptions[]; + + printf("Version %s\n Compiled with:", Version); + av = CompileOptions; + ll = 7; + while (*av != NULL) + { + if (ll + strlen(*av) > 63) + { + putchar('\n'); + ll = 0; + } + if (ll == 0) + { + putchar('\t'); + putchar('\t'); + } + else + putchar(' '); + printf("%s", *av); + ll += strlen(*av++) + 1; + } + putchar('\n'); + } + if (tTd(0, 10)) + { + int ll; + extern char *OsCompileOptions[]; + + printf(" OS Defines:", Version); + av = OsCompileOptions; + ll = 7; + while (*av != NULL) + { + if (ll + strlen(*av) > 63) + { + putchar('\n'); + ll = 0; + } + if (ll == 0) + { + putchar('\t'); + putchar('\t'); + } + else + putchar(' '); + printf("%s", *av); + ll += strlen(*av++) + 1; + } + putchar('\n'); +#ifdef _PATH_UNIX + printf("Kernel symbols:\t%s\n", _PATH_UNIX); +#endif + printf(" Config file:\t%s\n", getcfname()); + printf(" Pid file:\t%s\n", PidFile); + } + + InChannel = stdin; + OutChannel = stdout; + + /* initialize for setproctitle */ + initsetproctitle(argc, argv, envp); + + /* prime the child environment */ + setuserenv("AGENT", "sendmail"); + + if (setsignal(SIGINT, SIG_IGN) != SIG_IGN) + (void) setsignal(SIGINT, intsig); + (void) setsignal(SIGTERM, intsig); + (void) setsignal(SIGPIPE, SIG_IGN); + OldUmask = umask(022); + OpMode = MD_DELIVER; + FullName = getenv("NAME"); + +#if NAMED_BIND + if (tTd(8, 8)) + { + res_init(); + _res.options |= RES_DEBUG; + } +#endif + + errno = 0; + from = NULL; + + /* initialize some macros, etc. */ + initmacros(CurEnv); + init_vendor_macros(CurEnv); + + /* version */ + define('v', Version, CurEnv); + + /* hostname */ + hp = myhostname(jbuf, sizeof jbuf); + if (jbuf[0] != '\0') + { + struct utsname utsname; + + if (tTd(0, 4)) + printf("canonical name: %s\n", jbuf); + define('w', newstr(jbuf), CurEnv); /* must be new string */ + define('j', newstr(jbuf), CurEnv); + setclass('w', jbuf); + + p = strchr(jbuf, '.'); + if (p != NULL) + { + if (p[1] != '\0') + { + define('m', newstr(&p[1]), CurEnv); + } + while (p != NULL && strchr(&p[1], '.') != NULL) + { + *p = '\0'; + setclass('w', jbuf); + *p++ = '.'; + p = strchr(p, '.'); + } + } + + if (uname(&utsname) >= 0) + p = utsname.nodename; + else + { + if (tTd(0, 22)) + printf("uname failed (%s)\n", errstring(errno)); + makelower(jbuf); + p = jbuf; + } + if (tTd(0, 4)) + printf(" UUCP nodename: %s\n", p); + p = newstr(p); + define('k', p, CurEnv); + setclass('k', p); + setclass('w', p); + } + if (hp != NULL) + { + for (av = hp->h_aliases; av != NULL && *av != NULL; av++) + { + if (tTd(0, 4)) + printf("\ta.k.a.: %s\n", *av); + setclass('w', *av); + } +#if NETINET + if (hp->h_addrtype == AF_INET && hp->h_length == INADDRSZ) + { + register int i; + + for (i = 0; hp->h_addr_list[i] != NULL; i++) + { + char ipbuf[103]; + + sprintf(ipbuf, "[%.100s]", + inet_ntoa(*((struct in_addr *) hp->h_addr_list[i]))); + if (tTd(0, 4)) + printf("\ta.k.a.: %s\n", ipbuf); + setclass('w', ipbuf); + } + } +#endif + } + + /* probe interfaces and locate any additional names */ + load_if_names(); + + /* current time */ + define('b', arpadate((char *) NULL), CurEnv); + + /* + ** Find our real host name for future logging. + */ + + p = getauthinfo(STDIN_FILENO); + define('_', p, CurEnv); + + /* + ** Crack argv. + */ + + av = argv; + p = strrchr(*av, '/'); + if (p++ == NULL) + p = *av; + if (strcmp(p, "newaliases") == 0) + OpMode = MD_INITALIAS; + else if (strcmp(p, "mailq") == 0) + OpMode = MD_PRINT; + else if (strcmp(p, "smtpd") == 0) + OpMode = MD_DAEMON; + + optind = 1; + while ((j = getopt(argc, argv, OPTIONS)) != EOF) + { + switch (j) + { + case 'b': /* operations mode */ + switch (j = *optarg) + { + case MD_DAEMON: +# ifdef DAEMON + if (RealUid != 0) { + usrerr("Permission denied"); + exit (EX_USAGE); + } + (void) unsetenv("HOSTALIASES"); +# else + usrerr("Daemon mode not implemented"); + ExitStat = EX_USAGE; + break; +# endif /* DAEMON */ + case MD_SMTP: +# ifndef SMTP + usrerr("I don't speak SMTP"); + ExitStat = EX_USAGE; + break; +# endif /* SMTP */ + case MD_DELIVER: + case MD_VERIFY: + case MD_TEST: + case MD_INITALIAS: + case MD_PRINT: + case MD_ARPAFTP: + OpMode = j; + break; + + case MD_FREEZE: + usrerr("Frozen configurations unsupported"); + ExitStat = EX_USAGE; + break; + + default: + usrerr("Invalid operation mode %c", j); + ExitStat = EX_USAGE; + break; + } + break; + + case 'B': /* body type */ + CurEnv->e_bodytype = optarg; + break; + + case 'C': /* select configuration file (already done) */ + if (RealUid != 0) + warn_C_flag = TRUE; + ConfFile = optarg; + endpwent(); + (void) setgid(RealGid); + (void) setuid(RealUid); + safecf = FALSE; + break; + + case 'd': /* debugging -- already done */ + break; + + case 'f': /* from address */ + case 'r': /* obsolete -f flag */ + if (from != NULL) + { + usrerr("More than one \"from\" person"); + ExitStat = EX_USAGE; + break; + } + from = newstr(denlstring(optarg, TRUE, TRUE)); + if (strcmp(RealUserName, from) != 0) + warn_f_flag = j; + break; + + case 'F': /* set full name */ + FullName = newstr(optarg); + break; + + case 'h': /* hop count */ + CurEnv->e_hopcount = strtol(optarg, &ep, 10); + if (*ep) + { + usrerr("Bad hop count (%s)", optarg); + ExitStat = EX_USAGE; + break; + } + break; + + case 'n': /* don't alias */ + NoAlias = TRUE; + break; + + case 'o': /* set option */ + setoption(*optarg, optarg + 1, FALSE, TRUE, CurEnv); + break; + + case 'O': /* set option (long form) */ + setoption(' ', optarg, FALSE, TRUE, CurEnv); + break; + + case 'p': /* set protocol */ + p = strchr(optarg, ':'); + if (p != NULL) + { + *p++ = '\0'; + if (*p != '\0') + { + ep = xalloc(strlen(p) + 1); + cleanstrcpy(ep, p, MAXNAME); + define('s', ep, CurEnv); + } + } + if (*optarg != '\0') + { + ep = xalloc(strlen(optarg) + 1); + cleanstrcpy(ep, optarg, MAXNAME); + define('r', ep, CurEnv); + } + break; + + case 'q': /* run queue files at intervals */ +# ifdef QUEUE + (void) unsetenv("HOSTALIASES"); + FullName = NULL; + queuemode = TRUE; + switch (optarg[0]) + { + case 'I': + QueueLimitId = newstr(&optarg[1]); + break; + + case 'R': + QueueLimitRecipient = newstr(&optarg[1]); + break; + + case 'S': + QueueLimitSender = newstr(&optarg[1]); + break; + + default: + QueueIntvl = convtime(optarg, 'm'); + break; + } +# else /* QUEUE */ + usrerr("I don't know about queues"); + ExitStat = EX_USAGE; +# endif /* QUEUE */ + break; + + case 't': /* read recipients from message */ + GrabTo = TRUE; + break; + + case 'X': /* traffic log file */ + endpwent(); + setgid(RealGid); + setuid(RealUid); + TrafficLogFile = fopen(optarg, "a"); + if (TrafficLogFile == NULL) + { + syserr("cannot open %s", optarg); + break; + } +#ifdef HASSETVBUF + setvbuf(TrafficLogFile, NULL, _IOLBF, 0); +#else + setlinebuf(TrafficLogFile); +#endif + break; + + /* compatibility flags */ + case 'c': /* connect to non-local mailers */ + case 'i': /* don't let dot stop me */ + case 'm': /* send to me too */ + case 'T': /* set timeout interval */ + case 'v': /* give blow-by-blow description */ + setoption(j, "T", FALSE, TRUE, CurEnv); + break; + + case 'e': /* error message disposition */ + case 'M': /* define macro */ + setoption(j, optarg, FALSE, TRUE, CurEnv); + break; + + case 's': /* save From lines in headers */ + setoption('f', "T", FALSE, TRUE, CurEnv); + break; + +# ifdef DBM + case 'I': /* initialize alias DBM file */ + OpMode = MD_INITALIAS; + break; +# endif /* DBM */ + +# if defined(__osf__) || defined(_AIX3) + case 'x': /* random flag that OSF/1 & AIX mailx passes */ + break; +# endif +# if defined(sony_news) + case 'E': + case 'J': /* ignore flags for Japanese code conversion + impremented on Sony NEWS */ + break; +# endif + + default: + ExitStat = EX_USAGE; + finis(); + break; + } + } + av += optind; + + /* + ** Do basic initialization. + ** Read system control file. + ** Extract special fields for local use. + */ + + /* set up ${opMode} for use in config file */ + { + char mbuf[2]; + + mbuf[0] = OpMode; + mbuf[1] = '\0'; + define(MID_OPMODE, newstr(mbuf), CurEnv); + } + +#if XDEBUG + checkfd012("before readcf"); +#endif + vendor_pre_defaults(CurEnv); + readcf(getcfname(), safecf, CurEnv); + vendor_post_defaults(CurEnv); + + /* suppress error printing if errors mailed back or whatever */ + if (CurEnv->e_errormode != EM_PRINT) + HoldErrs = TRUE; + + /* set up the $=m class now, after .cf has a chance to redefine $m */ + expand("\201m", jbuf, sizeof jbuf, CurEnv); + setclass('m', jbuf); + + if (tTd(0, 1)) + { + printf("\n============ SYSTEM IDENTITY (after readcf) ============"); + printf("\n (short domain name) $w = "); + xputs(macvalue('w', CurEnv)); + printf("\n (canonical domain name) $j = "); + xputs(macvalue('j', CurEnv)); + printf("\n (subdomain name) $m = "); + xputs(macvalue('m', CurEnv)); + printf("\n (node name) $k = "); + xputs(macvalue('k', CurEnv)); + printf("\n========================================================\n\n"); + } + + /* + ** Initialize name server if it is going to be used. + */ + +#if NAMED_BIND + if (UseNameServer && !bitset(RES_INIT, _res.options)) + res_init(); +# ifdef RES_NOALIASES + _res.options |= RES_NOALIASES; +# endif +#endif + + /* + ** Do more command line checking -- these are things that + ** have to modify the results of reading the config file. + */ + + /* process authorization warnings from command line */ + if (warn_C_flag) + auth_warning(CurEnv, "Processed by %s with -C %s", + RealUserName, ConfFile); + if (Warn_Q_option) + auth_warning(CurEnv, "Processed from queue %s", QueueDir); + + /* check body type for legality */ + if (CurEnv->e_bodytype == NULL) + /* nothing */ ; + else if (strcasecmp(CurEnv->e_bodytype, "7BIT") == 0) + SevenBitInput = TRUE; + else if (strcasecmp(CurEnv->e_bodytype, "8BITMIME") == 0) + SevenBitInput = FALSE; + else + { + usrerr("Illegal body type %s", CurEnv->e_bodytype); + CurEnv->e_bodytype = NULL; + } + + /* Enforce use of local time (null string overrides this) */ + if (TimeZoneSpec == NULL) + unsetenv("TZ"); + else if (TimeZoneSpec[0] != '\0') + setuserenv("TZ", TimeZoneSpec); + else + setuserenv("TZ", NULL); + tzset(); + + /* check for sane configuration level */ + if (ConfigLevel > MAXCONFIGLEVEL) + { + syserr("Warning: .cf version level (%d) exceeds program functionality (%d)", + ConfigLevel, MAXCONFIGLEVEL); + } + + if (MeToo) + BlankEnvelope.e_flags |= EF_METOO; + + switch (OpMode) + { + case MD_DAEMON: + /* remove things that don't make sense in daemon mode */ + FullName = NULL; + GrabTo = FALSE; + + /* arrange to restart on hangup signal */ + setsignal(SIGHUP, sighup); + break; + + case MD_INITALIAS: + Verbose = TRUE; + /* fall through... */ + + default: + /* arrange to exit cleanly on hangup signal */ + setsignal(SIGHUP, intsig); + break; + } + + /* full names can't have newlines */ + if (FullName != NULL && strchr(FullName, '\n') != NULL) + FullName = newstr(denlstring(FullName, TRUE, TRUE)); + + /* do heuristic mode adjustment */ + if (Verbose) + { + /* turn off noconnect option */ + setoption('c', "F", TRUE, FALSE, CurEnv); + + /* turn on interactive delivery */ + setoption('d', "", TRUE, FALSE, CurEnv); + } + + if (ConfigLevel < 3) + { + UseErrorsTo = TRUE; + } + + /* set options that were previous macros */ + if (SmtpGreeting == NULL) + { + if (ConfigLevel < 7 && (p = macvalue('e', CurEnv)) != NULL) + SmtpGreeting = newstr(p); + else + SmtpGreeting = "\201j Sendmail \201v ready at \201b"; + } + if (UnixFromLine == NULL) + { + if (ConfigLevel < 7 && (p = macvalue('l', CurEnv)) != NULL) + UnixFromLine = newstr(p); + else + UnixFromLine = "From \201g \201d"; + } + + /* our name for SMTP codes */ + expand("\201j", jbuf, sizeof jbuf, CurEnv); + MyHostName = jbuf; + if (strchr(jbuf, '.') == NULL) + message("WARNING: local host name (%s) is not qualified; fix $j in config file", + jbuf); + + /* make certain that this name is part of the $=w class */ + setclass('w', MyHostName); + + /* the indices of built-in mailers */ + st = stab("local", ST_MAILER, ST_FIND); + if (st != NULL) + LocalMailer = st->s_mailer; + else if (OpMode != MD_TEST || !warn_C_flag) + syserr("No local mailer defined"); + + st = stab("prog", ST_MAILER, ST_FIND); + if (st == NULL) + syserr("No prog mailer defined"); + else + { + ProgMailer = st->s_mailer; + clrbitn(M_MUSER, ProgMailer->m_flags); + } + + st = stab("*file*", ST_MAILER, ST_FIND); + if (st == NULL) + syserr("No *file* mailer defined"); + else + { + FileMailer = st->s_mailer; + clrbitn(M_MUSER, FileMailer->m_flags); + } + + st = stab("*include*", ST_MAILER, ST_FIND); + if (st == NULL) + syserr("No *include* mailer defined"); + else + InclMailer = st->s_mailer; + + if (ConfigLevel < 6) + { + /* heuristic tweaking of local mailer for back compat */ + if (LocalMailer != NULL) + { + setbitn(M_ALIASABLE, LocalMailer->m_flags); + setbitn(M_HASPWENT, LocalMailer->m_flags); + setbitn(M_TRYRULESET5, LocalMailer->m_flags); + setbitn(M_CHECKINCLUDE, LocalMailer->m_flags); + setbitn(M_CHECKPROG, LocalMailer->m_flags); + setbitn(M_CHECKFILE, LocalMailer->m_flags); + setbitn(M_CHECKUDB, LocalMailer->m_flags); + } + if (ProgMailer != NULL) + setbitn(M_RUNASRCPT, ProgMailer->m_flags); + if (FileMailer != NULL) + setbitn(M_RUNASRCPT, FileMailer->m_flags); + + /* propogate some envariables into children */ + setuserenv("ISP", NULL); + setuserenv("SYSTYPE", NULL); + } + + /* MIME Content-Types that cannot be transfer encoded */ + setclass('n', "multipart/signed"); + + /* MIME message/* subtypes that can be treated as messages */ + setclass('s', "rfc822"); + + /* MIME Content-Transfer-Encodings that can be encoded */ + setclass('e', "7bit"); + setclass('e', "8bit"); + setclass('e', "binary"); + + /* operate in queue directory */ + if (OpMode != MD_TEST && chdir(QueueDir) < 0) + { + syserr("cannot chdir(%s)", QueueDir); + ExitStat = EX_SOFTWARE; + } + +# ifdef QUEUE + if (queuemode && RealUid != 0 && bitset(PRIV_RESTRICTQRUN, PrivacyFlags)) + { + struct stat stbuf; + + /* check to see if we own the queue directory */ + if (stat(".", &stbuf) < 0) + syserr("main: cannot stat %s", QueueDir); + if (stbuf.st_uid != RealUid) + { + /* nope, really a botch */ + usrerr("You do not have permission to process the queue"); + exit (EX_NOPERM); + } + } +# endif /* QUEUE */ + + /* if we've had errors so far, exit now */ + if (ExitStat != EX_OK && OpMode != MD_TEST) + { + endpwent(); + setuid(RealUid); + exit(ExitStat); + } + +#if XDEBUG + checkfd012("before main() initmaps"); +#endif + + /* + ** Do operation-mode-dependent initialization. + */ + + switch (OpMode) + { + case MD_PRINT: + /* print the queue */ +#ifdef QUEUE + dropenvelope(CurEnv); + printqueue(); + endpwent(); + setuid(RealUid); + exit(EX_OK); +#else /* QUEUE */ + usrerr("No queue to print"); + finis(); +#endif /* QUEUE */ + + case MD_INITALIAS: + /* initialize alias database */ + initmaps(TRUE, CurEnv); + endpwent(); + setuid(RealUid); + exit(EX_OK); + + case MD_DAEMON: + case MD_SMTP: + /* don't open alias database -- done in srvrsmtp */ + break; + + default: + /* open the alias database */ + initmaps(FALSE, CurEnv); + break; + } + + if (tTd(0, 15)) + { + /* print configuration table (or at least part of it) */ + if (tTd(0, 90)) + printrules(); + for (i = 0; i < MAXMAILERS; i++) + { + if (Mailer[i] != NULL) + printmailer(Mailer[i]); + } + } + + /* + ** Switch to the main envelope. + */ + + CurEnv = newenvelope(&MainEnvelope, CurEnv); + MainEnvelope.e_flags = BlankEnvelope.e_flags; + + /* + ** If test mode, read addresses from stdin and process. + */ + + if (OpMode == MD_TEST) + { + char buf[MAXLINE]; + void intindebug(); + + if (isatty(fileno(stdin))) + Verbose = TRUE; + + if (Verbose) + { + printf("ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)\n"); + printf("Enter <ruleset> <address>\n"); + } + if (setjmp(TopFrame) > 0) + printf("\n"); + (void) setsignal(SIGINT, intindebug); + for (;;) + { + extern void testmodeline __P((char *, ENVELOPE *)); + + if (Verbose) + printf("> "); + (void) fflush(stdout); + if (fgets(buf, sizeof buf, stdin) == NULL) + finis(); + p = strchr(buf, '\n'); + if (p != NULL) + *p = '\0'; + if (!Verbose) + printf("> %s\n", buf); + testmodeline(buf, CurEnv); + } + } + +# ifdef QUEUE + /* + ** If collecting stuff from the queue, go start doing that. + */ + + if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0) + { + (void) unsetenv("HOSTALIASES"); + runqueue(FALSE); + finis(); + } +# endif /* QUEUE */ + + /* + ** If a daemon, wait for a request. + ** getrequests will always return in a child. + ** If we should also be processing the queue, start + ** doing it in background. + ** We check for any errors that might have happened + ** during startup. + */ + + if (OpMode == MD_DAEMON || QueueIntvl != 0) + { + char dtype[200]; + + if (!tTd(99, 100)) + { + /* put us in background */ + i = fork(); + if (i < 0) + syserr("daemon: cannot fork"); + if (i != 0) + exit(0); + + /* disconnect from our controlling tty */ + disconnect(2, CurEnv); + } + + dtype[0] = '\0'; + if (OpMode == MD_DAEMON) + strcat(dtype, "+SMTP"); + if (QueueIntvl != 0) + { + strcat(dtype, "+queueing@"); + strcat(dtype, pintvl(QueueIntvl, TRUE)); + } + if (tTd(0, 1)) + strcat(dtype, "+debugging"); + +#ifdef LOG + syslog(LOG_INFO, "starting daemon (%s): %s", Version, dtype + 1); +#endif +#ifdef XLA + xla_create_file(); +#endif + +# ifdef QUEUE + if (queuemode) + { + runqueue(TRUE); + if (OpMode != MD_DAEMON) + for (;;) + pause(); + } +# endif /* QUEUE */ + dropenvelope(CurEnv); + +#ifdef DAEMON + getrequests(); + + /* at this point we are in a child: reset state */ + (void) newenvelope(CurEnv, CurEnv); + + /* + ** Get authentication data + */ + + p = getauthinfo(fileno(InChannel)); + define('_', p, CurEnv); + +#endif /* DAEMON */ + } + +# ifdef SMTP + /* + ** If running SMTP protocol, start collecting and executing + ** commands. This will never return. + */ + + if (OpMode == MD_SMTP || OpMode == MD_DAEMON) + smtp(CurEnv); +# endif /* SMTP */ + + if (OpMode == MD_VERIFY) + { + CurEnv->e_sendmode = SM_VERIFY; + CurEnv->e_errormode = EM_QUIET; + PostMasterCopy = NULL; + } + else + { + /* interactive -- all errors are global */ + CurEnv->e_flags |= EF_GLOBALERRS|EF_LOGSENDER; + } + + /* + ** Do basic system initialization and set the sender + */ + + initsys(CurEnv); + if (warn_f_flag != '\0' && !wordinclass(RealUserName, 't')) + auth_warning(CurEnv, "%s set sender to %s using -%c", + RealUserName, from, warn_f_flag); + setsender(from, CurEnv, NULL, FALSE); + if (macvalue('s', CurEnv) == NULL) + define('s', RealHostName, CurEnv); + + if (*av == NULL && !GrabTo) + { + CurEnv->e_flags |= EF_GLOBALERRS; + usrerr("Recipient names must be specified"); + + /* collect body for UUCP return */ + if (OpMode != MD_VERIFY) + collect(InChannel, FALSE, FALSE, NULL, CurEnv); + finis(); + } + + /* + ** Scan argv and deliver the message to everyone. + */ + + sendtoargv(av, CurEnv); + + /* if we have had errors sofar, arrange a meaningful exit stat */ + if (Errors > 0 && ExitStat == EX_OK) + ExitStat = EX_USAGE; + + /* + ** Read the input mail. + */ + + CurEnv->e_to = NULL; + if (OpMode != MD_VERIFY || GrabTo) + { + CurEnv->e_flags |= EF_GLOBALERRS; + collect(InChannel, FALSE, FALSE, NULL, CurEnv); + } + errno = 0; + + if (tTd(1, 1)) + printf("From person = \"%s\"\n", CurEnv->e_from.q_paddr); + + /* + ** Actually send everything. + ** If verifying, just ack. + */ + + CurEnv->e_from.q_flags |= QDONTSEND; + if (tTd(1, 5)) + { + printf("main: QDONTSEND "); + printaddr(&CurEnv->e_from, FALSE); + } + CurEnv->e_to = NULL; + sendall(CurEnv, SM_DEFAULT); + + /* + ** All done. + ** Don't send return error message if in VERIFY mode. + */ + + finis(); +} + + +void +intindebug() +{ + longjmp(TopFrame, 1); +} + + +/* +** FINIS -- Clean up and exit. +** +** Parameters: +** none +** +** Returns: +** never +** +** Side Effects: +** exits sendmail +*/ + +void +finis() +{ + if (tTd(2, 1)) + { + extern void printenvflags(); + + printf("\n====finis: stat %d e_id=%s e_flags=", + ExitStat, + CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id); + printenvflags(CurEnv); + } + if (tTd(2, 9)) + printopenfds(FALSE); + + /* clean up temp files */ + CurEnv->e_to = NULL; + dropenvelope(CurEnv); + + /* flush any cached connections */ + mci_flush(TRUE, NULL); + +# ifdef XLA + /* clean up extended load average stuff */ + xla_all_end(); +# endif + + /* and exit */ +# ifdef LOG + if (LogLevel > 78) + syslog(LOG_DEBUG, "finis, pid=%d", getpid()); +# endif /* LOG */ + if (ExitStat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET) + ExitStat = EX_OK; + + /* reset uid for process accounting */ + endpwent(); + setuid(RealUid); + + exit(ExitStat); +} +/* +** INTSIG -- clean up on interrupt +** +** This just arranges to exit. It pessimises in that it +** may resend a message. +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Unlocks the current job. +*/ + +void +intsig() +{ + FileName = NULL; + unlockqueue(CurEnv); +#ifdef XLA + xla_all_end(); +#endif + + /* reset uid for process accounting */ + endpwent(); + setuid(RealUid); + + exit(EX_OK); +} +/* +** INITMACROS -- initialize the macro system +** +** This just involves defining some macros that are actually +** used internally as metasymbols to be themselves. +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** initializes several macros to be themselves. +*/ + +struct metamac MetaMacros[] = +{ + /* LHS pattern matching characters */ + '*', MATCHZANY, '+', MATCHANY, '-', MATCHONE, + '=', MATCHCLASS, '~', MATCHNCLASS, + + /* these are RHS metasymbols */ + '#', CANONNET, '@', CANONHOST, ':', CANONUSER, + '>', CALLSUBR, + + /* the conditional operations */ + '?', CONDIF, '|', CONDELSE, '.', CONDFI, + + /* the hostname lookup characters */ + '[', HOSTBEGIN, ']', HOSTEND, + '(', LOOKUPBEGIN, ')', LOOKUPEND, + + /* miscellaneous control characters */ + '&', MACRODEXPAND, + + '\0' +}; + +#define MACBINDING(name, mid) \ + stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \ + MacroName[mid] = name; + +void +initmacros(e) + register ENVELOPE *e; +{ + register struct metamac *m; + register int c; + char buf[5]; + extern char *MacroName[256]; + + for (m = MetaMacros; m->metaname != '\0'; m++) + { + buf[0] = m->metaval; + buf[1] = '\0'; + define(m->metaname, newstr(buf), e); + } + buf[0] = MATCHREPL; + buf[2] = '\0'; + for (c = '0'; c <= '9'; c++) + { + buf[1] = c; + define(c, newstr(buf), e); + } + + /* set defaults for some macros sendmail will use later */ + define('n', "MAILER-DAEMON", e); + + /* set up external names for some internal macros */ + MACBINDING("opMode", MID_OPMODE); + /*XXX should probably add equivalents for all short macros here XXX*/ +} +/* +** DISCONNECT -- remove our connection with any foreground process +** +** Parameters: +** droplev -- how "deeply" we should drop the line. +** 0 -- ignore signals, mail back errors, make sure +** output goes to stdout. +** 1 -- also, make stdout go to transcript. +** 2 -- also, disconnect from controlling terminal +** (only for daemon mode). +** e -- the current envelope. +** +** Returns: +** none +** +** Side Effects: +** Trys to insure that we are immune to vagaries of +** the controlling tty. +*/ + +void +disconnect(droplev, e) + int droplev; + register ENVELOPE *e; +{ + int fd; + + if (tTd(52, 1)) + printf("disconnect: In %d Out %d, e=%x\n", + fileno(InChannel), fileno(OutChannel), e); + if (tTd(52, 100)) + { + printf("don't\n"); + return; + } + + /* be sure we don't get nasty signals */ + (void) setsignal(SIGINT, SIG_IGN); + (void) setsignal(SIGQUIT, SIG_IGN); + + /* we can't communicate with our caller, so.... */ + HoldErrs = TRUE; + CurEnv->e_errormode = EM_MAIL; + Verbose = FALSE; + DisConnected = TRUE; + + /* all input from /dev/null */ + if (InChannel != stdin) + { + (void) fclose(InChannel); + InChannel = stdin; + } + (void) freopen("/dev/null", "r", stdin); + + /* output to the transcript */ + if (OutChannel != stdout) + { + (void) fclose(OutChannel); + OutChannel = stdout; + } + if (droplev > 0) + { + if (e->e_xfp == NULL) + fd = open("/dev/null", O_WRONLY, 0666); + else + fd = fileno(e->e_xfp); + (void) fflush(stdout); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if (e->e_xfp == NULL) + close(fd); + } + + /* drop our controlling TTY completely if possible */ + if (droplev > 1) + { + (void) setsid(); + errno = 0; + } + +#if XDEBUG + checkfd012("disconnect"); +#endif + +# ifdef LOG + if (LogLevel > 71) + syslog(LOG_DEBUG, "in background, pid=%d", getpid()); +# endif /* LOG */ + + errno = 0; +} + +static void +obsolete(argv) + char *argv[]; +{ + register char *ap; + register char *op; + + while ((ap = *++argv) != NULL) + { + /* Return if "--" or not an option of any form. */ + if (ap[0] != '-' || ap[1] == '-') + return; + + /* skip over options that do have a value */ + op = strchr(OPTIONS, ap[1]); + if (op != NULL && *++op == ':' && ap[2] == '\0' && + ap[1] != 'd' && +#if defined(sony_news) + ap[1] != 'E' && ap[1] != 'J' && +#endif + argv[1] != NULL && argv[1][0] != '-') + { + argv++; + continue; + } + + /* If -C doesn't have an argument, use sendmail.cf. */ +#define __DEFPATH "sendmail.cf" + if (ap[1] == 'C' && ap[2] == '\0') + { + *argv = xalloc(sizeof(__DEFPATH) + 2); + argv[0][0] = '-'; + argv[0][1] = 'C'; + (void)strcpy(&argv[0][2], __DEFPATH); + } + + /* If -q doesn't have an argument, run it once. */ + if (ap[1] == 'q' && ap[2] == '\0') + *argv = "-q0"; + + /* if -d doesn't have an argument, use 0-99.1 */ + if (ap[1] == 'd' && ap[2] == '\0') + *argv = "-d0-99.1"; + +# if defined(sony_news) + /* if -E doesn't have an argument, use -EC */ + if (ap[1] == 'E' && ap[2] == '\0') + *argv = "-EC"; + + /* if -J doesn't have an argument, use -JJ */ + if (ap[1] == 'J' && ap[2] == '\0') + *argv = "-JJ"; +# endif + } +} +/* +** AUTH_WARNING -- specify authorization warning +** +** Parameters: +** e -- the current envelope. +** msg -- the text of the message. +** args -- arguments to the message. +** +** Returns: +** none. +*/ + +void +#ifdef __STDC__ +auth_warning(register ENVELOPE *e, const char *msg, ...) +#else +auth_warning(e, msg, va_alist) + register ENVELOPE *e; + const char *msg; + va_dcl +#endif +{ + char buf[MAXLINE]; + VA_LOCAL_DECL + + if (bitset(PRIV_AUTHWARNINGS, PrivacyFlags)) + { + register char *p; + static char hostbuf[48]; + extern struct hostent *myhostname(); + + if (hostbuf[0] == '\0') + (void) myhostname(hostbuf, sizeof hostbuf); + + (void) sprintf(buf, "%s: ", hostbuf); + p = &buf[strlen(buf)]; + VA_START(msg); + vsnprintf(p, sizeof buf - (p - buf), msg, ap); + VA_END; + addheader("X-Authentication-Warning", buf, &e->e_header); +#ifdef LOG + if (LogLevel > 3) + syslog(LOG_INFO, "%s: Authentication-Warning: %.400s", + e->e_id == NULL ? "[NOQUEUE]" : e->e_id, buf); +#endif + } +} +/* +** SETUSERENV -- set an environment in the propogated environment +** +** Parameters: +** envar -- the name of the environment variable. +** value -- the value to which it should be set. If +** null, this is extracted from the incoming +** environment. If that is not set, the call +** to setuserenv is ignored. +** +** Returns: +** none. +*/ + +void +setuserenv(envar, value) + const char *envar; + const char *value; +{ + int i; + char **evp = UserEnviron; + char *p; + + if (value == NULL) + { + value = getenv(envar); + if (value == NULL) + return; + } + + i = strlen(envar); + p = (char *) xalloc(strlen(value) + i + 2); + strcpy(p, envar); + p[i++] = '='; + strcpy(&p[i], value); + + while (*evp != NULL && strncmp(*evp, p, i) != 0) + evp++; + if (*evp != NULL) + { + *evp++ = p; + } + else if (evp < &UserEnviron[MAXUSERENVIRON]) + { + *evp++ = p; + *evp = NULL; + } + + /* make sure it is in our environment as well */ + if (putenv(p) < 0) + syserr("setuserenv: putenv(%s) failed", p); +} +/* +** DUMPSTATE -- dump state +** +** For debugging. +*/ + +void +dumpstate(when) + char *when; +{ +#ifdef LOG + register char *j = macvalue('j', CurEnv); + + syslog(LOG_DEBUG, "--- dumping state on %s: $j = %s ---", + when, + j == NULL ? "<NULL>" : j); + if (j != NULL) + { + if (!wordinclass(j, 'w')) + syslog(LOG_DEBUG, "*** $j not in $=w ***"); + } + syslog(LOG_DEBUG, "CurChildren = %d", CurChildren); + syslog(LOG_DEBUG, "--- open file descriptors: ---"); + printopenfds(TRUE); + syslog(LOG_DEBUG, "--- connection cache: ---"); + mci_dump_all(TRUE); + if (RewriteRules[89] != NULL) + { + int stat; + register char **pvp; + char *pv[MAXATOM + 1]; + + pv[0] = NULL; + stat = rewrite(pv, 89, 0, CurEnv); + syslog(LOG_DEBUG, "--- ruleset 89 returns stat %d, pv: ---", + stat); + for (pvp = pv; *pvp != NULL; pvp++) + syslog(LOG_DEBUG, "%s", *pvp); + } + syslog(LOG_DEBUG, "--- end of state dump ---"); +#endif +} + + +void +sigusr1() +{ + dumpstate("user signal"); +} + + +void +sighup() +{ +#ifdef LOG + if (LogLevel > 3) + syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]); +#endif + releasesignal(SIGHUP); + execv(SaveArgv[0], (ARGV_T) SaveArgv); +#ifdef LOG + if (LogLevel > 0) + syslog(LOG_ALERT, "could not exec %s: %m", SaveArgv[0]); +#endif + exit(EX_OSFILE); +} +/* +** TESTMODELINE -- process a test mode input line +** +** Parameters: +** line -- the input line. +** e -- the current environment. +** Syntax: +** # a comment +** .X process X as a configuration line +** =X dump a configuration item (such as mailers) +** $X dump a macro or class +** /X try an activity +** X normal process through rule set X +*/ + +void +testmodeline(line, e) + char *line; + ENVELOPE *e; +{ + register char *p; + char *q; + auto char *delimptr; + int mid; + int i, rs; + STAB *map; + char **s; + struct rewrite *rw; + ADDRESS a; + static int tryflags = RF_COPYNONE; + char exbuf[MAXLINE]; + extern bool invalidaddr __P((char *, char *)); + extern char *crackaddr __P((char *)); + extern void dump_class __P((STAB *, int)); + extern void translate_dollars __P((char *)); + + switch (line[0]) + { + case '#': + case 0: + return; + + case '?': + help("-bt"); + return; + + case '.': /* config-style settings */ + switch (line[1]) + { + case 'D': + mid = macid(&line[2], &delimptr); + if (mid == '\0') + return; + translate_dollars(delimptr); + define(mid, newstr(delimptr), e); + break; + + case 'C': + if (line[2] == '\0') /* not to call syserr() */ + return; + + mid = macid(&line[2], &delimptr); + if (mid == '\0') + return; + translate_dollars(delimptr); + expand(delimptr, exbuf, sizeof exbuf, e); + p = exbuf; + while (*p != '\0') + { + register char *wd; + char delim; + + while (*p != '\0' && isascii(*p) && isspace(*p)) + p++; + wd = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + delim = *p; + *p = '\0'; + if (wd[0] != '\0') + setclass(mid, wd); + *p = delim; + } + break; + + case '\0': + printf("Usage: .[DC]macro value(s)\n"); + break; + + default: + printf("Unknown \".\" command %s\n", line); + break; + } + return; + + case '=': /* config-style settings */ + switch (line[1]) + { + case 'S': /* dump rule set */ + rs = strtorwset(&line[2], NULL, ST_FIND); + if (rs < 0) + return; + rw = RewriteRules[rs]; + if (rw == NULL) + return; + do + { + putchar('R'); + s = rw->r_lhs; + while (*s != NULL) + { + xputs(*s++); + putchar(' '); + } + putchar('\t'); + putchar('\t'); + s = rw->r_rhs; + while (*s != NULL) + { + xputs(*s++); + putchar(' '); + } + putchar('\n'); + } while (rw = rw->r_next); + break; + + case 'M': + for (i = 0; i < MAXMAILERS; i++) + { + if (Mailer[i] != NULL) + printmailer(Mailer[i]); + } + break; + + case '\0': + printf("Usage: =Sruleset or =M\n"); + break; + + default: + printf("Unknown \"=\" command %s\n", line); + break; + } + return; + + case '-': /* set command-line-like opts */ + switch (line[1]) + { + case 'd': + tTflag(&line[2]); + break; + + case '\0': + printf("Usage: -d{debug arguments}\n"); + break; + + default: + printf("Unknown \"-\" command %s\n", line); + break; + } + return; + + case '$': + if (line[1] == '=') + { + mid = macid(&line[2], NULL); + if (mid != '\0') + stabapply(dump_class, mid); + return; + } + mid = macid(&line[1], NULL); + if (mid == '\0') + return; + p = macvalue(mid, e); + if (p == NULL) + printf("Undefined\n"); + else + { + xputs(p); + printf("\n"); + } + return; + + case '/': /* miscellaneous commands */ + p = &line[strlen(line)]; + while (--p >= line && isascii(*p) && isspace(*p)) + *p = '\0'; + p = strpbrk(line, " \t"); + if (p != NULL) + { + while (isascii(*p) && isspace(*p)) + *p++ = '\0'; + } + else + p = ""; + if (line[1] == '\0') + { + printf("Usage: /[canon|map|mx|parse|try|tryflags]\n"); + return; + } + if (strcasecmp(&line[1], "mx") == 0) + { +#if NAMED_BIND + /* look up MX records */ + int nmx; + auto int rcode; + char *mxhosts[MAXMXHOSTS + 1]; + + if (*p == '\0') + { + printf("Usage: /mx address\n"); + return; + } + nmx = getmxrr(p, mxhosts, FALSE, &rcode); + printf("getmxrr(%s) returns %d value(s):\n", p, nmx); + for (i = 0; i < nmx; i++) + printf("\t%s\n", mxhosts[i]); +#else + printf("No MX code compiled in\n"); +#endif + } + else if (strcasecmp(&line[1], "canon") == 0) + { + auto int rcode = EX_OK; + char host[MAXHOSTNAMELEN]; + + if (*p == '\0') + { + printf("Usage: /canon address\n"); + return; + } + strcpy(host, p); + getcanonname(host, sizeof(host), HasWildcardMX, &rcode); + printf("getcanonname(%s) returns %s (%d)\n", + p, host, rcode); + } + else if (strcasecmp(&line[1], "map") == 0) + { + auto int rcode = EX_OK; + + if (*p == '\0') + { + printf("Usage: /map mapname key\n"); + return; + } + for (q = p; *q != '\0' && !isspace(*q); q++) + continue; + if (*q == '\0') + { + printf("No key specified\n"); + return; + } + *q++ = '\0'; + map = stab(p, ST_MAP, ST_FIND); + if (map == NULL) + { + printf("Map named \"%s\" not found\n", p); + return; + } + printf("map_lookup: %s (%s) ", p, q); + p = (*map->s_map.map_class->map_lookup) + (&map->s_map, q, NULL, &rcode); + if (p == NULL) + printf("no match (%d)\n", rcode); + else + printf("returns %s (%d)\n", p, rcode); + } + else if (strcasecmp(&line[1], "try") == 0) + { + MAILER *m; + STAB *s; + auto int rcode = EX_OK; + + q = strpbrk(p, " \t"); + if (q != NULL) + { + while (isascii(*q) && isspace(*q)) + *q++ = '\0'; + } + if (q == NULL || *q == '\0') + { + printf("Usage: /try mailer address\n"); + return; + } + s = stab(p, ST_MAILER, ST_FIND); + if (s == NULL) + { + printf("Unknown mailer %s\n", p); + return; + } + m = s->s_mailer; + printf("Trying %s %s address %s for mailer %s\n", + bitset(RF_HEADERADDR, tryflags) ? "header" : "envelope", + bitset(RF_SENDERADDR, tryflags) ? "sender" : "recipient", + q, p); + p = remotename(q, m, tryflags, &rcode, CurEnv); + printf("Rcode = %d, addr = %s\n", + rcode, p == NULL ? "<NULL>" : p); + } + else if (strcasecmp(&line[1], "tryflags") == 0) + { + if (*p == '\0') + { + printf("Usage: /tryflags [Hh|Ee][Ss|Rr]\n"); + return; + } + for (; *p != '\0'; p++) + { + switch (*p) + { + case 'H': + case 'h': + tryflags |= RF_HEADERADDR; + break; + + case 'E': + case 'e': + tryflags &= ~RF_HEADERADDR; + break; + + case 'S': + case 's': + tryflags |= RF_SENDERADDR; + break; + + case 'R': + case 'r': + tryflags &= ~RF_SENDERADDR; + break; + } + } + } + else if (strcasecmp(&line[1], "parse") == 0) + { + if (*p == '\0') + { + printf("Usage: /parse address\n"); + return; + } + q = crackaddr(p); + printf("Cracked address = "); + xputs(q); + printf("\nParsing %s %s address\n", + bitset(RF_HEADERADDR, tryflags) ? "header" : "envelope", + bitset(RF_SENDERADDR, tryflags) ? "sender" : "recipient"); + if (parseaddr(p, &a, tryflags, '\0', NULL, e) == NULL) + printf("Cannot parse\n"); + else if (a.q_host != NULL && a.q_host[0] != '\0') + printf("mailer %s, host %s, user %s\n", + a.q_mailer->m_name, a.q_host, a.q_user); + else + printf("mailer %s, user %s\n", + a.q_mailer->m_name, a.q_user); + } + else + { + printf("Unknown \"/\" command %s\n", line); + } + return; + } + + for (p = line; isascii(*p) && isspace(*p); p++) + continue; + q = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p == '\0') + { + printf("No address!\n"); + return; + } + *p = '\0'; + if (invalidaddr(p + 1, NULL)) + return; + do + { + register char **pvp; + char pvpbuf[PSBUFSIZE]; + + pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf, + &delimptr, NULL); + if (pvp == NULL) + continue; + p = q; + while (*p != '\0') + { + int stat; + int rs = strtorwset(p, NULL, ST_FIND); + + if (rs < 0) + break; + stat = rewrite(pvp, rs, 0, e); + if (stat != EX_OK) + printf("== Ruleset %s (%d) status %d\n", + p, rs, stat); + while (*p != '\0' && *p++ != ',') + continue; + } + } while (*(p = delimptr) != '\0'); +} + + +void +dump_class(s, id) + register STAB *s; + int id; +{ + if (s->s_type != ST_CLASS) + return; + if (bitnset(id & 0xff, s->s_class)) + printf("%s\n", s->s_name); +} diff --git a/usr.sbin/sendmail/src/makesendmail b/usr.sbin/sendmail/src/makesendmail new file mode 100644 index 000000000000..df202e9163e2 --- /dev/null +++ b/usr.sbin/sendmail/src/makesendmail @@ -0,0 +1,282 @@ +#!/bin/sh + +# Copyright (c) 1993 Eric P. Allman +# Copyright (c) 1993 The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# @(#)makesendmail 8.29 (Berkeley) 8/1/95 +# + +# +# A quick-and-dirty script to compile sendmail in the presence of +# multiple architectures and Makefiles. +# + +if [ "x${1-""}" = "x-m" ] +then + # show Makefile name only + mflag=1 +else + mflag="" +fi + +# +# Do heuristic guesses !ONLY! for machines that do not have uname +# +if [ -d /LocalApps -a ! -f /bin/uname -a ! -f /usr/bin/uname ] +then + # probably a NeXT box + arch=NeXT + os=Mach + rel=`strings /mach | grep 'Mach.*:' | sed -e 's/.* Mach //' -e 's/:.*//'` +elif [ -f /usr/sony/bin/machine -a -f /etc/osversion ] +then + # probably a Sony NEWS 4.x + os=NEWS-OS + rel=`awk '{ print $3}' /etc/osversion` + arch=`/usr/sony/bin/machine` +elif [ -d /usr/omron -a -f /bin/luna ] +then + # probably a Omron LUNA + os=LUNA + if [ -f /bin/luna1 ] && /bin/luna1 + then + rel=unios-b + arch=luna1 + elif [ -f /bin/luna2 ] && /bin/luna2 + then + rel=Mach + arch=luna2 + elif [ -f /bin/luna88k ] && /bin/luna88k + then + rel=Mach + arch=luna88k + fi +fi + +if [ ! "$arch" -a ! "$os" -a ! "$rel" ] +then + arch=`uname -m | sed -e 's/ //g'` + os=`uname -s | sed 's/\//-/g'` + rel=`uname -r` +fi + +# +# Tweak the values we have already got. PLEASE LIMIT THESE to +# tweaks that are absolutely necessary because your system uname +# routine doesn't return something sufficiently unique. Don't do +# it just because you don't like the name that is returned. You +# can combine the architecture name with the os name to create a +# unique Makefile name. +# + +# tweak machine architecture +case $arch +in + sun4*) arch=sun4;; + + 9000/*) arch=`echo $arch | sed -e 's/9000.//' -e 's/..$/xx/'`;; +esac + +# tweak operating system type and release +case $os +in + DYNIX-ptx) os=PTX;; + Paragon*) os=Paragon;; + HP-UX) rel=`echo $rel | sed -e 's/^[^.]*\.0*//'`;; + AIX) rel=`uname -v`;; + BSD-386) os=BSD-OS;; +esac + +# get "base part" of operating system release +rbase=`echo $rel | sed -e 's/\..*//'` + +# heuristic tweaks to clean up names -- PLEASE LIMIT THESE! +if [ "$os" = "unix" ] +then + # might be Altos System V + case $rel + in + 5.3*) os=Altos;; + esac +elif [ -r /unix -a -r /usr/lib/libseq.a -a -r /lib/cpp ] +then + # might be a DYNIX/ptx 2.x system, which has a broken uname + if strings /lib/cpp | grep _SEQUENT_ > /dev/null + then + os=PTX + fi +elif [ -d /usr/nec ] +then + # NEC machine -- what is it running? + if [ "$os" = "UNIX_System_V" ] + then + os=EWS-UX_V + elif [ "$os" = "UNIX_SV" ] + then + os=UX4800 + fi +elif [ "$arch" = "mips" ] +then + case $rel + in + 4_*) + if [ `uname -v` = "UMIPS" ] + then + os=RISCos + fi;; + esac +fi + +# see if there is a "user suffix" specified +if [ "${SENDMAIL_SUFFIX-}x" = "x" ] +then + sfx="" +else + sfx=".${SENDMAIL_SUFFIX}" +fi + +echo "Configuration: os=$os, rel=$rel, rbase=$rbase, arch=$arch, sfx=$sfx" + +# now try to find a reasonable object directory +if [ -r obj.$os.$rel.$arch$sfx ]; then + obj=obj.$os.$rel.$arch$sfx +elif [ -r obj.$os.$rbase.x.$arch$sfx ]; then + obj=obj.$os.$rbase.x.$arch$sfx +elif [ -r obj.$os.$rel$sfx ]; then + obj=obj.$os.$rel$sfx +elif [ -r obj.$os.$rbase.x$sfx ]; then + obj=obj.$os.$rbase.x$sfx +elif [ -r obj.$os.$arch$sfx ]; then + obj=obj.$os.$arch$sfx +elif [ -r obj.$rel.$arch$sfx ]; then + obj=obj.$rel.$arch$sfx +elif [ -r obj.$rbase.x.$arch$sfx ]; then + obj=obj.$rbase.x.$arch$sfx +elif [ -r obj.$os$sfx ]; then + obj=obj.$os$sfx +elif [ -r obj.$arch$sfx ]; then + obj=obj.$arch$sfx +elif [ -r obj.$rel$sfx ]; then + obj=obj.$rel$sfx +elif [ -r obj$sfx ]; then + obj=obj$sfx +else + # no existing obj directory -- try to create one if Makefile found + obj=obj.$os.$rel.$arch$sfx + if [ -r Makefiles/Makefile.$os.$rel.$arch$sfx ]; then + makefile=Makefile.$os.$rel.$arch$sfx + elif [ -r Makefiles/Makefile.$os.$rel.$arch ]; then + makefile=Makefile.$os.$rel.$arch + elif [ -r Makefiles/Makefile.$os.$rbase.x.$arch$sfx ]; then + makefile=Makefile.$os.$rbase.x.$arch$sfx + elif [ -r Makefiles/Makefile.$os.$rbase.x.$arch ]; then + makefile=Makefile.$os.$rbase.x.$arch + elif [ -r Makefiles/Makefile.$os.$rel$sfx ]; then + makefile=Makefile.$os.$rel$sfx + elif [ -r Makefiles/Makefile.$os.$rel ]; then + makefile=Makefile.$os.$rel + elif [ -r Makefiles/Makefile.$os.$rbase.x$sfx ]; then + makefile=Makefile.$os.$rbase.x$sfx + elif [ -r Makefiles/Makefile.$os.$rbase.x ]; then + makefile=Makefile.$os.$rbase.x + elif [ -r Makefiles/Makefile.$os.$arch$sfx ]; then + makefile=Makefile.$os.$arch$sfx + elif [ -r Makefiles/Makefile.$os.$arch ]; then + makefile=Makefile.$os.$arch + elif [ -r Makefiles/Makefile.$rel.$arch$sfx ]; then + makefile=Makefile.$rel.$arch$sfx + elif [ -r Makefiles/Makefile.$rel.$arch ]; then + makefile=Makefile.$rel.$arch + elif [ -r Makefiles/Makefile.$rbase.x.$arch$sfx ]; then + makefile=Makefile.$rbase.x.$arch$sfx + elif [ -r Makefiles/Makefile.$rbase.x.$arch ]; then + makefile=Makefile.$rbase.x.$arch + elif [ -r Makefiles/Makefile.$os$sfx ]; then + makefile=Makefile.$os$sfx + elif [ -r Makefiles/Makefile.$os ]; then + makefile=Makefile.$os + elif [ -r Makefiles/Makefile.$arch$sfx ]; then + makefile=Makefile.$arch$sfx + elif [ -r Makefiles/Makefile.$arch ]; then + makefile=Makefile.$arch + elif [ -r Makefiles/Makefile.$rel$sfx ]; then + makefile=Makefile.$rel$sfx + elif [ -r Makefiles/Makefile.$rel ]; then + makefile=Makefile.$rel + elif [ -r Makefiles/Makefile.$rel$sfx ]; then + makefile=Makefile.$rel$sfx + else + echo "Cannot determine how to support $arch.$os.$rel" + exit 1 + fi + if [ "$mflag" ] + then + echo "Will run in virgin $obj using $makefile" + exit 0 + fi + echo "Creating $obj using $makefile" + mkdir $obj + (cd $obj; ln -s ../*.[ch158] ../sendmail.hf .; ln -s ../Makefiles/$makefile Makefile) + echo "Making dependencies in $obj" + (cd $obj; ${MAKE-make} depend) +fi + +if [ "$mflag" ] +then + makefile=`ls -l $obj/Makefile | sed 's/.* //'` + if [ -z "$makefile" ] + then + echo "ERROR: $obj exists but has no Makefile" + exit 1 + fi + case $makefile + in + ../Makefiles/*) + makefile=`echo $makefile | sed 's/...Makefiles.//'` + echo "Will run in existing $obj using $makefile" + ;; + + *) + echo "Will run in existing $obj using custom $makefile" + ;; + esac + exit 0 +fi + +echo "Making in $obj" +cd $obj +if [ $# = 0 ] +then + exec ${MAKE-make} +else + exec ${MAKE-make} "$@" +fi diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c new file mode 100644 index 000000000000..b8ea903fb3de --- /dev/null +++ b/usr.sbin/sendmail/src/map.c @@ -0,0 +1,3330 @@ +/* + * Copyright (c) 1992, 1995 Eric P. Allman. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)map.c 8.107 (Berkeley) 11/20/95"; +#endif /* not lint */ + +#include "sendmail.h" + +#ifdef NDBM +# include <ndbm.h> +#endif +#ifdef NEWDB +# ifdef R_FIRST + ERROR README: You are running the Berkeley DB version of ndbm.h. See + ERROR README: the READ_ME file about tweaking Berkeley DB so it can + ERROR README: coexist with NDBM, or delete -DNDBM from the Makefile. +# endif +# include <db.h> +#endif +#ifdef NIS + struct dom_binding; /* forward reference needed on IRIX */ +# include <rpcsvc/ypclnt.h> +#endif + +/* +** MAP.C -- implementations for various map classes. +** +** Each map class implements a series of functions: +** +** bool map_parse(MAP *map, char *args) +** Parse the arguments from the config file. Return TRUE +** if they were ok, FALSE otherwise. Fill in map with the +** values. +** +** char *map_lookup(MAP *map, char *key, char **args, int *pstat) +** Look up the key in the given map. If found, do any +** rewriting the map wants (including "args" if desired) +** and return the value. Set *pstat to the appropriate status +** on error and return NULL. Args will be NULL if called +** from the alias routines, although this should probably +** not be relied upon. It is suggested you call map_rewrite +** to return the results -- it takes care of null termination +** and uses a dynamically expanded buffer as needed. +** +** void map_store(MAP *map, char *key, char *value) +** Store the key:value pair in the map. +** +** bool map_open(MAP *map, int mode) +** Open the map for the indicated mode. Mode should +** be either O_RDONLY or O_RDWR. Return TRUE if it +** was opened successfully, FALSE otherwise. If the open +** failed an the MF_OPTIONAL flag is not set, it should +** also print an error. If the MF_ALIAS bit is set +** and this map class understands the @:@ convention, it +** should call aliaswait() before returning. +** +** void map_close(MAP *map) +** Close the map. +** +** This file also includes the implementation for getcanonname. +** It is currently implemented in a pretty ad-hoc manner; it ought +** to be more properly integrated into the map structure. +*/ + +#define DBMMODE 0644 + +#define EX_NOTFOUND EX_NOHOST + +extern bool aliaswait __P((MAP *, char *, int)); +extern bool extract_canonname __P((char *, char *, char[])); + +#if defined(O_EXLOCK) && HASFLOCK +# define LOCK_ON_OPEN 1 /* we can open/create a locked file */ +#else +# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */ +#endif +/* +** MAP_PARSEARGS -- parse config line arguments for database lookup +** +** This is a generic version of the map_parse method. +** +** Parameters: +** map -- the map being initialized. +** ap -- a pointer to the args on the config line. +** +** Returns: +** TRUE -- if everything parsed OK. +** FALSE -- otherwise. +** +** Side Effects: +** null terminates the filename; stores it in map +*/ + +bool +map_parseargs(map, ap) + MAP *map; + char *ap; +{ + register char *p = ap; + + map->map_mflags |= MF_TRY0NULL | MF_TRY1NULL; + for (;;) + { + while (isascii(*p) && isspace(*p)) + p++; + if (*p != '-') + break; + switch (*++p) + { + case 'N': + map->map_mflags |= MF_INCLNULL; + map->map_mflags &= ~MF_TRY0NULL; + break; + + case 'O': + map->map_mflags &= ~MF_TRY1NULL; + break; + + case 'o': + map->map_mflags |= MF_OPTIONAL; + break; + + case 'f': + map->map_mflags |= MF_NOFOLDCASE; + break; + + case 'm': + map->map_mflags |= MF_MATCHONLY; + break; + + case 'A': + map->map_mflags |= MF_APPEND; + break; + + case 'q': + map->map_mflags |= MF_KEEPQUOTES; + break; + + case 'a': + map->map_app = ++p; + break; + + case 'k': + while (isascii(*++p) && isspace(*p)) + continue; + map->map_keycolnm = p; + break; + + case 'v': + while (isascii(*++p) && isspace(*p)) + continue; + map->map_valcolnm = p; + break; + + case 'z': + if (*++p != '\\') + map->map_coldelim = *p; + else + { + switch (*++p) + { + case 'n': + map->map_coldelim = '\n'; + break; + + case 't': + map->map_coldelim = '\t'; + break; + + default: + map->map_coldelim = '\\'; + } + } + break; +#ifdef RESERVED_FOR_SUN + case 'd': + map->map_mflags |= MF_DOMAIN_WIDE; + break; + + case 's': + /* info type */ + break; +#endif + } + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + } + if (map->map_app != NULL) + map->map_app = newstr(map->map_app); + if (map->map_keycolnm != NULL) + map->map_keycolnm = newstr(map->map_keycolnm); + if (map->map_valcolnm != NULL) + map->map_valcolnm = newstr(map->map_valcolnm); + + if (*p != '\0') + { + map->map_file = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + map->map_file = newstr(map->map_file); + } + + while (*p != '\0' && isascii(*p) && isspace(*p)) + p++; + if (*p != '\0') + map->map_rebuild = newstr(p); + + if (map->map_file == NULL && + !bitset(MCF_OPTFILE, map->map_class->map_cflags)) + { + syserr("No file name for %s map %s", + map->map_class->map_cname, map->map_mname); + return FALSE; + } + return TRUE; +} +/* +** MAP_REWRITE -- rewrite a database key, interpolating %n indications. +** +** It also adds the map_app string. It can be used as a utility +** in the map_lookup method. +** +** Parameters: +** map -- the map that causes this. +** s -- the string to rewrite, NOT necessarily null terminated. +** slen -- the length of s. +** av -- arguments to interpolate into buf. +** +** Returns: +** Pointer to rewritten result. This is static data that +** should be copied if it is to be saved! +** +** Side Effects: +** none. +*/ + +char * +map_rewrite(map, s, slen, av) + register MAP *map; + register char *s; + int slen; + char **av; +{ + register char *bp; + register char c; + char **avp; + register char *ap; + int i; + int len; + static int buflen = -1; + static char *buf = NULL; + + if (tTd(39, 1)) + { + printf("map_rewrite(%.*s), av =", slen, s); + if (av == NULL) + printf(" (nullv)"); + else + { + for (avp = av; *avp != NULL; avp++) + printf("\n\t%s", *avp); + } + printf("\n"); + } + + /* count expected size of output (can safely overestimate) */ + i = len = slen; + if (av != NULL) + { + bp = s; + for (i = slen; --i >= 0 && (c = *bp++) != 0; ) + { + if (c != '%') + continue; + if (--i < 0) + break; + c = *bp++; + if (!(isascii(c) && isdigit(c))) + continue; + for (avp = av; --c >= '0' && *avp != NULL; avp++) + continue; + if (*avp == NULL) + continue; + len += strlen(*avp); + } + } + if (map->map_app != NULL) + len += strlen(map->map_app); + if (buflen < ++len) + { + /* need to malloc additional space */ + buflen = len; + if (buf != NULL) + free(buf); + buf = xalloc(buflen); + } + + bp = buf; + if (av == NULL) + { + bcopy(s, bp, slen); + bp += slen; + } + else + { + while (--slen >= 0 && (c = *s++) != '\0') + { + if (c != '%') + { + pushc: + *bp++ = c; + continue; + } + if (--slen < 0 || (c = *s++) == '\0') + c = '%'; + if (c == '%') + goto pushc; + if (!(isascii(c) && isdigit(c))) + { + *bp++ = '%'; + goto pushc; + } + for (avp = av; --c >= '0' && *avp != NULL; avp++) + continue; + if (*avp == NULL) + continue; + + /* transliterate argument into output string */ + for (ap = *avp; (c = *ap++) != '\0'; ) + *bp++ = c; + } + } + if (map->map_app != NULL) + strcpy(bp, map->map_app); + else + *bp = '\0'; + if (tTd(39, 1)) + printf("map_rewrite => %s\n", buf); + return buf; +} +/* +** INITMAPS -- initialize for aliasing +** +** Parameters: +** rebuild -- if TRUE, this rebuilds the cached versions. +** e -- current envelope. +** +** Returns: +** none. +** +** Side Effects: +** initializes aliases: +** if NDBM: opens the database. +** if ~NDBM: reads the aliases into the symbol table. +*/ + +void +initmaps(rebuild, e) + bool rebuild; + register ENVELOPE *e; +{ + extern void map_init(); + +#if XDEBUG + checkfd012("entering initmaps"); +#endif + CurEnv = e; + if (rebuild) + { + stabapply(map_init, 1); + stabapply(map_init, 2); + } + else + { + stabapply(map_init, 0); + } +#if XDEBUG + checkfd012("exiting initmaps"); +#endif +} + +void +map_init(s, rebuild) + register STAB *s; + int rebuild; +{ + register MAP *map; + + /* has to be a map */ + if (s->s_type != ST_MAP) + return; + + map = &s->s_map; + if (!bitset(MF_VALID, map->map_mflags)) + return; + + if (tTd(38, 2)) + printf("map_init(%s:%s, %s, %d)\n", + map->map_class->map_cname == NULL ? "NULL" : + map->map_class->map_cname, + map->map_mname == NULL ? "NULL" : map->map_mname, + map->map_file == NULL ? "NULL" : map->map_file, + rebuild); + + if (rebuild == (bitset(MF_ALIAS, map->map_mflags) && + bitset(MCF_REBUILDABLE, map->map_class->map_cflags) ? 1 : 2)) + { + if (tTd(38, 3)) + printf("\twrong pass\n"); + return; + } + + /* if already open, close it (for nested open) */ + if (bitset(MF_OPEN, map->map_mflags)) + { + map->map_class->map_close(map); + map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); + } + + if (rebuild == 2) + { + rebuildaliases(map, FALSE); + } + else + { + if (map->map_class->map_open(map, O_RDONLY)) + { + if (tTd(38, 4)) + printf("\t%s:%s %s: valid\n", + map->map_class->map_cname == NULL ? "NULL" : + map->map_class->map_cname, + map->map_mname == NULL ? "NULL" : + map->map_mname, + map->map_file == NULL ? "NULL" : + map->map_file); + map->map_mflags |= MF_OPEN; + } + else + { + if (tTd(38, 4)) + printf("\t%s:%s %s: invalid: %s\n", + map->map_class->map_cname == NULL ? "NULL" : + map->map_class->map_cname, + map->map_mname == NULL ? "NULL" : + map->map_mname, + map->map_file == NULL ? "NULL" : + map->map_file, + errstring(errno)); + if (!bitset(MF_OPTIONAL, map->map_mflags)) + { + extern MAPCLASS BogusMapClass; + + map->map_class = &BogusMapClass; + map->map_mflags |= MF_OPEN; + } + } + } +} +/* +** GETCANONNAME -- look up name using service switch +** +** Parameters: +** host -- the host name to look up. +** hbsize -- the size of the host buffer. +** trymx -- if set, try MX records. +** +** Returns: +** TRUE -- if the host was found. +** FALSE -- otherwise. +*/ + +bool +getcanonname(host, hbsize, trymx) + char *host; + int hbsize; + bool trymx; +{ + int nmaps; + int mapno; + bool found = FALSE; + bool got_tempfail = FALSE; + auto int stat; + char *maptype[MAXMAPSTACK]; + short mapreturn[MAXMAPACTIONS]; + + nmaps = switch_map_find("hosts", maptype, mapreturn); + for (mapno = 0; mapno < nmaps; mapno++) + { + int i; + + if (tTd(38, 20)) + printf("getcanonname(%s), trying %s\n", + host, maptype[mapno]); + if (strcmp("files", maptype[mapno]) == 0) + { + extern bool text_getcanonname __P((char *, int, int *)); + + found = text_getcanonname(host, hbsize, &stat); + } +#ifdef NIS + else if (strcmp("nis", maptype[mapno]) == 0) + { + extern bool nis_getcanonname __P((char *, int, int *)); + + found = nis_getcanonname(host, hbsize, &stat); + } +#endif +#ifdef NISPLUS + else if (strcmp("nisplus", maptype[mapno]) == 0) + { + extern bool nisplus_getcanonname __P((char *, int, int *)); + + found = nisplus_getcanonname(host, hbsize, &stat); + } +#endif +#if NAMED_BIND + else if (strcmp("dns", maptype[mapno]) == 0) + { + extern bool dns_getcanonname __P((char *, int, bool, int *)); + + found = dns_getcanonname(host, hbsize, trymx, &stat); + } +#endif +#if NETINFO + else if (strcmp("netinfo", maptype[mapno]) == 0) + { + extern bool ni_getcanonname __P((char *, int, int *)); + + found = ni_getcanonname(host, hbsize, &stat); + } +#endif + else + { + found = FALSE; + stat = EX_UNAVAILABLE; + } + + /* + ** Heuristic: if $m is not set, we are running during system + ** startup. In this case, when a name is apparently found + ** but has no dot, treat is as not found. This avoids + ** problems if /etc/hosts has no FQDN but is listed first + ** in the service switch. + */ + + if (found && + (macvalue('m', CurEnv) != NULL || strchr(host, '.') != NULL)) + break; + + /* see if we should continue */ + if (stat == EX_TEMPFAIL) + { + i = MA_TRYAGAIN; + got_tempfail = TRUE; + } + else if (stat == EX_NOTFOUND) + i = MA_NOTFOUND; + else + i = MA_UNAVAIL; + if (bitset(1 << mapno, mapreturn[i])) + break; + } + + if (found) + { + char *d; + + if (tTd(38, 20)) + printf("getcanonname(%s), found\n", host); + + /* + ** If returned name is still single token, compensate + ** by tagging on $m. This is because some sites set + ** up their DNS or NIS databases wrong. + */ + + if ((d = strchr(host, '.')) == NULL || d[1] == '\0') + { + d = macvalue('m', CurEnv); + if (d != NULL && + hbsize > (int) (strlen(host) + strlen(d) + 1)) + { + if (host[strlen(host) - 1] != '.') + strcat(host, "."); + strcat(host, d); + } + else + { + return FALSE; + } + } + return TRUE; + } + + if (tTd(38, 20)) + printf("getcanonname(%s), failed, stat=%d\n", host, stat); + +#if NAMED_BIND + if (stat == EX_NOHOST && !got_tempfail) + h_errno = HOST_NOT_FOUND; + else + h_errno = TRY_AGAIN; +#endif + + return FALSE; +} +/* +** EXTRACT_CANONNAME -- extract canonical name from /etc/hosts entry +** +** Parameters: +** name -- the name against which to match. +** line -- the /etc/hosts line. +** cbuf -- the location to store the result. +** +** Returns: +** TRUE -- if the line matched the desired name. +** FALSE -- otherwise. +*/ + +bool +extract_canonname(name, line, cbuf) + char *name; + char *line; + char cbuf[]; +{ + int i; + char *p; + bool found = FALSE; + extern char *get_column(); + + cbuf[0] = '\0'; + if (line[0] == '#') + return FALSE; + + for (i = 1; ; i++) + { + char nbuf[MAXNAME + 1]; + + p = get_column(line, i, '\0', nbuf); + if (p == NULL) + break; + if (cbuf[0] == '\0' || + (strchr(cbuf, '.') == NULL && strchr(p, '.') != NULL)) + strcpy(cbuf, p); + if (strcasecmp(name, p) == 0) + found = TRUE; + } + if (found && strchr(cbuf, '.') == NULL) + { + /* try to add a domain on the end of the name */ + char *domain = macvalue('m', CurEnv); + + if (domain != NULL && + strlen(domain) + strlen(cbuf) + 1 < MAXNAME) + { + p = &cbuf[strlen(cbuf)]; + *p++ = '.'; + strcpy(p, domain); + } + } + return found; +} +/* +** NDBM modules +*/ + +#ifdef NDBM + +/* +** DBM_MAP_OPEN -- DBM-style map open +*/ + +bool +ndbm_map_open(map, mode) + MAP *map; + int mode; +{ + register DBM *dbm; + struct stat st; + int fd; + + if (tTd(38, 2)) + printf("ndbm_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + +#if LOCK_ON_OPEN + if (mode == O_RDONLY) + mode |= O_SHLOCK; + else + mode |= O_CREAT|O_TRUNC|O_EXLOCK; +#else + if (mode == O_RDWR) + { +# ifdef NOFTRUNCATE + /* + ** Warning: race condition. Try to lock the file as + ** quickly as possible after opening it. + */ + + mode |= O_CREAT|O_TRUNC; +# else + /* + ** This ugly code opens the map without truncating it, + ** locks the file, then truncates it. Necessary to + ** avoid race conditions. + */ + + int dirfd; + int pagfd; + char dirfile[MAXNAME + 1]; + char pagfile[MAXNAME + 1]; + + sprintf(dirfile, "%s.dir", map->map_file); + sprintf(pagfile, "%s.pag", map->map_file); + dirfd = open(dirfile, mode|O_CREAT, DBMMODE); + pagfd = open(pagfile, mode|O_CREAT, DBMMODE); + + if (dirfd < 0 || pagfd < 0) + { + syserr("ndbm_map_open: cannot create database %s", + map->map_file); + close(dirfd); + close(pagfd); + return FALSE; + } + if (!lockfile(dirfd, map->map_file, ".dir", LOCK_EX)) + syserr("ndbm_map_open: cannot lock %s.dir", + map->map_file); + if (ftruncate(dirfd, 0) < 0) + syserr("ndbm_map_open: cannot truncate %s.dir", + map->map_file); + if (ftruncate(pagfd, 0) < 0) + syserr("ndbm_map_open: cannot truncate %s.pag", + map->map_file); + + /* we can safely unlock because others will wait for @:@ */ + close(dirfd); + close(pagfd); +# endif + } +#endif + + /* open the database */ + dbm = dbm_open(map->map_file, mode, DBMMODE); + if (dbm == NULL) + { + if (bitset(MF_ALIAS, map->map_mflags) && + aliaswait(map, ".pag", FALSE)) + return TRUE; + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("Cannot open DBM database %s", map->map_file); + return FALSE; + } + map->map_db1 = (void *) dbm; + fd = dbm_dirfno((DBM *) map->map_db1); + if (mode == O_RDONLY) + { +#if LOCK_ON_OPEN + if (fd >= 0) + (void) lockfile(fd, map->map_file, ".pag", LOCK_UN); +#endif + if (bitset(MF_ALIAS, map->map_mflags) && + !aliaswait(map, ".pag", TRUE)) + return FALSE; + } + else + { + /* exclusive lock for duration of rebuild */ +#if !LOCK_ON_OPEN + if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags) && + lockfile(fd, map->map_file, ".dir", LOCK_EX)) +#endif + map->map_mflags |= MF_LOCKED; + } + if (fstat(dbm_dirfno((DBM *) map->map_db1), &st) >= 0) + map->map_mtime = st.st_mtime; + return TRUE; +} + + +/* +** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map +*/ + +char * +ndbm_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + datum key, val; + int fd; + char keybuf[MAXNAME + 1]; + + if (tTd(38, 20)) + printf("ndbm_map_lookup(%s, %s)\n", + map->map_mname, name); + + key.dptr = name; + key.dsize = strlen(name); + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + { + if (key.dsize > sizeof keybuf - 1) + key.dsize = sizeof keybuf - 1; + bcopy(key.dptr, keybuf, key.dsize + 1); + makelower(keybuf); + key.dptr = keybuf; + } + fd = dbm_dirfno((DBM *) map->map_db1); + if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) + (void) lockfile(fd, map->map_file, ".dir", LOCK_SH); + val.dptr = NULL; + if (bitset(MF_TRY0NULL, map->map_mflags)) + { + val = dbm_fetch((DBM *) map->map_db1, key); + if (val.dptr != NULL) + map->map_mflags &= ~MF_TRY1NULL; + } + if (val.dptr == NULL && bitset(MF_TRY1NULL, map->map_mflags)) + { + key.dsize++; + val = dbm_fetch((DBM *) map->map_db1, key); + if (val.dptr != NULL) + map->map_mflags &= ~MF_TRY0NULL; + } + if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) + (void) lockfile(fd, map->map_file, ".dir", LOCK_UN); + if (val.dptr == NULL) + return NULL; + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, name, strlen(name), NULL); + else + return map_rewrite(map, val.dptr, val.dsize, av); +} + + +/* +** DBM_MAP_STORE -- store a datum in the database +*/ + +void +ndbm_map_store(map, lhs, rhs) + register MAP *map; + char *lhs; + char *rhs; +{ + datum key; + datum data; + int stat; + + if (tTd(38, 12)) + printf("ndbm_map_store(%s, %s, %s)\n", + map->map_mname, lhs, rhs); + + key.dsize = strlen(lhs); + key.dptr = lhs; + + data.dsize = strlen(rhs); + data.dptr = rhs; + + if (bitset(MF_INCLNULL, map->map_mflags)) + { + key.dsize++; + data.dsize++; + } + + stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT); + if (stat > 0) + { + if (!bitset(MF_APPEND, map->map_mflags)) + usrerr("050 Warning: duplicate alias name %s", lhs); + else + { + static char *buf = NULL; + static int bufsiz = 0; + auto int xstat; + datum old; + + old.dptr = ndbm_map_lookup(map, key.dptr, NULL, &xstat); + if (old.dptr != NULL && *old.dptr != '\0') + { + old.dsize = strlen(old.dptr); + if (data.dsize + old.dsize + 2 > bufsiz) + { + if (buf != NULL) + (void) free(buf); + bufsiz = data.dsize + old.dsize + 2; + buf = xalloc(bufsiz); + } + sprintf(buf, "%s,%s", data.dptr, old.dptr); + data.dsize = data.dsize + old.dsize + 1; + data.dptr = buf; + if (tTd(38, 9)) + printf("ndbm_map_store append=%s\n", data.dptr); + } + } + stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE); + } + if (stat != 0) + syserr("readaliases: dbm put (%s)", lhs); +} + + +/* +** NDBM_MAP_CLOSE -- close the database +*/ + +void +ndbm_map_close(map) + register MAP *map; +{ + if (tTd(38, 9)) + printf("ndbm_map_close(%s, %s, %x)\n", + map->map_mname, map->map_file, map->map_mflags); + + if (bitset(MF_WRITABLE, map->map_mflags)) + { +#ifdef NIS + bool inclnull; + char buf[200]; + + inclnull = bitset(MF_INCLNULL, map->map_mflags); + map->map_mflags &= ~MF_INCLNULL; + + if (strstr(map->map_file, "/yp/") != NULL) + { + (void) sprintf(buf, "%010ld", curtime()); + ndbm_map_store(map, "YP_LAST_MODIFIED", buf); + + (void) gethostname(buf, sizeof buf); + ndbm_map_store(map, "YP_MASTER_NAME", buf); + } + + if (inclnull) + map->map_mflags |= MF_INCLNULL; +#endif + + /* write out the distinguished alias */ + ndbm_map_store(map, "@", "@"); + } + dbm_close((DBM *) map->map_db1); +} + +#endif +/* +** NEWDB (Hash and BTree) Modules +*/ + +#ifdef NEWDB + +/* +** BT_MAP_OPEN, HASH_MAP_OPEN -- database open primitives. +** +** These do rather bizarre locking. If you can lock on open, +** do that to avoid the condition of opening a database that +** is being rebuilt. If you don't, we'll try to fake it, but +** there will be a race condition. If opening for read-only, +** we immediately release the lock to avoid freezing things up. +** We really ought to hold the lock, but guarantee that we won't +** be pokey about it. That's hard to do. +*/ + +bool +bt_map_open(map, mode) + MAP *map; + int mode; +{ + if (tTd(38, 2)) + printf("bt_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + return db_map_open(map, mode, DB_BTREE); +} + +bool +hash_map_open(map, mode) + MAP *map; + int mode; +{ + if (tTd(38, 2)) + printf("hash_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + return db_map_open(map, mode, DB_HASH); +} + +bool +db_map_open(map, mode, dbtype) + MAP *map; + int mode; + DBTYPE dbtype; +{ + DB *db; + int i; + int omode; + int fd; + int saveerrno; + struct stat st; + char buf[MAXNAME + 1]; + + (void) strcpy(buf, map->map_file); + i = strlen(buf); + if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) + (void) strcat(buf, ".db"); + + omode = mode; + +#if LOCK_ON_OPEN + if (mode == O_RDWR) + omode |= O_CREAT|O_TRUNC|O_EXLOCK; +# if !OLD_NEWDB + else + omode |= O_SHLOCK; +# endif +#else + if (mode == O_RDWR) + omode |= O_CREAT; + + /* + ** Pre-lock the file to avoid race conditions. In particular, + ** since dbopen returns NULL if the file is zero length, we + ** must have a locked instance around the dbopen. + */ + + fd = open(buf, omode, DBMMODE); + + if (fd < 0) + { + syserr("db_map_open: cannot pre-open database %s", + buf); + close(fd); + return FALSE; + } + if (!lockfile(fd, map->map_file, ".db", + mode == O_RDONLY ? LOCK_SH : LOCK_EX)) + syserr("db_map_open: cannot lock %s", buf); + if (mode == O_RDWR) + omode |= O_TRUNC; +#endif + + db = dbopen(buf, omode, DBMMODE, dbtype, NULL); + saveerrno = errno; + +#if !LOCK_ON_OPEN + /* we can safely unlock now because others will wait for @:@ */ + close(fd); +#endif + + if (db == NULL) + { + if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) && + aliaswait(map, ".db", FALSE)) + return TRUE; + errno = saveerrno; + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("Cannot open DB database %s", map->map_file); + return FALSE; + } +#if !OLD_NEWDB + fd = db->fd(db); +# if LOCK_ON_OPEN + if (fd >= 0) + { + if (mode == O_RDONLY) + (void) lockfile(fd, map->map_file, ".db", LOCK_UN); + else + map->map_mflags |= MF_LOCKED; + } +# else + if (mode == O_RDWR && fd >= 0) + { + if (lockfile(fd, map->map_file, ".db", LOCK_EX)) + map->map_mflags |= MF_LOCKED; + } +# endif +#endif + + /* try to make sure that at least the database header is on disk */ + if (mode == O_RDWR) +#if OLD_NEWDB + (void) db->sync(db); +#else + (void) db->sync(db, 0); + + if (fd >= 0 && fstat(fd, &st) >= 0) + map->map_mtime = st.st_mtime; +#endif + + map->map_db2 = (void *) db; + if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) && + !aliaswait(map, ".db", TRUE)) + return FALSE; + return TRUE; +} + + +/* +** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map +*/ + +char * +db_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + DBT key, val; + register DB *db = (DB *) map->map_db2; + int st; + int saveerrno; + int fd; + char keybuf[MAXNAME + 1]; + + if (tTd(38, 20)) + printf("db_map_lookup(%s, %s)\n", + map->map_mname, name); + + key.size = strlen(name); + if (key.size > sizeof keybuf - 1) + key.size = sizeof keybuf - 1; + key.data = keybuf; + bcopy(name, keybuf, key.size + 1); + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + makelower(keybuf); +#if !OLD_NEWDB + fd = db->fd(db); + if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) + (void) lockfile(db->fd(db), map->map_file, ".db", LOCK_SH); +#endif + st = 1; + if (bitset(MF_TRY0NULL, map->map_mflags)) + { + st = db->get(db, &key, &val, 0); + if (st == 0) + map->map_mflags &= ~MF_TRY1NULL; + } + if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags)) + { + key.size++; + st = db->get(db, &key, &val, 0); + if (st == 0) + map->map_mflags &= ~MF_TRY0NULL; + } + saveerrno = errno; +#if !OLD_NEWDB + if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) + (void) lockfile(fd, map->map_file, ".db", LOCK_UN); +#endif + if (st != 0) + { + errno = saveerrno; + if (st < 0) + syserr("db_map_lookup: get (%s)", name); + return NULL; + } + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, name, strlen(name), NULL); + else + return map_rewrite(map, val.data, val.size, av); +} + + +/* +** DB_MAP_STORE -- store a datum in the NEWDB database +*/ + +void +db_map_store(map, lhs, rhs) + register MAP *map; + char *lhs; + char *rhs; +{ + int stat; + DBT key; + DBT data; + register DB *db = map->map_db2; + + if (tTd(38, 12)) + printf("db_map_store(%s, %s, %s)\n", + map->map_mname, lhs, rhs); + + key.size = strlen(lhs); + key.data = lhs; + + data.size = strlen(rhs); + data.data = rhs; + + if (bitset(MF_INCLNULL, map->map_mflags)) + { + key.size++; + data.size++; + } + + stat = db->put(db, &key, &data, R_NOOVERWRITE); + if (stat > 0) + { + if (!bitset(MF_APPEND, map->map_mflags)) + usrerr("050 Warning: duplicate alias name %s", lhs); + else + { + static char *buf = NULL; + static int bufsiz = 0; + DBT old; + + old.data = db_map_lookup(map, key.data, NULL, &stat); + if (old.data != NULL) + { + old.size = strlen(old.data); + if (data.size + old.size + 2 > bufsiz) + { + if (buf != NULL) + (void) free(buf); + bufsiz = data.size + old.size + 2; + buf = xalloc(bufsiz); + } + sprintf(buf, "%s,%s", data.data, old.data); + data.size = data.size + old.size + 1; + data.data = buf; + if (tTd(38, 9)) + printf("db_map_store append=%s\n", data.data); + } + } + stat = db->put(db, &key, &data, 0); + } + if (stat != 0) + syserr("readaliases: db put (%s)", lhs); +} + + +/* +** DB_MAP_CLOSE -- add distinguished entries and close the database +*/ + +void +db_map_close(map) + MAP *map; +{ + register DB *db = map->map_db2; + + if (tTd(38, 9)) + printf("db_map_close(%s, %s, %x)\n", + map->map_mname, map->map_file, map->map_mflags); + + if (bitset(MF_WRITABLE, map->map_mflags)) + { + /* write out the distinguished alias */ + db_map_store(map, "@", "@"); + } + + if (db->close(db) != 0) + syserr("readaliases: db close failure"); +} + +#endif +/* +** NIS Modules +*/ + +# ifdef NIS + +# ifndef YPERR_BUSY +# define YPERR_BUSY 16 +# endif + +/* +** NIS_MAP_OPEN -- open DBM map +*/ + +bool +nis_map_open(map, mode) + MAP *map; + int mode; +{ + int yperr; + register char *p; + auto char *vp; + auto int vsize; + + if (tTd(38, 2)) + printf("nis_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + + if (mode != O_RDONLY) + { + /* issue a pseudo-error message */ +#ifdef ENOSYS + errno = ENOSYS; +#else +# ifdef EFTYPE + errno = EFTYPE; +# else + errno = ENXIO; +# endif +#endif + return FALSE; + } + + p = strchr(map->map_file, '@'); + if (p != NULL) + { + *p++ = '\0'; + if (*p != '\0') + map->map_domain = p; + } + + if (*map->map_file == '\0') + map->map_file = "mail.aliases"; + + if (map->map_domain == NULL) + { + yperr = yp_get_default_domain(&map->map_domain); + if (yperr != 0) + { + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("421 NIS map %s specified, but NIS not running\n", + map->map_file); + return FALSE; + } + } + + /* check to see if this map actually exists */ + yperr = yp_match(map->map_domain, map->map_file, "@", 1, + &vp, &vsize); + if (tTd(38, 10)) + printf("nis_map_open: yp_match(@, %s, %s) => %s\n", + map->map_domain, map->map_file, yperr_string(yperr)); + if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) + { + /* + ** We ought to be calling aliaswait() here if this is an + ** alias file, but powerful HP-UX NIS servers apparently + ** don't insert the @:@ token into the alias map when it + ** is rebuilt, so aliaswait() just hangs. I hate HP-UX. + */ + +#if 0 + if (!bitset(MF_ALIAS, map->map_mflags) || + aliaswait(map, NULL, TRUE)) +#endif + return TRUE; + } + + if (!bitset(MF_OPTIONAL, map->map_mflags)) + { + syserr("421 Cannot bind to map %s in domain %s: %s", + map->map_file, map->map_domain, yperr_string(yperr)); + } + + return FALSE; +} + + +/* +** NIS_MAP_LOOKUP -- look up a datum in a NIS map +*/ + +char * +nis_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + char *vp; + auto int vsize; + int buflen; + int yperr; + char keybuf[MAXNAME + 1]; + + if (tTd(38, 20)) + printf("nis_map_lookup(%s, %s)\n", + map->map_mname, name); + + buflen = strlen(name); + if (buflen > sizeof keybuf - 1) + buflen = sizeof keybuf - 1; + bcopy(name, keybuf, buflen + 1); + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + makelower(keybuf); + yperr = YPERR_KEY; + if (bitset(MF_TRY0NULL, map->map_mflags)) + { + yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, + &vp, &vsize); + if (yperr == 0) + map->map_mflags &= ~MF_TRY1NULL; + } + if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags)) + { + buflen++; + yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, + &vp, &vsize); + if (yperr == 0) + map->map_mflags &= ~MF_TRY0NULL; + } + if (yperr != 0) + { + if (yperr != YPERR_KEY && yperr != YPERR_BUSY) + map->map_mflags &= ~(MF_VALID|MF_OPEN); + return NULL; + } + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, name, strlen(name), NULL); + else + return map_rewrite(map, vp, vsize, av); +} + + +/* +** NIS_GETCANONNAME -- look up canonical name in NIS +*/ + +bool +nis_getcanonname(name, hbsize, statp) + char *name; + int hbsize; + int *statp; +{ + char *vp; + auto int vsize; + int keylen; + int yperr; + static bool try0null = TRUE; + static bool try1null = TRUE; + static char *yp_domain = NULL; + char host_record[MAXLINE]; + char cbuf[MAXNAME]; + char nbuf[MAXNAME + 1]; + + if (tTd(38, 20)) + printf("nis_getcanonname(%s)\n", name); + + if (strlen(name) >= sizeof nbuf) + { + *statp = EX_UNAVAILABLE; + return FALSE; + } + (void) strcpy(nbuf, name); + shorten_hostname(nbuf); + keylen = strlen(nbuf); + + if (yp_domain == NULL) + yp_get_default_domain(&yp_domain); + makelower(nbuf); + yperr = YPERR_KEY; + if (try0null) + { + yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen, + &vp, &vsize); + if (yperr == 0) + try1null = FALSE; + } + if (yperr == YPERR_KEY && try1null) + { + keylen++; + yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen, + &vp, &vsize); + if (yperr == 0) + try0null = FALSE; + } + if (yperr != 0) + { + if (yperr == YPERR_KEY) + *statp = EX_NOHOST; + else if (yperr == YPERR_BUSY) + *statp = EX_TEMPFAIL; + else + *statp = EX_UNAVAILABLE; + return FALSE; + } + strncpy(host_record, vp, vsize); + host_record[vsize] = '\0'; + if (tTd(38, 44)) + printf("got record `%s'\n", host_record); + if (!extract_canonname(nbuf, host_record, cbuf)) + { + /* this should not happen, but.... */ + *statp = EX_NOHOST; + return FALSE; + } + if (hbsize < strlen(cbuf)) + { + *statp = EX_UNAVAILABLE; + return FALSE; + } + strcpy(name, cbuf); + *statp = EX_OK; + return TRUE; +} + +#endif +/* +** NISPLUS Modules +** +** This code donated by Sun Microsystems. +*/ + +#ifdef NISPLUS + +#undef NIS /* symbol conflict in nis.h */ +#include <rpcsvc/nis.h> +#include <rpcsvc/nislib.h> + +#define EN_col(col) zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val +#define COL_NAME(res,i) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_val)[i].tc_name +#define COL_MAX(res) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_len) +#define PARTIAL_NAME(x) ((x)[strlen(x) - 1] != '.') + +/* +** NISPLUS_MAP_OPEN -- open nisplus table +*/ + +bool +nisplus_map_open(map, mode) + MAP *map; + int mode; +{ + register char *p; + char qbuf[MAXLINE + NIS_MAXNAMELEN]; + nis_result *res = NULL; + u_int objs_len; + nis_object *obj_ptr; + int retry_cnt, max_col, i; + + if (tTd(38, 2)) + printf("nisplus_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + + if (mode != O_RDONLY) + { + errno = ENODEV; + return FALSE; + } + + if (*map->map_file == '\0') + map->map_file = "mail_aliases.org_dir"; + + if (PARTIAL_NAME(map->map_file) && map->map_domain == NULL) + { + /* set default NISPLUS Domain to $m */ + extern char *nisplus_default_domain(); + + map->map_domain = newstr(nisplus_default_domain()); + if (tTd(38, 2)) + printf("nisplus_map_open(%s): using domain %s\n", + map->map_file, map->map_domain); + } + if (!PARTIAL_NAME(map->map_file)) + map->map_domain = newstr(""); + + /* check to see if this map actually exists */ + if (PARTIAL_NAME(map->map_file)) + sprintf(qbuf, "%s.%s", map->map_file, map->map_domain); + else + strcpy(qbuf, map->map_file); + + retry_cnt = 0; + while (res == NULL || res->status != NIS_SUCCESS) + { + res = nis_lookup(qbuf, FOLLOW_LINKS); + switch (res->status) + { + case NIS_SUCCESS: + break; + + case NIS_TRYAGAIN: + case NIS_RPCERROR: + case NIS_NAMEUNREACHABLE: + if (retry_cnt++ > 4) + { + errno = EBADR; + return FALSE; + } + /* try not to overwhelm hosed server */ + sleep(2); + break; + + default: /* all other nisplus errors */ +#if 0 + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("421 Cannot find table %s.%s: %s", + map->map_file, map->map_domain, + nis_sperrno(res->status)); +#endif + errno = EBADR; + return FALSE; + } + } + + if (NIS_RES_NUMOBJ(res) != 1 || + (NIS_RES_OBJECT(res)->zo_data.zo_type != TABLE_OBJ)) + { + if (tTd(38, 10)) + printf("nisplus_map_open: %s is not a table\n", qbuf); +#if 0 + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("421 %s.%s: %s is not a table", + map->map_file, map->map_domain, + nis_sperrno(res->status)); +#endif + errno = EBADR; + return FALSE; + } + /* default key column is column 0 */ + if (map->map_keycolnm == NULL) + map->map_keycolnm = newstr(COL_NAME(res,0)); + + max_col = COL_MAX(res); + + /* verify the key column exist */ + for (i=0; i< max_col; i++) + { + if (!strcmp(map->map_keycolnm, COL_NAME(res,i))) + break; + } + if (i == max_col) + { + if (tTd(38, 2)) + printf("nisplus_map_open(%s): can not find key column %s\n", + map->map_file, map->map_keycolnm); + errno = EBADR; + return FALSE; + } + + /* default value column is the last column */ + if (map->map_valcolnm == NULL) + { + map->map_valcolno = max_col - 1; + return TRUE; + } + + for (i=0; i< max_col; i++) + { + if (strcmp(map->map_valcolnm, COL_NAME(res,i)) == 0) + { + map->map_valcolno = i; + return TRUE; + } + } + + if (tTd(38, 2)) + printf("nisplus_map_open(%s): can not find column %s\n", + map->map_file, map->map_keycolnm); + errno = EBADR; + return FALSE; +} + + +/* +** NISPLUS_MAP_LOOKUP -- look up a datum in a NISPLUS table +*/ + +char * +nisplus_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + char *vp; + auto int vsize; + int buflen; + char search_key[MAXNAME + 1]; + char qbuf[MAXLINE + NIS_MAXNAMELEN]; + nis_result *result; + + if (tTd(38, 20)) + printf("nisplus_map_lookup(%s, %s)\n", + map->map_mname, name); + + if (!bitset(MF_OPEN, map->map_mflags)) + { + if (nisplus_map_open(map, O_RDONLY)) + map->map_mflags |= MF_OPEN; + else + { + *statp = EX_UNAVAILABLE; + return NULL; + } + } + + buflen = strlen(name); + if (buflen > sizeof search_key - 1) + buflen = sizeof search_key - 1; + bcopy(name, search_key, buflen + 1); + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + makelower(search_key); + + /* construct the query */ + if (PARTIAL_NAME(map->map_file)) + sprintf(qbuf, "[%s=%s],%s.%s", map->map_keycolnm, + search_key, map->map_file, map->map_domain); + else + sprintf(qbuf, "[%s=%s],%s", map->map_keycolnm, + search_key, map->map_file); + + if (tTd(38, 20)) + printf("qbuf=%s\n", qbuf); + result = nis_list(qbuf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); + if (result->status == NIS_SUCCESS) + { + int count; + char *str; + + if ((count = NIS_RES_NUMOBJ(result)) != 1) + { + if (LogLevel > 10) + syslog(LOG_WARNING, + "%s: lookup error, expected 1 entry, got %d", + map->map_file, count); + + /* ignore second entry */ + if (tTd(38, 20)) + printf("nisplus_map_lookup(%s), got %d entries, additional entries ignored\n", + name, count); + } + + vp = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno)); + /* set the length of the result */ + if (vp == NULL) + vp = ""; + vsize = strlen(vp); + if (tTd(38, 20)) + printf("nisplus_map_lookup(%s), found %s\n", + name, vp); + if (bitset(MF_MATCHONLY, map->map_mflags)) + str = map_rewrite(map, name, strlen(name), NULL); + else + str = map_rewrite(map, vp, vsize, av); + nis_freeresult(result); + *statp = EX_OK; + return str; + } + else + { + if (result->status == NIS_NOTFOUND) + *statp = EX_NOTFOUND; + else if (result->status == NIS_TRYAGAIN) + *statp = EX_TEMPFAIL; + else + { + *statp = EX_UNAVAILABLE; + map->map_mflags &= ~(MF_VALID|MF_OPEN); + } + } + if (tTd(38, 20)) + printf("nisplus_map_lookup(%s), failed\n", name); + nis_freeresult(result); + return NULL; +} + + + +/* +** NISPLUS_GETCANONNAME -- look up canonical name in NIS+ +*/ + +bool +nisplus_getcanonname(name, hbsize, statp) + char *name; + int hbsize; + int *statp; +{ + char *vp; + auto int vsize; + nis_result *result; + char *p; + char nbuf[MAXNAME + 1]; + char qbuf[MAXLINE + NIS_MAXNAMELEN]; + + if (strlen(name) >= sizeof nbuf) + { + *statp = EX_UNAVAILABLE; + return FALSE; + } + (void) strcpy(nbuf, name); + shorten_hostname(nbuf); + + p = strchr(nbuf, '.'); + if (p == NULL) + { + /* single token */ + sprintf(qbuf, "[name=%s],hosts.org_dir", nbuf); + } + else if (p[1] != '\0') + { + /* multi token -- take only first token in nbuf */ + *p = '\0'; + sprintf(qbuf, "[name=%s],hosts.org_dir.%s", nbuf, &p[1]); + } + else + { + *statp = EX_NOHOST; + return FALSE; + } + + if (tTd(38, 20)) + printf("\nnisplus_getcanoname(%s), qbuf=%s\n", + name, qbuf); + + result = nis_list(qbuf, EXPAND_NAME|FOLLOW_LINKS|FOLLOW_PATH, + NULL, NULL); + + if (result->status == NIS_SUCCESS) + { + int count; + char *str; + char *domain; + + if ((count = NIS_RES_NUMOBJ(result)) != 1) + { +#ifdef LOG + if (LogLevel > 10) + syslog(LOG_WARNING, + "nisplus_getcanonname: lookup error, expected 1 entry, got %d", + count); +#endif + + /* ignore second entry */ + if (tTd(38, 20)) + printf("nisplus_getcanoname(%s), got %d entries, addtional entries ignores\n", name); + } + + if (tTd(38, 20)) + printf("nisplus_getcanoname(%s), found in directory \"%s\"\n", + name, (NIS_RES_OBJECT(result))->zo_domain); + + + vp = ((NIS_RES_OBJECT(result))->EN_col(0)); + vsize = strlen(vp); + if (tTd(38, 20)) + printf("nisplus_getcanonname(%s), found %s\n", + name, vp); + if (strchr(vp, '.') != NULL) + { + domain = ""; + } + else + { + domain = macvalue('m', CurEnv); + if (domain == NULL) + domain = ""; + } + if (hbsize > vsize + (int) strlen(domain) + 1) + { + if (domain[0] == '\0') + strcpy(name, vp); + else + sprintf(name, "%s.%s", vp, domain); + *statp = EX_OK; + } + else + *statp = EX_NOHOST; + nis_freeresult(result); + return TRUE; + } + else + { + if (result->status == NIS_NOTFOUND) + *statp = EX_NOHOST; + else if (result->status == NIS_TRYAGAIN) + *statp = EX_TEMPFAIL; + else + *statp = EX_UNAVAILABLE; + } + if (tTd(38, 20)) + printf("nisplus_getcanonname(%s), failed, status=%d, nsw_stat=%d\n", + name, result->status, *statp); + nis_freeresult(result); + return FALSE; +} + + +char * +nisplus_default_domain() +{ + static char default_domain[MAXNAME + 1] = ""; + char *p; + + if (default_domain[0] != '\0') + return(default_domain); + + p = nis_local_directory(); + strcpy(default_domain, p); + return default_domain; +} + +#endif /* NISPLUS */ +/* +** HESIOD Modules +*/ + +#ifdef HESIOD + +#include <hesiod.h> + +bool +hes_map_open(map, mode) + MAP *map; + int mode; +{ + if (tTd(38, 2)) + printf("hes_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + + if (mode != O_RDONLY) + { + /* issue a pseudo-error message */ +#ifdef ENOSYS + errno = ENOSYS; +#else +# ifdef EFTYPE + errno = EFTYPE; +# else + errno = ENXIO; +# endif +#endif + return FALSE; + } + + if (hes_error() == HES_ER_UNINIT) + hes_init(); + switch (hes_error()) + { + case HES_ER_OK: + case HES_ER_NOTFOUND: + return TRUE; + } + + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("421 cannot initialize Hesiod map (%d)", hes_error()); + + return FALSE; +} + +char * +hes_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + char **hp; + + if (tTd(38, 20)) + printf("hes_map_lookup(%s, %s)\n", map->map_file, name); + + if (name[0] == '\\') + { + char *np; + int nl; + char nbuf[MAXNAME]; + + nl = strlen(name); + if (nl < sizeof nbuf - 1) + np = nbuf; + else + np = xalloc(strlen(name) + 2); + np[0] = '\\'; + strcpy(&np[1], name); + hp = hes_resolve(np, map->map_file); + if (np != nbuf) + free(np); + } + else + { + hp = hes_resolve(name, map->map_file); + } + if (hp == NULL || hp[0] == NULL) + { + switch (hes_error()) + { + case HES_ER_OK: + *statp = EX_OK; + break; + + case HES_ER_NOTFOUND: + *statp = EX_NOTFOUND; + break; + + case HES_ER_CONFIG: + *statp = EX_UNAVAILABLE; + break; + + case HES_ER_NET: + *statp = EX_TEMPFAIL; + break; + } + return NULL; + } + + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, name, strlen(name), NULL); + else + return map_rewrite(map, hp[0], strlen(hp[0]), av); +} + +#endif +/* +** NeXT NETINFO Modules +*/ + +#if NETINFO + +# define NETINFO_DEFAULT_DIR "/aliases" +# define NETINFO_DEFAULT_PROPERTY "members" + +extern char *ni_propval __P((char *, char *, char *, char *, int)); + + +/* +** NI_MAP_OPEN -- open NetInfo Aliases +*/ + +bool +ni_map_open(map, mode) + MAP *map; + int mode; +{ + char *p; + + if (tTd(38, 20)) + printf("ni_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + + if (*map->map_file == '\0') + map->map_file = NETINFO_DEFAULT_DIR; + + if (map->map_valcolnm == NULL) + map->map_valcolnm = NETINFO_DEFAULT_PROPERTY; + + if (map->map_coldelim == '\0' && bitset(MF_ALIAS, map->map_mflags)) + map->map_coldelim = ','; + + return TRUE; +} + + +/* +** NI_MAP_LOOKUP -- look up a datum in NetInfo +*/ + +char * +ni_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + char *res; + char *propval; + + if (tTd(38, 20)) + printf("ni_map_lookup(%s, %s)\n", map->map_mname, name); + + propval = ni_propval(map->map_file, map->map_keycolnm, name, + map->map_valcolnm, map->map_coldelim); + + if (propval == NULL) + return NULL; + + if (bitset(MF_MATCHONLY, map->map_mflags)) + res = map_rewrite(map, name, strlen(name), NULL); + else + res = map_rewrite(map, propval, strlen(propval), av); + free(propval); + return res; +} + + +bool +ni_getcanonname(name, hbsize, statp) + char *name; + int hbsize; + int *statp; +{ + char *vptr; + char nbuf[MAXNAME + 1]; + + if (tTd(38, 20)) + printf("ni_getcanonname(%s)\n", name); + + if (strlen(name) >= sizeof nbuf) + { + *statp = EX_UNAVAILABLE; + return FALSE; + } + (void) strcpy(nbuf, name); + shorten_hostname(nbuf); + + /* we only accept single token search key */ + if (strchr(nbuf, '.')) + { + *statp = EX_NOHOST; + return FALSE; + } + + /* Do the search */ + vptr = ni_propval("/machines", NULL, nbuf, "name", '\0'); + + if (vptr == NULL) + { + *statp = EX_NOHOST; + return FALSE; + } + + if (hbsize >= strlen(vptr)) + { + strcpy(name, vptr); + *statp = EX_OK; + return TRUE; + } + *statp = EX_UNAVAILABLE; + free(vptr); + return FALSE; +} + + +/* +** NI_PROPVAL -- NetInfo property value lookup routine +** +** Parameters: +** keydir -- the NetInfo directory name in which to search +** for the key. +** keyprop -- the name of the property in which to find the +** property we are interested. Defaults to "name". +** keyval -- the value for which we are really searching. +** valprop -- the property name for the value in which we +** are interested. +** sepchar -- if non-nil, this can be multiple-valued, and +** we should return a string separated by this +** character. +** +** Returns: +** NULL -- if: +** 1. the directory is not found +** 2. the property name is not found +** 3. the property contains multiple values +** 4. some error occured +** else -- the value of the lookup. +** +** Example: +** To search for an alias value, use: +** ni_propval("/aliases", "name", aliasname, "members", ',') +** +** Notes: +** Caller should free the return value of ni_proval +*/ + +# include <netinfo/ni.h> + +# define LOCAL_NETINFO_DOMAIN "." +# define PARENT_NETINFO_DOMAIN ".." +# define MAX_NI_LEVELS 256 + +char * +ni_propval(keydir, keyprop, keyval, valprop, sepchar) + char *keydir; + char *keyprop; + char *keyval; + char *valprop; + int sepchar; +{ + char *propval = NULL; + int i; + int j, alen; + void *ni = NULL; + void *lastni = NULL; + ni_status nis; + ni_id nid; + ni_namelist ninl; + register char *p; + char keybuf[1024]; + + /* + ** Create the full key from the two parts. + ** + ** Note that directory can end with, e.g., "name=" to specify + ** an alternate search property. + */ + + i = strlen(keydir) + strlen(keyval) + 2; + if (keyprop != NULL) + i += strlen(keyprop) + 1; + if (i > sizeof keybuf) + return NULL; + strcpy(keybuf, keydir); + strcat(keybuf, "/"); + if (keyprop != NULL) + { + strcat(keybuf, keyprop); + strcat(keybuf, "="); + } + strcat(keybuf, keyval); + + /* + ** If the passed directory and property name are found + ** in one of netinfo domains we need to search (starting + ** from the local domain moving all the way back to the + ** root domain) set propval to the property's value + ** and return it. + */ + + for (i = 0; i < MAX_NI_LEVELS; ++i) + { + if (i == 0) + { + nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni); + } + else + { + if (lastni != NULL) + ni_free(lastni); + lastni = ni; + nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni); + } + + /* + ** Don't bother if we didn't get a handle on a + ** proper domain. This is not necessarily an error. + ** We would get a positive ni_status if, for instance + ** we never found the directory or property and tried + ** to open the parent of the root domain! + */ + + if (nis != 0) + break; + + /* + ** Find the path to the server information. + */ + + if (ni_pathsearch(ni, &nid, keybuf) != 0) + continue; + + /* + ** Find associated value information. + */ + + if (ni_lookupprop(ni, &nid, valprop, &ninl) != 0) + continue; + + /* + ** See if we have an acceptable number of values. + */ + + if (ninl.ni_namelist_len <= 0) + continue; + + if (sepchar == '\0' && ninl.ni_namelist_len > 1) + { + ni_namelist_free(&ninl); + continue; + } + + /* + ** Calculate number of bytes needed and build result + */ + + alen = 1; + for (j = 0; j < ninl.ni_namelist_len; j++) + alen += strlen(ninl.ni_namelist_val[j]) + 1; + propval = p = xalloc(alen); + for (j = 0; j < ninl.ni_namelist_len; j++) + { + strcpy(p, ninl.ni_namelist_val[j]); + p += strlen(p); + *p++ = sepchar; + } + *--p = '\0'; + + ni_namelist_free(&ninl); + } + + /* + ** Clean up. + */ + + if (ni != NULL) + ni_free(ni); + if (lastni != NULL && ni != lastni) + ni_free(lastni); + + return propval; +} + +#endif +/* +** TEXT (unindexed text file) Modules +** +** This code donated by Sun Microsystems. +*/ + + +/* +** TEXT_MAP_OPEN -- open text table +*/ + +bool +text_map_open(map, mode) + MAP *map; + int mode; +{ + struct stat sbuf; + + if (tTd(38, 2)) + printf("text_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + + if (mode != O_RDONLY) + { + errno = ENODEV; + return FALSE; + } + + if (*map->map_file == '\0') + { + if (tTd(38, 2)) + printf("text_map_open(%s): file name required\n", + map->map_mname); + return FALSE; + } + + if (map->map_file[0] != '/') + { + if (tTd(38, 2)) + printf("text_map_open(%s, %s): file name must be fully qualified\n", + map->map_mname, map->map_file); + return FALSE; + } + /* check to see if this map actually accessable */ + if (access(map->map_file, R_OK) <0) + return FALSE; + + /* check to see if this map actually exist */ + if (stat(map->map_file, &sbuf) <0) + { + if (tTd(38, 2)) + printf("text_map_open(%s, %s): cannot stat\n", + map->map_mname, map->map_file); + return FALSE; + } + + if (!S_ISREG(sbuf.st_mode)) + { + if (tTd(38, 2)) + printf("text_map_open(%s): %s is not a regular file\n", + map->map_mname, map->map_file); + return FALSE; + } + + if (map->map_keycolnm == NULL) + map->map_keycolno = 0; + else + { + if (!isdigit(*map->map_keycolnm)) + { + if (tTd(38, 2)) + printf("text_map_open(%s, %s): -k should specify a number, not %s\n", + map->map_mname, map->map_file, + map->map_keycolnm); + return FALSE; + } + map->map_keycolno = atoi(map->map_keycolnm); + } + + if (map->map_valcolnm == NULL) + map->map_valcolno = 0; + else + { + if (!isdigit(*map->map_valcolnm)) + { + if (tTd(38, 2)) + printf("text_map_open(%s, %s): -v should specify a number, not %s\n", + map->map_mname, map->map_file, + map->map_valcolnm); + return FALSE; + } + map->map_valcolno = atoi(map->map_valcolnm); + } + + if (tTd(38, 2)) + { + printf("text_map_open(%s, %s): delimiter = ", + map->map_mname, map->map_file); + if (map->map_coldelim == '\0') + printf("(white space)\n"); + else + printf("%c\n", map->map_coldelim); + } + + return TRUE; +} + + +/* +** TEXT_MAP_LOOKUP -- look up a datum in a TEXT table +*/ + +char * +text_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + char *vp; + auto int vsize; + int buflen; + char search_key[MAXNAME + 1]; + char linebuf[MAXLINE]; + FILE *f; + char buf[MAXNAME + 1]; + char delim; + int key_idx; + bool found_it; + extern char *get_column(); + + + found_it = FALSE; + if (tTd(38, 20)) + printf("text_map_lookup(%s, %s)\n", map->map_mname, name); + + buflen = strlen(name); + if (buflen > sizeof search_key - 1) + buflen = sizeof search_key - 1; + bcopy(name, search_key, buflen + 1); + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + makelower(search_key); + + f = fopen(map->map_file, "r"); + if (f == NULL) + { + map->map_mflags &= ~(MF_VALID|MF_OPEN); + *statp = EX_UNAVAILABLE; + return NULL; + } + key_idx = map->map_keycolno; + delim = map->map_coldelim; + while (fgets(linebuf, MAXLINE, f) != NULL) + { + char *p; + + /* skip comment line */ + if (linebuf[0] == '#') + continue; + p = strchr(linebuf, '\n'); + if (p != NULL) + *p = '\0'; + p = get_column(linebuf, key_idx, delim, buf); + if (p != NULL && strcasecmp(search_key, p) == 0) + { + found_it = TRUE; + break; + } + } + fclose(f); + if (!found_it) + { + *statp = EX_NOTFOUND; + return NULL; + } + vp = get_column(linebuf, map->map_valcolno, delim, buf); + vsize = strlen(vp); + *statp = EX_OK; + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, name, strlen(name), NULL); + else + return map_rewrite(map, vp, vsize, av); +} + + +/* +** TEXT_GETCANONNAME -- look up canonical name in hosts file +*/ + +bool +text_getcanonname(name, hbsize, statp) + char *name; + int hbsize; + int *statp; +{ + int key_idx; + bool found; + FILE *f; + char linebuf[MAXLINE]; + char cbuf[MAXNAME + 1]; + char fbuf[MAXNAME + 1]; + char nbuf[MAXNAME + 1]; + extern char *get_column(); + + if (tTd(38, 20)) + printf("text_getcanonname(%s)\n", name); + + if (strlen(name) >= sizeof nbuf) + { + *statp = EX_UNAVAILABLE; + return FALSE; + } + (void) strcpy(nbuf, name); + shorten_hostname(nbuf); + + f = fopen(HostsFile, "r"); + if (f == NULL) + { + *statp = EX_UNAVAILABLE; + return FALSE; + } + found = FALSE; + while (!found && fgets(linebuf, MAXLINE, f) != NULL) + { + char *p = strpbrk(linebuf, "#\n"); + + if (p != NULL) + *p = '\0'; + if (linebuf[0] != '\0') + found = extract_canonname(nbuf, linebuf, cbuf); + } + fclose(f); + if (!found) + { + *statp = EX_NOHOST; + return FALSE; + } + + if (hbsize >= strlen(cbuf)) + { + strcpy(name, cbuf); + *statp = EX_OK; + return TRUE; + } + *statp = EX_UNAVAILABLE; + return FALSE; +} +/* +** STAB (Symbol Table) Modules +*/ + + +/* +** STAB_MAP_LOOKUP -- look up alias in symbol table +*/ + +char * +stab_map_lookup(map, name, av, pstat) + register MAP *map; + char *name; + char **av; + int *pstat; +{ + register STAB *s; + + if (tTd(38, 20)) + printf("stab_lookup(%s, %s)\n", + map->map_mname, name); + + s = stab(name, ST_ALIAS, ST_FIND); + if (s != NULL) + return (s->s_alias); + return (NULL); +} + + +/* +** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild) +*/ + +void +stab_map_store(map, lhs, rhs) + register MAP *map; + char *lhs; + char *rhs; +{ + register STAB *s; + + s = stab(lhs, ST_ALIAS, ST_ENTER); + s->s_alias = newstr(rhs); +} + + +/* +** STAB_MAP_OPEN -- initialize (reads data file) +** +** This is a wierd case -- it is only intended as a fallback for +** aliases. For this reason, opens for write (only during a +** "newaliases") always fails, and opens for read open the +** actual underlying text file instead of the database. +*/ + +bool +stab_map_open(map, mode) + register MAP *map; + int mode; +{ + FILE *af; + struct stat st; + + if (tTd(38, 2)) + printf("stab_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + + if (mode != O_RDONLY) + { + errno = ENODEV; + return FALSE; + } + + af = fopen(map->map_file, "r"); + if (af == NULL) + return FALSE; + readaliases(map, af, FALSE, FALSE); + + if (fstat(fileno(af), &st) >= 0) + map->map_mtime = st.st_mtime; + fclose(af); + + return TRUE; +} +/* +** Implicit Modules +** +** Tries several types. For back compatibility of aliases. +*/ + + +/* +** IMPL_MAP_LOOKUP -- lookup in best open database +*/ + +char * +impl_map_lookup(map, name, av, pstat) + MAP *map; + char *name; + char **av; + int *pstat; +{ + if (tTd(38, 20)) + printf("impl_map_lookup(%s, %s)\n", + map->map_mname, name); + +#ifdef NEWDB + if (bitset(MF_IMPL_HASH, map->map_mflags)) + return db_map_lookup(map, name, av, pstat); +#endif +#ifdef NDBM + if (bitset(MF_IMPL_NDBM, map->map_mflags)) + return ndbm_map_lookup(map, name, av, pstat); +#endif + return stab_map_lookup(map, name, av, pstat); +} + +/* +** IMPL_MAP_STORE -- store in open databases +*/ + +void +impl_map_store(map, lhs, rhs) + MAP *map; + char *lhs; + char *rhs; +{ + if (tTd(38, 12)) + printf("impl_map_store(%s, %s, %s)\n", + map->map_mname, lhs, rhs); +#ifdef NEWDB + if (bitset(MF_IMPL_HASH, map->map_mflags)) + db_map_store(map, lhs, rhs); +#endif +#ifdef NDBM + if (bitset(MF_IMPL_NDBM, map->map_mflags)) + ndbm_map_store(map, lhs, rhs); +#endif + stab_map_store(map, lhs, rhs); +} + +/* +** IMPL_MAP_OPEN -- implicit database open +*/ + +bool +impl_map_open(map, mode) + MAP *map; + int mode; +{ + if (tTd(38, 2)) + printf("impl_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + +#ifdef NEWDB + map->map_mflags |= MF_IMPL_HASH; + if (hash_map_open(map, mode)) + { +#if defined(NDBM) && defined(NIS) + if (mode == O_RDONLY || strstr(map->map_file, "/yp/") == NULL) +#endif + return TRUE; + } + else + map->map_mflags &= ~MF_IMPL_HASH; +#endif +#ifdef NDBM + map->map_mflags |= MF_IMPL_NDBM; + if (ndbm_map_open(map, mode)) + { + return TRUE; + } + else + map->map_mflags &= ~MF_IMPL_NDBM; +#endif + +#if defined(NEWDB) || defined(NDBM) + if (Verbose) + message("WARNING: cannot open alias database %s", map->map_file); +#else + if (mode != O_RDONLY) + usrerr("Cannot rebuild aliases: no database format defined"); +#endif + + return stab_map_open(map, mode); +} + + +/* +** IMPL_MAP_CLOSE -- close any open database(s) +*/ + +void +impl_map_close(map) + MAP *map; +{ + if (tTd(38, 9)) + printf("impl_map_close(%s, %s, %x)\n", + map->map_mname, map->map_file, map->map_mflags); +#ifdef NEWDB + if (bitset(MF_IMPL_HASH, map->map_mflags)) + { + db_map_close(map); + map->map_mflags &= ~MF_IMPL_HASH; + } +#endif + +#ifdef NDBM + if (bitset(MF_IMPL_NDBM, map->map_mflags)) + { + ndbm_map_close(map); + map->map_mflags &= ~MF_IMPL_NDBM; + } +#endif +} +/* +** User map class. +** +** Provides access to the system password file. +*/ + +/* +** USER_MAP_OPEN -- open user map +** +** Really just binds field names to field numbers. +*/ + +bool +user_map_open(map, mode) + MAP *map; + int mode; +{ + if (tTd(38, 2)) + printf("user_map_open(%s, %d)\n", + map->map_mname, mode); + + if (mode != O_RDONLY) + { + /* issue a pseudo-error message */ +#ifdef ENOSYS + errno = ENOSYS; +#else +# ifdef EFTYPE + errno = EFTYPE; +# else + errno = ENXIO; +# endif +#endif + return FALSE; + } + if (map->map_valcolnm == NULL) + /* nothing */ ; + else if (strcasecmp(map->map_valcolnm, "name") == 0) + map->map_valcolno = 1; + else if (strcasecmp(map->map_valcolnm, "passwd") == 0) + map->map_valcolno = 2; + else if (strcasecmp(map->map_valcolnm, "uid") == 0) + map->map_valcolno = 3; + else if (strcasecmp(map->map_valcolnm, "gid") == 0) + map->map_valcolno = 4; + else if (strcasecmp(map->map_valcolnm, "gecos") == 0) + map->map_valcolno = 5; + else if (strcasecmp(map->map_valcolnm, "dir") == 0) + map->map_valcolno = 6; + else if (strcasecmp(map->map_valcolnm, "shell") == 0) + map->map_valcolno = 7; + else + { + syserr("User map %s: unknown column name %s", + map->map_mname, map->map_valcolnm); + return FALSE; + } + return TRUE; +} + + +/* +** USER_MAP_LOOKUP -- look up a user in the passwd file. +*/ + +char * +user_map_lookup(map, key, av, statp) + MAP *map; + char *key; + char **av; + int *statp; +{ + struct passwd *pw; + + if (tTd(38, 20)) + printf("user_map_lookup(%s, %s)\n", + map->map_mname, key); + + pw = sm_getpwnam(key); + if (pw == NULL) + return NULL; + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, key, strlen(key), NULL); + else + { + char *rwval = NULL; + char buf[30]; + + switch (map->map_valcolno) + { + case 0: + case 1: + rwval = pw->pw_name; + break; + + case 2: + rwval = pw->pw_passwd; + break; + + case 3: + sprintf(buf, "%d", pw->pw_uid); + rwval = buf; + break; + + case 4: + sprintf(buf, "%d", pw->pw_gid); + rwval = buf; + break; + + case 5: + rwval = pw->pw_gecos; + break; + + case 6: + rwval = pw->pw_dir; + break; + + case 7: + rwval = pw->pw_shell; + break; + } + return map_rewrite(map, rwval, strlen(rwval), av); + } +} +/* +** Program map type. +** +** This provides access to arbitrary programs. It should be used +** only very sparingly, since there is no way to bound the cost +** of invoking an arbitrary program. +*/ + +char * +prog_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + int i; + register char *p; + int fd; + auto pid_t pid; + char *rval; + int stat; + char *argv[MAXPV + 1]; + char buf[MAXLINE]; + + if (tTd(38, 20)) + printf("prog_map_lookup(%s, %s) %s\n", + map->map_mname, name, map->map_file); + + i = 0; + argv[i++] = map->map_file; + if (map->map_rebuild != NULL) + { + strcpy(buf, map->map_rebuild); + for (p = strtok(buf, " \t"); p != NULL; p = strtok(NULL, " \t")) + { + if (i >= MAXPV - 1) + break; + argv[i++] = p; + } + } + argv[i++] = name; + argv[i] = NULL; + if (tTd(38, 21)) + { + printf("prog_open:"); + for (i = 0; argv[i] != NULL; i++) + printf(" %s", argv[i]); + printf("\n"); + } + pid = prog_open(argv, &fd, CurEnv); + if (pid < 0) + { + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("prog_map_lookup(%s) failed (%s) -- closing", + map->map_mname, errstring(errno)); + else if (tTd(38, 9)) + printf("prog_map_lookup(%s) failed (%s) -- closing", + map->map_mname, errstring(errno)); + map->map_mflags &= ~(MF_VALID|MF_OPEN); + *statp = EX_OSFILE; + return NULL; + } + i = read(fd, buf, sizeof buf - 1); + if (i < 0) + { + syserr("prog_map_lookup(%s): read error %s\n", + map->map_mname, errstring(errno)); + rval = NULL; + } + else if (i == 0 && tTd(38, 20)) + { + printf("prog_map_lookup(%s): empty answer\n", + map->map_mname); + rval = NULL; + } + if (i > 0) + { + buf[i] = '\0'; + p = strchr(buf, '\n'); + if (p != NULL) + *p = '\0'; + + /* collect the return value */ + if (bitset(MF_MATCHONLY, map->map_mflags)) + rval = map_rewrite(map, name, strlen(name), NULL); + else + rval = map_rewrite(map, buf, strlen(buf), NULL); + + /* now flush any additional output */ + while ((i = read(fd, buf, sizeof buf)) > 0) + continue; + } + + /* wait for the process to terminate */ + close(fd); + stat = waitfor(pid); + + if (stat == -1) + { + syserr("prog_map_lookup(%s): wait error %s\n", + map->map_mname, errstring(errno)); + *statp = EX_SOFTWARE; + rval = NULL; + } + else if (WIFEXITED(stat)) + { + if ((*statp = WEXITSTATUS(stat)) != EX_OK) + rval = NULL; + } + else + { + syserr("prog_map_lookup(%s): child died on signal %d", + map->map_mname, stat); + *statp = EX_UNAVAILABLE; + rval = NULL; + } + return rval; +} +/* +** Sequenced map type. +** +** Tries each map in order until something matches, much like +** implicit. Stores go to the first map in the list that can +** support storing. +** +** This is slightly unusual in that there are two interfaces. +** The "sequence" interface lets you stack maps arbitrarily. +** The "switch" interface builds a sequence map by looking +** at a system-dependent configuration file such as +** /etc/nsswitch.conf on Solaris or /etc/svc.conf on Ultrix. +** +** We don't need an explicit open, since all maps are +** opened during startup, including underlying maps. +*/ + +/* +** SEQ_MAP_PARSE -- Sequenced map parsing +*/ + +bool +seq_map_parse(map, ap) + MAP *map; + char *ap; +{ + int maxmap; + + if (tTd(38, 2)) + printf("seq_map_parse(%s, %s)\n", map->map_mname, ap); + maxmap = 0; + while (*ap != '\0') + { + register char *p; + STAB *s; + + /* find beginning of map name */ + while (isascii(*ap) && isspace(*ap)) + ap++; + for (p = ap; isascii(*p) && isalnum(*p); p++) + continue; + if (*p != '\0') + *p++ = '\0'; + while (*p != '\0' && (!isascii(*p) || !isalnum(*p))) + p++; + if (*ap == '\0') + { + ap = p; + continue; + } + s = stab(ap, ST_MAP, ST_FIND); + if (s == NULL) + { + syserr("Sequence map %s: unknown member map %s", + map->map_mname, ap); + } + else if (maxmap == MAXMAPSTACK) + { + syserr("Sequence map %s: too many member maps (%d max)", + map->map_mname, MAXMAPSTACK); + maxmap++; + } + else if (maxmap < MAXMAPSTACK) + { + map->map_stack[maxmap++] = &s->s_map; + } + ap = p; + } + return TRUE; +} + + +/* +** SWITCH_MAP_OPEN -- open a switched map +** +** This looks at the system-dependent configuration and builds +** a sequence map that does the same thing. +** +** Every system must define a switch_map_find routine in conf.c +** that will return the list of service types associated with a +** given service class. +*/ + +bool +switch_map_open(map, mode) + MAP *map; + int mode; +{ + int mapno; + int nmaps; + char *maptype[MAXMAPSTACK]; + + if (tTd(38, 2)) + printf("switch_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + + nmaps = switch_map_find(map->map_file, maptype, map->map_return); + if (tTd(38, 19)) + { + printf("\tswitch_map_find => %d\n", nmaps); + for (mapno = 0; mapno < nmaps; mapno++) + printf("\t\t%s\n", maptype[mapno]); + } + if (nmaps <= 0 || nmaps > MAXMAPSTACK) + return FALSE; + + for (mapno = 0; mapno < nmaps; mapno++) + { + register STAB *s; + char nbuf[MAXNAME + 1]; + + if (maptype[mapno] == NULL) + continue; + (void) sprintf(nbuf, "%s.%s", map->map_mname, maptype[mapno]); + s = stab(nbuf, ST_MAP, ST_FIND); + if (s == NULL) + { + syserr("Switch map %s: unknown member map %s", + map->map_mname, nbuf); + } + else + { + map->map_stack[mapno] = &s->s_map; + if (tTd(38, 4)) + printf("\tmap_stack[%d] = %s:%s\n", + mapno, s->s_map.map_class->map_cname, + nbuf); + } + } + return TRUE; +} + + +/* +** SEQ_MAP_CLOSE -- close all underlying maps +*/ + +void +seq_map_close(map) + MAP *map; +{ + int mapno; + + if (tTd(38, 9)) + printf("seq_map_close(%s)\n", map->map_mname); + + for (mapno = 0; mapno < MAXMAPSTACK; mapno++) + { + MAP *mm = map->map_stack[mapno]; + + if (mm == NULL || !bitset(MF_OPEN, mm->map_mflags)) + continue; + mm->map_class->map_close(mm); + mm->map_mflags &= ~(MF_OPEN|MF_WRITABLE); + } +} + + +/* +** SEQ_MAP_LOOKUP -- sequenced map lookup +*/ + +char * +seq_map_lookup(map, key, args, pstat) + MAP *map; + char *key; + char **args; + int *pstat; +{ + int mapno; + int mapbit = 0x01; + bool tempfail = FALSE; + + if (tTd(38, 20)) + printf("seq_map_lookup(%s, %s)\n", map->map_mname, key); + + for (mapno = 0; mapno < MAXMAPSTACK; mapbit <<= 1, mapno++) + { + MAP *mm = map->map_stack[mapno]; + char *rv; + + if (mm == NULL) + continue; + if (!bitset(MF_OPEN, mm->map_mflags)) + { + if (bitset(mapbit, map->map_return[MA_UNAVAIL])) + { + *pstat = EX_UNAVAILABLE; + return NULL; + } + continue; + } + *pstat = EX_OK; + rv = mm->map_class->map_lookup(mm, key, args, pstat); + if (rv != NULL) + return rv; + if (*pstat == EX_TEMPFAIL) + { + if (bitset(mapbit, map->map_return[MA_TRYAGAIN])) + return NULL; + tempfail = TRUE; + } + else if (bitset(mapbit, map->map_return[MA_NOTFOUND])) + break; + } + if (tempfail) + *pstat = EX_TEMPFAIL; + else if (*pstat == EX_OK) + *pstat = EX_NOTFOUND; + return NULL; +} + + +/* +** SEQ_MAP_STORE -- sequenced map store +*/ + +void +seq_map_store(map, key, val) + MAP *map; + char *key; + char *val; +{ + int mapno; + + if (tTd(38, 12)) + printf("seq_map_store(%s, %s, %s)\n", + map->map_mname, key, val); + + for (mapno = 0; mapno < MAXMAPSTACK; mapno++) + { + MAP *mm = map->map_stack[mapno]; + + if (mm == NULL || !bitset(MF_WRITABLE, mm->map_mflags)) + continue; + + mm->map_class->map_store(mm, key, val); + return; + } + syserr("seq_map_store(%s, %s, %s): no writable map", + map->map_mname, key, val); +} +/* +** NULL stubs +*/ + +bool +null_map_open(map, mode) + MAP *map; + int mode; +{ + return TRUE; +} + +void +null_map_close(map) + MAP *map; +{ + return; +} + +char * +null_map_lookup(map, key, args, pstat) + MAP *map; + char *key; + char **args; + int *pstat; +{ + *pstat = EX_NOTFOUND; + return NULL; +} + +void +null_map_store(map, key, val) + MAP *map; + char *key; + char *val; +{ + return; +} + + +/* +** BOGUS stubs +*/ + +char * +bogus_map_lookup(map, key, args, pstat) + MAP *map; + char *key; + char **args; + int *pstat; +{ + *pstat = EX_TEMPFAIL; + return NULL; +} + +MAPCLASS BogusMapClass = +{ + "bogus-map", NULL, 0, + NULL, bogus_map_lookup, null_map_store, + null_map_open, null_map_close, +}; diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c new file mode 100644 index 000000000000..ee0da2d1f324 --- /dev/null +++ b/usr.sbin/sendmail/src/mci.c @@ -0,0 +1,425 @@ +/* + * Copyright (c) 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)mci.c 8.22 (Berkeley) 11/18/95"; +#endif /* not lint */ + +#include "sendmail.h" + +/* +** Mail Connection Information (MCI) Caching Module. +** +** There are actually two separate things cached. The first is +** the set of all open connections -- these are stored in a +** (small) list. The second is stored in the symbol table; it +** has the overall status for all hosts, whether or not there +** is a connection open currently. +** +** There should never be too many connections open (since this +** could flood the socket table), nor should a connection be +** allowed to sit idly for too long. +** +** MaxMciCache is the maximum number of open connections that +** will be supported. +** +** MciCacheTimeout is the time (in seconds) that a connection +** is permitted to survive without activity. +** +** We actually try any cached connections by sending a NOOP +** before we use them; if the NOOP fails we close down the +** connection and reopen it. Note that this means that a +** server SMTP that doesn't support NOOP will hose the +** algorithm -- but that doesn't seem too likely. +*/ + +MCI **MciCache; /* the open connection cache */ + +extern void mci_uncache __P((MCI **, bool)); +/* +** MCI_CACHE -- enter a connection structure into the open connection cache +** +** This may cause something else to be flushed. +** +** Parameters: +** mci -- the connection to cache. +** +** Returns: +** none. +*/ + +void +mci_cache(mci) + register MCI *mci; +{ + register MCI **mcislot; + extern MCI **mci_scan(); + + /* + ** Find the best slot. This may cause expired connections + ** to be closed. + */ + + mcislot = mci_scan(mci); + if (mcislot == NULL) + { + /* we don't support caching */ + return; + } + + /* if this is already cached, we are done */ + if (bitset(MCIF_CACHED, mci->mci_flags)) + return; + + /* otherwise we may have to clear the slot */ + if (*mcislot != NULL) + mci_uncache(mcislot, TRUE); + + if (tTd(42, 5)) + printf("mci_cache: caching %x (%s) in slot %d\n", + mci, mci->mci_host, mcislot - MciCache); +#ifdef LOG + if (tTd(91, 100)) + syslog(LOG_DEBUG, "%s: mci_cache: caching %x (%.100s) in slot %d", + CurEnv->e_id ? CurEnv->e_id : "NOQUEUE", + mci, mci->mci_host, mcislot - MciCache); +#endif + + *mcislot = mci; + mci->mci_flags |= MCIF_CACHED; +} +/* +** MCI_SCAN -- scan the cache, flush junk, and return best slot +** +** Parameters: +** savemci -- never flush this one. Can be null. +** +** Returns: +** The LRU (or empty) slot. +*/ + +MCI ** +mci_scan(savemci) + MCI *savemci; +{ + time_t now; + register MCI **bestmci; + register MCI *mci; + register int i; + + if (MaxMciCache <= 0) + { + /* we don't support caching */ + return NULL; + } + + if (MciCache == NULL) + { + /* first call */ + MciCache = (MCI **) xalloc(MaxMciCache * sizeof *MciCache); + bzero((char *) MciCache, MaxMciCache * sizeof *MciCache); + return (&MciCache[0]); + } + + now = curtime(); + bestmci = &MciCache[0]; + for (i = 0; i < MaxMciCache; i++) + { + mci = MciCache[i]; + if (mci == NULL || mci->mci_state == MCIS_CLOSED) + { + bestmci = &MciCache[i]; + continue; + } + if (mci->mci_lastuse + MciCacheTimeout < now && mci != savemci) + { + /* connection idle too long -- close it */ + bestmci = &MciCache[i]; + mci_uncache(bestmci, TRUE); + continue; + } + if (*bestmci == NULL) + continue; + if (mci->mci_lastuse < (*bestmci)->mci_lastuse) + bestmci = &MciCache[i]; + } + return bestmci; +} +/* +** MCI_UNCACHE -- remove a connection from a slot. +** +** May close a connection. +** +** Parameters: +** mcislot -- the slot to empty. +** doquit -- if TRUE, send QUIT protocol on this connection. +** if FALSE, we are assumed to be in a forked child; +** all we want to do is close the file(s). +** +** Returns: +** none. +*/ + +void +mci_uncache(mcislot, doquit) + register MCI **mcislot; + bool doquit; +{ + register MCI *mci; + extern ENVELOPE BlankEnvelope; + + mci = *mcislot; + if (mci == NULL) + return; + *mcislot = NULL; + + if (tTd(42, 5)) + printf("mci_uncache: uncaching %x (%s) from slot %d (%d)\n", + mci, mci->mci_host, mcislot - MciCache, doquit); +#ifdef LOG + if (tTd(91, 100)) + syslog(LOG_DEBUG, "%s: mci_uncache: uncaching %x (%.100s) from slot %d (%d)", + CurEnv->e_id ? CurEnv->e_id : "NOQUEUE", + mci, mci->mci_host, mcislot - MciCache, doquit); +#endif + +#ifdef SMTP + if (doquit) + { + message("Closing connection to %s", mci->mci_host); + + mci->mci_flags &= ~MCIF_CACHED; + + /* only uses the envelope to flush the transcript file */ + if (mci->mci_state != MCIS_CLOSED) + smtpquit(mci->mci_mailer, mci, &BlankEnvelope); +#ifdef XLA + xla_host_end(mci->mci_host); +#endif + } + else +#endif + { + if (mci->mci_in != NULL) + xfclose(mci->mci_in, "mci_uncache", "mci_in"); + if (mci->mci_out != NULL) + xfclose(mci->mci_out, "mci_uncache", "mci_out"); + mci->mci_in = mci->mci_out = NULL; + mci->mci_state = MCIS_CLOSED; + mci->mci_exitstat = EX_OK; + mci->mci_errno = 0; + mci->mci_flags = 0; + } +} +/* +** MCI_FLUSH -- flush the entire cache +** +** Parameters: +** doquit -- if TRUE, send QUIT protocol. +** if FALSE, just close the connection. +** allbut -- but leave this one open. +** +** Returns: +** none. +*/ + +void +mci_flush(doquit, allbut) + bool doquit; + MCI *allbut; +{ + register int i; + + if (MciCache == NULL) + return; + + for (i = 0; i < MaxMciCache; i++) + if (allbut != MciCache[i]) + mci_uncache(&MciCache[i], doquit); +} +/* +** MCI_GET -- get information about a particular host +*/ + +MCI * +mci_get(host, m) + char *host; + MAILER *m; +{ + register MCI *mci; + register STAB *s; + extern MCI **mci_scan(); + +#ifdef DAEMON + extern SOCKADDR CurHostAddr; + + /* clear CurHostAddr so we don't get a bogus address with this name */ + bzero(&CurHostAddr, sizeof CurHostAddr); +#endif + + /* clear out any expired connections */ + (void) mci_scan(NULL); + + if (m->m_mno < 0) + syserr("negative mno %d (%s)", m->m_mno, m->m_name); + s = stab(host, ST_MCI + m->m_mno, ST_ENTER); + mci = &s->s_mci; + mci->mci_host = s->s_name; + + if (tTd(42, 2)) + { + printf("mci_get(%s %s): mci_state=%d, _flags=%x, _exitstat=%d, _errno=%d\n", + host, m->m_name, mci->mci_state, mci->mci_flags, + mci->mci_exitstat, mci->mci_errno); + } + +#ifdef SMTP + if (mci->mci_state == MCIS_OPEN) + { + /* poke the connection to see if it's still alive */ + smtpprobe(mci); + + /* reset the stored state in the event of a timeout */ + if (mci->mci_state != MCIS_OPEN) + { + mci->mci_errno = 0; + mci->mci_exitstat = EX_OK; + mci->mci_state = MCIS_CLOSED; + } +# ifdef DAEMON + else + { + /* get peer host address for logging reasons only */ + /* (this should really be in the mci struct) */ + int socksize = sizeof CurHostAddr; + + (void) getpeername(fileno(mci->mci_in), + (struct sockaddr *) &CurHostAddr, &socksize); + } +# endif + } +#endif +#ifdef MAYBE_NEXT_RELEASE + if (mci->mci_state == MCIS_CLOSED) + { + time_t now = curtime(); + + /* if this info is stale, ignore it */ + if (now > mci->mci_lastuse + MciInfoTimeout) + { + mci->mci_lastuse = now; + mci->mci_errno = 0; + mci->mci_exitstat = EX_OK; + } + } +#endif + + return mci; +} +/* +** MCI_DUMP -- dump the contents of an MCI structure. +** +** Parameters: +** mci -- the MCI structure to dump. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +void +mci_dump(mci, logit) + register MCI *mci; + bool logit; +{ + register char *p; + char *sep; + char buf[4000]; + extern char *ctime(); + + sep = logit ? " " : "\n\t"; + p = buf; + sprintf(p, "MCI@%x: ", mci); + p += strlen(p); + if (mci == NULL) + { + sprintf(p, "NULL"); + goto printit; + } + sprintf(p, "flags=%x, errno=%d, herrno=%d, exitstat=%d, state=%d, pid=%d,%s", + mci->mci_flags, mci->mci_errno, mci->mci_herrno, + mci->mci_exitstat, mci->mci_state, mci->mci_pid, sep); + p += strlen(p); + sprintf(p, "maxsize=%ld, phase=%s, mailer=%s,%s", + mci->mci_maxsize, + mci->mci_phase == NULL ? "NULL" : mci->mci_phase, + mci->mci_mailer == NULL ? "NULL" : mci->mci_mailer->m_name, + sep); + p += strlen(p); + sprintf(p, "host=%s, lastuse=%s", + mci->mci_host == NULL ? "NULL" : mci->mci_host, + ctime(&mci->mci_lastuse)); +printit: +#ifdef LOG + if (logit) + syslog(LOG_DEBUG, "%.1000s", buf); + else +#endif + printf("%s\n", buf); +} +/* +** MCI_DUMP_ALL -- print the entire MCI cache +** +** Parameters: +** logit -- if set, log the result instead of printing +** to stdout. +** +** Returns: +** none. +*/ + +void +mci_dump_all(logit) + bool logit; +{ + register int i; + + if (MciCache == NULL) + return; + + for (i = 0; i < MaxMciCache; i++) + mci_dump(MciCache[i], logit); +} diff --git a/usr.sbin/sendmail/src/mime.c b/usr.sbin/sendmail/src/mime.c new file mode 100644 index 000000000000..acbc04ca617f --- /dev/null +++ b/usr.sbin/sendmail/src/mime.c @@ -0,0 +1,866 @@ +/* + * Copyright (c) 1994 Eric P. Allman + * Copyright (c) 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +# include "sendmail.h" +# include <string.h> + +#ifndef lint +static char sccsid[] = "@(#)mime.c 8.30 (Berkeley) 10/31/95"; +#endif /* not lint */ + +/* +** MIME support. +** +** I am indebted to John Beck of Hewlett-Packard, who contributed +** his code to me for inclusion. As it turns out, I did not use +** his code since he used a "minimum change" approach that used +** several temp files, and I wanted a "minimum impact" approach +** that would avoid copying. However, looking over his code +** helped me cement my understanding of the problem. +** +** I also looked at, but did not directly use, Nathaniel +** Borenstein's "code.c" module. Again, it functioned as +** a file-to-file translator, which did not fit within my +** design bounds, but it was a useful base for understanding +** the problem. +*/ + +#if MIME8TO7 + +/* character set for hex and base64 encoding */ +char Base16Code[] = "0123456789ABCDEF"; +char Base64Code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* types of MIME boundaries */ +#define MBT_SYNTAX 0 /* syntax error */ +#define MBT_NOTSEP 1 /* not a boundary */ +#define MBT_INTERMED 2 /* intermediate boundary (no trailing --) */ +#define MBT_FINAL 3 /* final boundary (trailing -- included) */ + +static char *MimeBoundaryNames[] = +{ + "SYNTAX", "NOTSEP", "INTERMED", "FINAL" +}; +/* +** MIME8TO7 -- output 8 bit body in 7 bit format +** +** The header has already been output -- this has to do the +** 8 to 7 bit conversion. It would be easy if we didn't have +** to deal with nested formats (multipart/xxx and message/rfc822). +** +** We won't be called if we don't have to do a conversion, and +** appropriate MIME-Version: and Content-Type: fields have been +** output. Any Content-Transfer-Encoding: field has not been +** output, and we can add it here. +** +** Parameters: +** mci -- mailer connection information. +** header -- the header for this body part. +** e -- envelope. +** boundaries -- the currently pending message boundaries. +** NULL if we are processing the outer portion. +** flags -- to tweak processing. +** +** Returns: +** An indicator of what terminated the message part: +** MBT_FINAL -- the final boundary +** MBT_INTERMED -- an intermediate boundary +** MBT_NOTSEP -- an end of file +*/ + +struct args +{ + char *field; /* name of field */ + char *value; /* value of that field */ +}; + +int +mime8to7(mci, header, e, boundaries, flags) + register MCI *mci; + HDR *header; + register ENVELOPE *e; + char **boundaries; + int flags; +{ + register char *p; + int linelen; + int bt; + off_t offset; + size_t sectionsize, sectionhighbits; + int i; + char *type; + char *subtype; + char *cte; + char **pvp; + int argc = 0; + char *bp; + struct args argv[MAXMIMEARGS]; + char bbuf[128]; + char buf[MAXLINE]; + char pvpbuf[MAXLINE]; + extern u_char MimeTokenTab[256]; + + if (tTd(43, 1)) + { + printf("mime8to7: flags = %x, boundaries =", flags); + if (boundaries[0] == NULL) + printf(" <none>"); + else + { + for (i = 0; boundaries[i] != NULL; i++) + printf(" %s", boundaries[i]); + } + printf("\n"); + } + p = hvalue("Content-Transfer-Encoding", header); + if (p == NULL || + (pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL, + MimeTokenTab)) == NULL || + pvp[0] == NULL) + { + cte = NULL; + } + else + { + cataddr(pvp, NULL, buf, sizeof buf, '\0'); + cte = newstr(buf); + } + + type = subtype = NULL; + p = hvalue("Content-Type", header); + if (p == NULL) + { + if (bitset(M87F_DIGEST, flags)) + p = "message/rfc822"; + else + p = "text/plain"; + } + if (p != NULL && + (pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL, + MimeTokenTab)) != NULL && + pvp[0] != NULL) + { + if (tTd(43, 40)) + { + for (i = 0; pvp[i] != NULL; i++) + printf("pvp[%d] = \"%s\"\n", i, pvp[i]); + } + type = *pvp++; + if (*pvp != NULL && strcmp(*pvp, "/") == 0 && + *++pvp != NULL) + { + subtype = *pvp++; + } + + /* break out parameters */ + while (*pvp != NULL && argc < MAXMIMEARGS) + { + /* skip to semicolon separator */ + while (*pvp != NULL && strcmp(*pvp, ";") != 0) + pvp++; + if (*pvp++ == NULL || *pvp == NULL) + break; + + /* extract field name */ + argv[argc].field = *pvp++; + + /* see if there is a value */ + if (*pvp != NULL && strcmp(*pvp, "=") == 0 && + (*++pvp == NULL || strcmp(*pvp, ";") != 0)) + { + argv[argc].value = *pvp; + argc++; + } + } + } + + /* check for disaster cases */ + if (type == NULL) + type = "-none-"; + if (subtype == NULL) + subtype = "-none-"; + + /* don't propogate some flags more than one level into the message */ + flags &= ~M87F_DIGEST; + + /* + ** Check for cases that can not be encoded. + ** + ** For example, you can't encode certain kinds of types + ** or already-encoded messages. If we find this case, + ** just copy it through. + */ + + sprintf(buf, "%.100s/%.100s", type, subtype); + if (wordinclass(buf, 'n') || (cte != NULL && !wordinclass(cte, 'e'))) + flags |= M87F_NO8BIT; + + /* + ** Multipart requires special processing. + ** + ** Do a recursive descent into the message. + */ + + if (strcasecmp(type, "multipart") == 0 && !bitset(M87F_NO8BIT, flags)) + { + int blen; + + if (strcasecmp(subtype, "digest") == 0) + flags |= M87F_DIGEST; + + for (i = 0; i < argc; i++) + { + if (strcasecmp(argv[i].field, "boundary") == 0) + break; + } + if (i >= argc) + { + syserr("mime8to7: Content-Type: %s missing boundary", p); + p = "---"; + } + else + { + p = argv[i].value; + stripquotes(p); + } + blen = strlen(p); + if (blen > sizeof bbuf - 1) + { + syserr("mime8to7: multipart boundary \"%s\" too long", + p); + blen = sizeof bbuf - 1; + } + strncpy(bbuf, p, blen); + bbuf[blen] = '\0'; + if (tTd(43, 1)) + printf("mime8to7: multipart boundary \"%s\"\n", bbuf); + for (i = 0; i < MAXMIMENESTING; i++) + if (boundaries[i] == NULL) + break; + if (i >= MAXMIMENESTING) + syserr("mime8to7: multipart nesting boundary too deep"); + else + { + boundaries[i] = bbuf; + boundaries[i + 1] = NULL; + } + mci->mci_flags |= MCIF_INMIME; + + /* skip the early "comment" prologue */ + putline("", mci); + while (fgets(buf, sizeof buf, e->e_dfp) != NULL) + { + bt = mimeboundary(buf, boundaries); + if (bt != MBT_NOTSEP) + break; + putxline(buf, mci, PXLF_MAPFROM|PXLF_STRIP8BIT); + if (tTd(43, 99)) + printf(" ...%s", buf); + } + if (feof(e->e_dfp)) + bt = MBT_FINAL; + while (bt != MBT_FINAL) + { + auto HDR *hdr = NULL; + + sprintf(buf, "--%s", bbuf); + putline(buf, mci); + if (tTd(43, 35)) + printf(" ...%s\n", buf); + collect(e->e_dfp, FALSE, FALSE, &hdr, e); + if (tTd(43, 101)) + putline("+++after collect", mci); + putheader(mci, hdr, e); + if (tTd(43, 101)) + putline("+++after putheader", mci); + bt = mime8to7(mci, hdr, e, boundaries, flags); + } + sprintf(buf, "--%s--", bbuf); + putline(buf, mci); + if (tTd(43, 35)) + printf(" ...%s\n", buf); + boundaries[i] = NULL; + mci->mci_flags &= ~MCIF_INMIME; + + /* skip the late "comment" epilogue */ + while (fgets(buf, sizeof buf, e->e_dfp) != NULL) + { + bt = mimeboundary(buf, boundaries); + if (bt != MBT_NOTSEP) + break; + putxline(buf, mci, PXLF_MAPFROM|PXLF_STRIP8BIT); + if (tTd(43, 99)) + printf(" ...%s", buf); + } + if (feof(e->e_dfp)) + bt = MBT_FINAL; + if (tTd(43, 3)) + printf("\t\t\tmime8to7=>%s (multipart)\n", + MimeBoundaryNames[bt]); + return bt; + } + + /* + ** Message/* types -- recurse exactly once. + ** + ** Class 's' is predefined to have "rfc822" only. + */ + + if (strcasecmp(type, "message") == 0) + { + if (!wordinclass(subtype, 's')) + { + flags |= M87F_NO8BIT; + } + else + { + auto HDR *hdr = NULL; + + putline("", mci); + + mci->mci_flags |= MCIF_INMIME; + collect(e->e_dfp, FALSE, FALSE, &hdr, e); + if (tTd(43, 101)) + putline("+++after collect", mci); + putheader(mci, hdr, e); + if (tTd(43, 101)) + putline("+++after putheader", mci); + if (hvalue("MIME-Version", hdr) == NULL) + putline("MIME-Version: 1.0", mci); + bt = mime8to7(mci, hdr, e, boundaries, flags); + mci->mci_flags &= ~MCIF_INMIME; + return bt; + } + } + + /* + ** Non-compound body type + ** + ** Compute the ratio of seven to eight bit characters; + ** use that as a heuristic to decide how to do the + ** encoding. + */ + + sectionsize = sectionhighbits = 0; + if (!bitset(M87F_NO8BIT, flags)) + { + /* remember where we were */ + offset = ftell(e->e_dfp); + if (offset == -1) + syserr("mime8to7: cannot ftell on df%s", e->e_id); + + /* do a scan of this body type to count character types */ + while (fgets(buf, sizeof buf, e->e_dfp) != NULL) + { + if (mimeboundary(buf, boundaries) != MBT_NOTSEP) + break; + for (p = buf; *p != '\0'; p++) + { + /* count bytes with the high bit set */ + sectionsize++; + if (bitset(0200, *p)) + sectionhighbits++; + } + + /* + ** Heuristic: if 1/4 of the first 4K bytes are 8-bit, + ** assume base64. This heuristic avoids double-reading + ** large graphics or video files. + */ + + if (sectionsize >= 4096 && + sectionhighbits > sectionsize / 4) + break; + } + + /* return to the original offset for processing */ + /* XXX use relative seeks to handle >31 bit file sizes? */ + if (fseek(e->e_dfp, offset, SEEK_SET) < 0) + syserr("mime8to7: cannot fseek on df%s", e->e_id); + else + clearerr(e->e_dfp); + } + + /* + ** Heuristically determine encoding method. + ** If more than 1/8 of the total characters have the + ** eighth bit set, use base64; else use quoted-printable. + ** However, only encode binary encoded data as base64, + ** since otherwise the NL=>CRLF mapping will be a problem. + */ + + if (tTd(43, 8)) + { + printf("mime8to7: %ld high bit(s) in %ld byte(s), cte=%s\n", + sectionhighbits, sectionsize, + cte == NULL ? "[none]" : cte); + } + if (cte != NULL && strcasecmp(cte, "binary") == 0) + sectionsize = sectionhighbits; + linelen = 0; + bp = buf; + if (sectionhighbits == 0) + { + /* no encoding necessary */ + if (cte != NULL) + { + sprintf(buf, "Content-Transfer-Encoding: %.200s", cte); + putline(buf, mci); + if (tTd(43, 36)) + printf(" ...%s\n", buf); + } + putline("", mci); + mci->mci_flags &= ~MCIF_INHEADER; + while (fgets(buf, sizeof buf, e->e_dfp) != NULL) + { + bt = mimeboundary(buf, boundaries); + if (bt != MBT_NOTSEP) + break; + putline(buf, mci); + } + if (feof(e->e_dfp)) + bt = MBT_FINAL; + } + else if (sectionsize / 8 < sectionhighbits) + { + /* use base64 encoding */ + int c1, c2; + + putline("Content-Transfer-Encoding: base64", mci); + if (tTd(43, 36)) + printf(" ...Content-Transfer-Encoding: base64\n"); + putline("", mci); + mci->mci_flags &= ~MCIF_INHEADER; + while ((c1 = mime_getchar_crlf(e->e_dfp, boundaries, &bt)) != EOF) + { + if (linelen > 71) + { + *bp = '\0'; + putline(buf, mci); + linelen = 0; + bp = buf; + } + linelen += 4; + *bp++ = Base64Code[(c1 >> 2)]; + c1 = (c1 & 0x03) << 4; + c2 = mime_getchar_crlf(e->e_dfp, boundaries, &bt); + if (c2 == EOF) + { + *bp++ = Base64Code[c1]; + *bp++ = '='; + *bp++ = '='; + break; + } + c1 |= (c2 >> 4) & 0x0f; + *bp++ = Base64Code[c1]; + c1 = (c2 & 0x0f) << 2; + c2 = mime_getchar_crlf(e->e_dfp, boundaries, &bt); + if (c2 == EOF) + { + *bp++ = Base64Code[c1]; + *bp++ = '='; + break; + } + c1 |= (c2 >> 6) & 0x03; + *bp++ = Base64Code[c1]; + *bp++ = Base64Code[c2 & 0x3f]; + } + *bp = '\0'; + putline(buf, mci); + } + else + { + /* use quoted-printable encoding */ + int c1, c2; + int fromstate; + BITMAP badchars; + + /* set up map of characters that must be mapped */ + clrbitmap(badchars); + for (c1 = 0x00; c1 < 0x20; c1++) + setbitn(c1, badchars); + clrbitn('\t', badchars); + for (c1 = 0x7f; c1 < 0x100; c1++) + setbitn(c1, badchars); + setbitn('=', badchars); + if (bitnset(M_EBCDIC, mci->mci_mailer->m_flags)) + for (p = "!\"#$@[\\]^`{|}~"; *p != '\0'; p++) + setbitn(*p, badchars); + + putline("Content-Transfer-Encoding: quoted-printable", mci); + if (tTd(43, 36)) + printf(" ...Content-Transfer-Encoding: quoted-printable\n"); + putline("", mci); + mci->mci_flags &= ~MCIF_INHEADER; + fromstate = 0; + c2 = '\n'; + while ((c1 = mime_getchar(e->e_dfp, boundaries, &bt)) != EOF) + { + if (c1 == '\n') + { + if (c2 == ' ' || c2 == '\t') + { + *bp++ = '='; + *bp++ = Base16Code[(c2 >> 4) & 0x0f]; + *bp++ = Base16Code[c2 & 0x0f]; + } + if (buf[0] == '.' && bp == &buf[1]) + { + buf[0] = '='; + *bp++ = Base16Code[('.' >> 4) & 0x0f]; + *bp++ = Base16Code['.' & 0x0f]; + } + *bp = '\0'; + putline(buf, mci); + linelen = fromstate = 0; + bp = buf; + c2 = c1; + continue; + } + if (c2 == ' ' && linelen == 4 && fromstate == 4 && + bitnset(M_ESCFROM, mci->mci_mailer->m_flags)) + { + *bp++ = '='; + *bp++ = '2'; + *bp++ = '0'; + linelen += 3; + } + else if (c2 == ' ' || c2 == '\t') + { + *bp++ = c2; + linelen++; + } + if (linelen > 72 && + (linelen > 75 || c1 != '.' || + (linelen > 73 && c2 == '.'))) + { + if (linelen > 73 && c2 == '.') + bp--; + else + c2 = '\n'; + *bp++ = '='; + *bp = '\0'; + putline(buf, mci); + linelen = fromstate = 0; + bp = buf; + if (c2 == '.') + { + *bp++ = '.'; + linelen++; + } + } + if (bitnset(c1 & 0xff, badchars)) + { + *bp++ = '='; + *bp++ = Base16Code[(c1 >> 4) & 0x0f]; + *bp++ = Base16Code[c1 & 0x0f]; + linelen += 3; + } + else if (c1 != ' ' && c1 != '\t') + { + if (linelen < 4 && c1 == "From"[linelen]) + fromstate++; + *bp++ = c1; + linelen++; + } + c2 = c1; + } + + /* output any saved character */ + if (c2 == ' ' || c2 == '\t') + { + *bp++ = '='; + *bp++ = Base16Code[(c2 >> 4) & 0x0f]; + *bp++ = Base16Code[c2 & 0x0f]; + linelen += 3; + } + + if (linelen > 0 || boundaries[0] != NULL) + { + *bp = '\0'; + putline(buf, mci); + } + + } + if (tTd(43, 3)) + printf("\t\t\tmime8to7=>%s (basic)\n", MimeBoundaryNames[bt]); + return bt; +} +/* +** MIME_GETCHAR -- get a character for MIME processing +** +** Treats boundaries as EOF. +** +** Parameters: +** fp -- the input file. +** boundaries -- the current MIME boundaries. +** btp -- if the return value is EOF, *btp is set to +** the type of the boundary. +** +** Returns: +** The next character in the input stream. +*/ + +int +mime_getchar(fp, boundaries, btp) + register FILE *fp; + char **boundaries; + int *btp; +{ + int c; + static u_char *bp = NULL; + static int buflen = 0; + static bool atbol = TRUE; /* at beginning of line */ + static int bt = MBT_SYNTAX; /* boundary type of next EOF */ + static u_char buf[128]; /* need not be a full line */ + + if (buflen > 0) + { + buflen--; + return *bp++; + } + bp = buf; + buflen = 0; + c = getc(fp); + if (c == '\n') + { + /* might be part of a MIME boundary */ + *bp++ = c; + atbol = TRUE; + c = getc(fp); + if (c == '\n') + { + ungetc(c, fp); + return c; + } + } + if (c != EOF) + *bp++ = c; + else + bt = MBT_FINAL; + if (atbol && c == '-') + { + /* check for a message boundary */ + c = getc(fp); + if (c != '-') + { + if (c != EOF) + *bp++ = c; + else + bt = MBT_FINAL; + buflen = bp - buf - 1; + bp = buf; + return *bp++; + } + + /* got "--", now check for rest of separator */ + *bp++ = '-'; + while (bp < &buf[sizeof buf - 2] && + (c = getc(fp)) != EOF && c != '\n') + { + *bp++ = c; + } + *bp = '\0'; + bt = mimeboundary(&buf[1], boundaries); + switch (bt) + { + case MBT_FINAL: + case MBT_INTERMED: + /* we have a message boundary */ + buflen = 0; + *btp = bt; + return EOF; + } + + atbol = c == '\n'; + if (c != EOF) + *bp++ = c; + } + + buflen = bp - buf - 1; + if (buflen < 0) + { + *btp = bt; + return EOF; + } + bp = buf; + return *bp++; +} +/* +** MIME_GETCHAR_CRLF -- do mime_getchar, but translate NL => CRLF +** +** Parameters: +** fp -- the input file. +** boundaries -- the current MIME boundaries. +** btp -- if the return value is EOF, *btp is set to +** the type of the boundary. +** +** Returns: +** The next character in the input stream. +*/ + +int +mime_getchar_crlf(fp, boundaries, btp) + register FILE *fp; + char **boundaries; + int *btp; +{ + static bool sendlf = FALSE; + int c; + + if (sendlf) + { + sendlf = FALSE; + return '\n'; + } + c = mime_getchar(fp, boundaries, btp); + if (c == '\n') + { + sendlf = TRUE; + return '\r'; + } + return c; +} +/* +** MIMEBOUNDARY -- determine if this line is a MIME boundary & its type +** +** Parameters: +** line -- the input line. +** boundaries -- the set of currently pending boundaries. +** +** Returns: +** MBT_NOTSEP -- if this is not a separator line +** MBT_INTERMED -- if this is an intermediate separator +** MBT_FINAL -- if this is a final boundary +** MBT_SYNTAX -- if this is a boundary for the wrong +** enclosure -- i.e., a syntax error. +*/ + +int +mimeboundary(line, boundaries) + register char *line; + char **boundaries; +{ + int type = MBT_NOTSEP; + int i; + int savec; + + if (line[0] != '-' || line[1] != '-' || boundaries == NULL) + return MBT_NOTSEP; + i = strlen(line); + if (line[i - 1] == '\n') + i--; + + /* strip off trailing whitespace */ + while (line[i - 1] == ' ' || line[i - 1] == '\t') + i--; + savec = line[i]; + line[i] = '\0'; + + if (tTd(43, 5)) + printf("mimeboundary: line=\"%s\"... ", line); + + /* check for this as an intermediate boundary */ + if (isboundary(&line[2], boundaries) >= 0) + type = MBT_INTERMED; + else if (i > 2 && strncmp(&line[i - 2], "--", 2) == 0) + { + /* check for a final boundary */ + line[i - 2] = '\0'; + if (isboundary(&line[2], boundaries) >= 0) + type = MBT_FINAL; + line[i - 2] = '-'; + } + + line[i] = savec; + if (tTd(43, 5)) + printf("%s\n", MimeBoundaryNames[type]); + return type; +} +/* +** DEFCHARSET -- return default character set for message +** +** The first choice for character set is for the mailer +** corresponding to the envelope sender. If neither that +** nor the global configuration file has a default character +** set defined, return "unknown-8bit" as recommended by +** RFC 1428 section 3. +** +** Parameters: +** e -- the envelope for this message. +** +** Returns: +** The default character set for that mailer. +*/ + +char * +defcharset(e) + register ENVELOPE *e; +{ + if (e != NULL && e->e_from.q_mailer != NULL && + e->e_from.q_mailer->m_defcharset != NULL) + return e->e_from.q_mailer->m_defcharset; + if (DefaultCharSet != NULL) + return DefaultCharSet; + return "unknown-8bit"; +} +/* +** ISBOUNDARY -- is a given string a currently valid boundary? +** +** Parameters: +** line -- the current input line. +** boundaries -- the list of valid boundaries. +** +** Returns: +** The index number in boundaries if the line is found. +** -1 -- otherwise. +** +*/ + +int +isboundary(line, boundaries) + char *line; + char **boundaries; +{ + register int i; + + for (i = 0; boundaries[i] != NULL; i++) + { + if (strcmp(line, boundaries[i]) == 0) + return i; + } + return -1; +} + +#endif /* MIME */ diff --git a/usr.sbin/sendmail/src/parseaddr.c b/usr.sbin/sendmail/src/parseaddr.c new file mode 100644 index 000000000000..e8bda9c4be58 --- /dev/null +++ b/usr.sbin/sendmail/src/parseaddr.c @@ -0,0 +1,2157 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)parseaddr.c 8.86 (Berkeley) 9/28/95"; +#endif /* not lint */ + +# include "sendmail.h" + +/* +** PARSEADDR -- Parse an address +** +** Parses an address and breaks it up into three parts: a +** net to transmit the message on, the host to transmit it +** to, and a user on that host. These are loaded into an +** ADDRESS header with the values squirreled away if necessary. +** The "user" part may not be a real user; the process may +** just reoccur on that machine. For example, on a machine +** with an arpanet connection, the address +** csvax.bill@berkeley +** will break up to a "user" of 'csvax.bill' and a host +** of 'berkeley' -- to be transmitted over the arpanet. +** +** Parameters: +** addr -- the address to parse. +** a -- a pointer to the address descriptor buffer. +** If NULL, a header will be created. +** flags -- describe detail for parsing. See RF_ definitions +** in sendmail.h. +** delim -- the character to terminate the address, passed +** to prescan. +** delimptr -- if non-NULL, set to the location of the +** delim character that was found. +** e -- the envelope that will contain this address. +** +** Returns: +** A pointer to the address descriptor header (`a' if +** `a' is non-NULL). +** NULL on error. +** +** Side Effects: +** none +*/ + +/* following delimiters are inherent to the internal algorithms */ +# define DELIMCHARS "()<>,;\r\n" /* default word delimiters */ + +ADDRESS * +parseaddr(addr, a, flags, delim, delimptr, e) + char *addr; + register ADDRESS *a; + int flags; + int delim; + char **delimptr; + register ENVELOPE *e; +{ + register char **pvp; + auto char *delimptrbuf; + bool queueup; + char pvpbuf[PSBUFSIZE]; + extern ADDRESS *buildaddr(); + extern bool invalidaddr(); + extern void allocaddr __P((ADDRESS *, int, char *)); + + /* + ** Initialize and prescan address. + */ + + e->e_to = addr; + if (tTd(20, 1)) + printf("\n--parseaddr(%s)\n", addr); + + if (delimptr == NULL) + delimptr = &delimptrbuf; + + pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr, NULL); + if (pvp == NULL) + { + if (tTd(20, 1)) + printf("parseaddr-->NULL\n"); + return (NULL); + } + + if (invalidaddr(addr, delim == '\0' ? NULL : *delimptr)) + { + if (tTd(20, 1)) + printf("parseaddr-->bad address\n"); + return NULL; + } + + /* + ** Save addr if we are going to have to. + ** + ** We have to do this early because there is a chance that + ** the map lookups in the rewriting rules could clobber + ** static memory somewhere. + */ + + if (bitset(RF_COPYPADDR, flags) && addr != NULL) + { + char savec = **delimptr; + + if (savec != '\0') + **delimptr = '\0'; + e->e_to = addr = newstr(addr); + if (savec != '\0') + **delimptr = savec; + } + + /* + ** Apply rewriting rules. + ** Ruleset 0 does basic parsing. It must resolve. + */ + + queueup = FALSE; + if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL) + queueup = TRUE; + if (rewrite(pvp, 0, 0, e) == EX_TEMPFAIL) + queueup = TRUE; + + + /* + ** Build canonical address from pvp. + */ + + a = buildaddr(pvp, a, flags, e); + + /* + ** Make local copies of the host & user and then + ** transport them out. + */ + + allocaddr(a, flags, addr); + if (bitset(QBADADDR, a->q_flags)) + return a; + + /* + ** If there was a parsing failure, mark it for queueing. + */ + + if (queueup) + { + char *msg = "Transient parse error -- message queued for future delivery"; + + if (e->e_sendmode == SM_DEFER) + msg = "Deferring message until queue run"; + if (tTd(20, 1)) + printf("parseaddr: queuing message\n"); + message(msg); + if (e->e_message == NULL && e->e_sendmode != SM_DEFER) + e->e_message = newstr(msg); + a->q_flags |= QQUEUEUP; + a->q_status = "4.4.3"; + } + + /* + ** Compute return value. + */ + + if (tTd(20, 1)) + { + printf("parseaddr-->"); + printaddr(a, FALSE); + } + + return (a); +} +/* +** INVALIDADDR -- check for address containing meta-characters +** +** Parameters: +** addr -- the address to check. +** +** Returns: +** TRUE -- if the address has any "wierd" characters +** FALSE -- otherwise. +*/ + +bool +invalidaddr(addr, delimptr) + register char *addr; + char *delimptr; +{ + char savedelim = '\0'; + + if (delimptr != NULL) + { + savedelim = *delimptr; + if (savedelim != '\0') + *delimptr = '\0'; + } +#if 0 + /* for testing.... */ + if (strcmp(addr, "INvalidADDR") == 0) + { + usrerr("553 INvalid ADDRess"); + goto addrfailure; + } +#endif + for (; *addr != '\0'; addr++) + { + if ((*addr & 0340) == 0200) + break; + } + if (*addr == '\0') + { + if (delimptr != NULL && savedelim != '\0') + *delimptr = savedelim; + return FALSE; + } + setstat(EX_USAGE); + usrerr("553 Address contained invalid control characters"); + addrfailure: + if (delimptr != NULL && savedelim != '\0') + *delimptr = savedelim; + return TRUE; +} +/* +** ALLOCADDR -- do local allocations of address on demand. +** +** Also lowercases the host name if requested. +** +** Parameters: +** a -- the address to reallocate. +** flags -- the copy flag (see RF_ definitions in sendmail.h +** for a description). +** paddr -- the printname of the address. +** +** Returns: +** none. +** +** Side Effects: +** Copies portions of a into local buffers as requested. +*/ + +void +allocaddr(a, flags, paddr) + register ADDRESS *a; + int flags; + char *paddr; +{ + if (tTd(24, 4)) + printf("allocaddr(flags=%x, paddr=%s)\n", flags, paddr); + + a->q_paddr = paddr; + + if (a->q_user == NULL) + a->q_user = ""; + if (a->q_host == NULL) + a->q_host = ""; + + if (bitset(RF_COPYPARSE, flags)) + { + a->q_host = newstr(a->q_host); + if (a->q_user != a->q_paddr) + a->q_user = newstr(a->q_user); + } + + if (a->q_paddr == NULL) + a->q_paddr = a->q_user; +} +/* +** PRESCAN -- Prescan name and make it canonical +** +** Scans a name and turns it into a set of tokens. This process +** deletes blanks and comments (in parentheses). +** +** This routine knows about quoted strings and angle brackets. +** +** There are certain subtleties to this routine. The one that +** comes to mind now is that backslashes on the ends of names +** are silently stripped off; this is intentional. The problem +** is that some versions of sndmsg (like at LBL) set the kill +** character to something other than @ when reading addresses; +** so people type "csvax.eric\@berkeley" -- which screws up the +** berknet mailer. +** +** Parameters: +** addr -- the name to chomp. +** delim -- the delimiter for the address, normally +** '\0' or ','; \0 is accepted in any case. +** If '\t' then we are reading the .cf file. +** pvpbuf -- place to put the saved text -- note that +** the pointers are static. +** pvpbsize -- size of pvpbuf. +** delimptr -- if non-NULL, set to the location of the +** terminating delimiter. +** toktab -- if set, a token table to use for parsing. +** If NULL, use the default table. +** +** Returns: +** A pointer to a vector of tokens. +** NULL on error. +*/ + +/* states and character types */ +# define OPR 0 /* operator */ +# define ATM 1 /* atom */ +# define QST 2 /* in quoted string */ +# define SPC 3 /* chewing up spaces */ +# define ONE 4 /* pick up one character */ +# define ILL 5 /* illegal character */ + +# define NSTATES 6 /* number of states */ +# define TYPE 017 /* mask to select state type */ + +/* meta bits for table */ +# define M 020 /* meta character; don't pass through */ +# define B 040 /* cause a break */ +# define MB M|B /* meta-break */ + +static short StateTab[NSTATES][NSTATES] = +{ + /* oldst chtype> OPR ATM QST SPC ONE ILL */ + /*OPR*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|MB, + /*ATM*/ OPR|B, ATM, QST|B, SPC|MB, ONE|B, ILL|MB, + /*QST*/ QST, QST, OPR, QST, QST, QST, + /*SPC*/ OPR, ATM, QST, SPC|M, ONE, ILL|MB, + /*ONE*/ OPR, OPR, OPR, OPR, OPR, ILL|MB, + /*ILL*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|M, +}; + +/* token type table -- it gets modified with $o characters */ +static u_char TokTypeTab[256] = +{ + /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM, + /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* sp ! " # $ % & ' ( ) * + , - . / */ + SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM, + /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* @ A B C D E F G H I J K L M N O */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* P Q R S T U V W X Y Z [ \ ] ^ _ */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* ` a b c d e f g h i j k l m n o */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* p q r s t u v w x y z { | } ~ del */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + + /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ + OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR, OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR, + /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ + OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR, OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR, + /* sp ! " # $ % & ' ( ) * + , - . / */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* @ A B C D E F G H I J K L M N O */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* P Q R S T U V W X Y Z [ \ ] ^ _ */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* ` a b c d e f g h i j k l m n o */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* p q r s t u v w x y z { | } ~ del */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, +}; + +/* token type table for MIME parsing */ +u_char MimeTokenTab[256] = +{ + /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,SPC,SPC,SPC,SPC,SPC,ILL,ILL, + /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, + /* sp ! " # $ % & ' ( ) * + , - . / */ + SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, ATM,SPC,ATM,ATM,OPR,ATM,ATM,OPR, + /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,OPR,OPR,OPR,OPR,OPR,OPR, + /* @ A B C D E F G H I J K L M N O */ + OPR,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* P Q R S T U V W X Y Z [ \ ] ^ _ */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,OPR,OPR,OPR,ATM,ATM, + /* ` a b c d e f g h i j k l m n o */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + /* p q r s t u v w x y z { | } ~ del */ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + + /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, + /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, + /* sp ! " # $ % & ' ( ) * + , - . / */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, + /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, + /* @ A B C D E F G H I J K L M N O */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, + /* P Q R S T U V W X Y Z [ \ ] ^ _ */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, + /* ` a b c d e f g h i j k l m n o */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, + /* p q r s t u v w x y z { | } ~ del */ + ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, +}; + + +# define NOCHAR -1 /* signal nothing in lookahead token */ + +char ** +prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) + char *addr; + int delim; + char pvpbuf[]; + int pvpbsize; + char **delimptr; + u_char *toktab; +{ + register char *p; + register char *q; + register int c; + char **avp; + bool bslashmode; + int cmntcnt; + int anglecnt; + char *tok; + int state; + int newstate; + char *saveto = CurEnv->e_to; + static char *av[MAXATOM+1]; + static char firsttime = TRUE; + extern int errno; + + if (firsttime) + { + /* initialize the token type table */ + char obuf[50]; + + firsttime = FALSE; + if (OperatorChars == NULL) + { + if (ConfigLevel < 7) + OperatorChars = macvalue('o', CurEnv); + if (OperatorChars == NULL) + OperatorChars = ".:@[]"; + } + expand(OperatorChars, obuf, sizeof obuf - sizeof DELIMCHARS, CurEnv); + strcat(obuf, DELIMCHARS); + for (p = obuf; *p != '\0'; p++) + { + if (TokTypeTab[*p & 0xff] == ATM) + TokTypeTab[*p & 0xff] = OPR; + } + } + if (toktab == NULL) + toktab = TokTypeTab; + + /* make sure error messages don't have garbage on them */ + errno = 0; + + q = pvpbuf; + bslashmode = FALSE; + cmntcnt = 0; + anglecnt = 0; + avp = av; + state = ATM; + c = NOCHAR; + p = addr; + CurEnv->e_to = p; + if (tTd(22, 11)) + { + printf("prescan: "); + xputs(p); + (void) putchar('\n'); + } + + do + { + /* read a token */ + tok = q; + for (;;) + { + /* store away any old lookahead character */ + if (c != NOCHAR && !bslashmode) + { + /* see if there is room */ + if (q >= &pvpbuf[pvpbsize - 5]) + { + usrerr("553 Address too long"); + if (strlen(addr) > MAXNAME) + addr[MAXNAME] = '\0'; + returnnull: + if (delimptr != NULL) + *delimptr = p; + CurEnv->e_to = saveto; + return (NULL); + } + + /* squirrel it away */ + *q++ = c; + } + + /* read a new input character */ + c = *p++; + if (c == '\0') + { + /* diagnose and patch up bad syntax */ + if (state == QST) + { + usrerr("653 Unbalanced '\"'"); + c = '"'; + } + else if (cmntcnt > 0) + { + usrerr("653 Unbalanced '('"); + c = ')'; + } + else if (anglecnt > 0) + { + c = '>'; + usrerr("653 Unbalanced '<'"); + } + else + break; + + p--; + } + else if (c == delim && anglecnt <= 0 && + cmntcnt <= 0 && state != QST) + break; + + if (tTd(22, 101)) + printf("c=%c, s=%d; ", c, state); + + /* chew up special characters */ + *q = '\0'; + if (bslashmode) + { + bslashmode = FALSE; + + /* kludge \! for naive users */ + if (cmntcnt > 0) + { + c = NOCHAR; + continue; + } + else if (c != '!' || state == QST) + { + *q++ = '\\'; + continue; + } + } + + if (c == '\\') + { + bslashmode = TRUE; + } + else if (state == QST) + { + /* do nothing, just avoid next clauses */ + } + else if (c == '(') + { + cmntcnt++; + c = NOCHAR; + } + else if (c == ')') + { + if (cmntcnt <= 0) + { + usrerr("653 Unbalanced ')'"); + c = NOCHAR; + } + else + cmntcnt--; + } + else if (cmntcnt > 0) + c = NOCHAR; + else if (c == '<') + anglecnt++; + else if (c == '>') + { + if (anglecnt <= 0) + { + usrerr("653 Unbalanced '>'"); + c = NOCHAR; + } + else + anglecnt--; + } + else if (delim == ' ' && isascii(c) && isspace(c)) + c = ' '; + + if (c == NOCHAR) + continue; + + /* see if this is end of input */ + if (c == delim && anglecnt <= 0 && state != QST) + break; + + newstate = StateTab[state][toktab[c & 0xff]]; + if (tTd(22, 101)) + printf("ns=%02o\n", newstate); + state = newstate & TYPE; + if (state == ILL) + { + if (isascii(c) && isprint(c)) + usrerr("653 Illegal character %c", c); + else + usrerr("653 Illegal character 0x%02x", c); + } + if (bitset(M, newstate)) + c = NOCHAR; + if (bitset(B, newstate)) + break; + } + + /* new token */ + if (tok != q) + { + *q++ = '\0'; + if (tTd(22, 36)) + { + printf("tok="); + xputs(tok); + (void) putchar('\n'); + } + if (avp >= &av[MAXATOM]) + { + syserr("553 prescan: too many tokens"); + goto returnnull; + } + if (q - tok > MAXNAME) + { + syserr("553 prescan: token too long"); + goto returnnull; + } + *avp++ = tok; + } + } while (c != '\0' && (c != delim || anglecnt > 0)); + *avp = NULL; + p--; + if (delimptr != NULL) + *delimptr = p; + if (tTd(22, 12)) + { + printf("prescan==>"); + printav(av); + } + CurEnv->e_to = saveto; + if (av[0] == NULL) + { + if (tTd(22, 1)) + printf("prescan: null leading token\n"); + return (NULL); + } + return (av); +} +/* +** REWRITE -- apply rewrite rules to token vector. +** +** This routine is an ordered production system. Each rewrite +** rule has a LHS (called the pattern) and a RHS (called the +** rewrite); 'rwr' points the the current rewrite rule. +** +** For each rewrite rule, 'avp' points the address vector we +** are trying to match against, and 'pvp' points to the pattern. +** If pvp points to a special match value (MATCHZANY, MATCHANY, +** MATCHONE, MATCHCLASS, MATCHNCLASS) then the address in avp +** matched is saved away in the match vector (pointed to by 'mvp'). +** +** When a match between avp & pvp does not match, we try to +** back out. If we back up over MATCHONE, MATCHCLASS, or MATCHNCLASS +** we must also back out the match in mvp. If we reach a +** MATCHANY or MATCHZANY we just extend the match and start +** over again. +** +** When we finally match, we rewrite the address vector +** and try over again. +** +** Parameters: +** pvp -- pointer to token vector. +** ruleset -- the ruleset to use for rewriting. +** reclevel -- recursion level (to catch loops). +** e -- the current envelope. +** +** Returns: +** A status code. If EX_TEMPFAIL, higher level code should +** attempt recovery. +** +** Side Effects: +** pvp is modified. +*/ + +struct match +{ + char **first; /* first token matched */ + char **last; /* last token matched */ + char **pattern; /* pointer to pattern */ +}; + +# define MAXMATCH 9 /* max params per rewrite */ + + +int +rewrite(pvp, ruleset, reclevel, e) + char **pvp; + int ruleset; + int reclevel; + register ENVELOPE *e; +{ + register char *ap; /* address pointer */ + register char *rp; /* rewrite pointer */ + register char **avp; /* address vector pointer */ + register char **rvp; /* rewrite vector pointer */ + register struct match *mlp; /* cur ptr into mlist */ + register struct rewrite *rwr; /* pointer to current rewrite rule */ + int ruleno; /* current rule number */ + int rstat = EX_OK; /* return status */ + int loopcount; + struct match mlist[MAXMATCH]; /* stores match on LHS */ + char *npvp[MAXATOM+1]; /* temporary space for rebuild */ + + if (OpMode == MD_TEST || tTd(21, 1)) + { + printf("rewrite: ruleset %2d input:", ruleset); + printav(pvp); + } + if (ruleset < 0 || ruleset >= MAXRWSETS) + { + syserr("554 rewrite: illegal ruleset number %d", ruleset); + return EX_CONFIG; + } + if (reclevel++ > MaxRuleRecursion) + { + syserr("rewrite: excessive recursion (max %d), ruleset %d", + MaxRuleRecursion, ruleset); + return EX_CONFIG; + } + if (pvp == NULL) + return EX_USAGE; + + /* + ** Run through the list of rewrite rules, applying + ** any that match. + */ + + ruleno = 1; + loopcount = 0; + for (rwr = RewriteRules[ruleset]; rwr != NULL; ) + { + if (tTd(21, 12)) + { + printf("-----trying rule:"); + printav(rwr->r_lhs); + } + + /* try to match on this rule */ + mlp = mlist; + rvp = rwr->r_lhs; + avp = pvp; + if (++loopcount > 100) + { + syserr("554 Infinite loop in ruleset %d, rule %d", + ruleset, ruleno); + if (tTd(21, 1)) + { + printf("workspace: "); + printav(pvp); + } + break; + } + + while ((ap = *avp) != NULL || *rvp != NULL) + { + rp = *rvp; + if (tTd(21, 35)) + { + printf("ADVANCE rp="); + xputs(rp); + printf(", ap="); + xputs(ap); + printf("\n"); + } + if (rp == NULL) + { + /* end-of-pattern before end-of-address */ + goto backup; + } + if (ap == NULL && (*rp & 0377) != MATCHZANY && + (*rp & 0377) != MATCHZERO) + { + /* end-of-input with patterns left */ + goto backup; + } + + switch (*rp & 0377) + { + char buf[MAXLINE]; + + case MATCHCLASS: + /* match any phrase in a class */ + mlp->pattern = rvp; + mlp->first = avp; + extendclass: + ap = *avp; + if (ap == NULL) + goto backup; + mlp->last = avp++; + cataddr(mlp->first, mlp->last, buf, sizeof buf, '\0'); + if (!wordinclass(buf, rp[1])) + { + if (tTd(21, 36)) + { + printf("EXTEND rp="); + xputs(rp); + printf(", ap="); + xputs(ap); + printf("\n"); + } + goto extendclass; + } + if (tTd(21, 36)) + printf("CLMATCH\n"); + mlp++; + break; + + case MATCHNCLASS: + /* match any token not in a class */ + if (wordinclass(ap, rp[1])) + goto backup; + + /* fall through */ + + case MATCHONE: + case MATCHANY: + /* match exactly one token */ + mlp->pattern = rvp; + mlp->first = avp; + mlp->last = avp++; + mlp++; + break; + + case MATCHZANY: + /* match zero or more tokens */ + mlp->pattern = rvp; + mlp->first = avp; + mlp->last = avp - 1; + mlp++; + break; + + case MATCHZERO: + /* match zero tokens */ + break; + + case MACRODEXPAND: + /* + ** Match against run-time macro. + ** This algorithm is broken for the + ** general case (no recursive macros, + ** improper tokenization) but should + ** work for the usual cases. + */ + + ap = macvalue(rp[1], e); + mlp->first = avp; + if (tTd(21, 2)) + printf("rewrite: LHS $&%c => \"%s\"\n", + rp[1], + ap == NULL ? "(NULL)" : ap); + + if (ap == NULL) + break; + while (*ap != '\0') + { + if (*avp == NULL || + strncasecmp(ap, *avp, strlen(*avp)) != 0) + { + /* no match */ + avp = mlp->first; + goto backup; + } + ap += strlen(*avp++); + } + + /* match */ + break; + + default: + /* must have exact match */ + if (strcasecmp(rp, ap)) + goto backup; + avp++; + break; + } + + /* successful match on this token */ + rvp++; + continue; + + backup: + /* match failed -- back up */ + while (--mlp >= mlist) + { + rvp = mlp->pattern; + rp = *rvp; + avp = mlp->last + 1; + ap = *avp; + + if (tTd(21, 36)) + { + printf("BACKUP rp="); + xputs(rp); + printf(", ap="); + xputs(ap); + printf("\n"); + } + + if (ap == NULL) + { + /* run off the end -- back up again */ + continue; + } + if ((*rp & 0377) == MATCHANY || + (*rp & 0377) == MATCHZANY) + { + /* extend binding and continue */ + mlp->last = avp++; + rvp++; + mlp++; + break; + } + if ((*rp & 0377) == MATCHCLASS) + { + /* extend binding and try again */ + mlp->last = avp; + goto extendclass; + } + } + + if (mlp < mlist) + { + /* total failure to match */ + break; + } + } + + /* + ** See if we successfully matched + */ + + if (mlp < mlist || *rvp != NULL) + { + if (tTd(21, 10)) + printf("----- rule fails\n"); + rwr = rwr->r_next; + ruleno++; + loopcount = 0; + continue; + } + + rvp = rwr->r_rhs; + if (tTd(21, 12)) + { + printf("-----rule matches:"); + printav(rvp); + } + + rp = *rvp; + if ((*rp & 0377) == CANONUSER) + { + rvp++; + rwr = rwr->r_next; + ruleno++; + loopcount = 0; + } + else if ((*rp & 0377) == CANONHOST) + { + rvp++; + rwr = NULL; + } + else if ((*rp & 0377) == CANONNET) + rwr = NULL; + + /* substitute */ + for (avp = npvp; *rvp != NULL; rvp++) + { + register struct match *m; + register char **pp; + + rp = *rvp; + if ((*rp & 0377) == MATCHREPL) + { + /* substitute from LHS */ + m = &mlist[rp[1] - '1']; + if (m < mlist || m >= mlp) + { + syserr("554 rewrite: ruleset %d: replacement $%c out of bounds", + ruleset, rp[1]); + return EX_CONFIG; + } + if (tTd(21, 15)) + { + printf("$%c:", rp[1]); + pp = m->first; + while (pp <= m->last) + { + printf(" %x=\"", *pp); + (void) fflush(stdout); + printf("%s\"", *pp++); + } + printf("\n"); + } + pp = m->first; + while (pp <= m->last) + { + if (avp >= &npvp[MAXATOM]) + { + syserr("554 rewrite: expansion too long"); + return EX_DATAERR; + } + *avp++ = *pp++; + } + } + else + { + /* vanilla replacement */ + if (avp >= &npvp[MAXATOM]) + { + toolong: + syserr("554 rewrite: expansion too long"); + return EX_DATAERR; + } + if ((*rp & 0377) != MACRODEXPAND) + *avp++ = rp; + else + { + *avp = macvalue(rp[1], e); + if (tTd(21, 2)) + printf("rewrite: RHS $&%c => \"%s\"\n", + rp[1], + *avp == NULL ? "(NULL)" : *avp); + if (*avp != NULL) + avp++; + } + } + } + *avp++ = NULL; + + /* + ** Check for any hostname/keyword lookups. + */ + + for (rvp = npvp; *rvp != NULL; rvp++) + { + char **hbrvp; + char **xpvp; + int trsize; + char *replac; + int endtoken; + STAB *map; + char *mapname; + char **key_rvp; + char **arg_rvp; + char **default_rvp; + char buf[MAXNAME + 1]; + char *pvpb1[MAXATOM + 1]; + char *argvect[10]; + char pvpbuf[PSBUFSIZE]; + char *nullpvp[1]; + + if ((**rvp & 0377) != HOSTBEGIN && + (**rvp & 0377) != LOOKUPBEGIN) + continue; + + /* + ** Got a hostname/keyword lookup. + ** + ** This could be optimized fairly easily. + */ + + hbrvp = rvp; + if ((**rvp & 0377) == HOSTBEGIN) + { + endtoken = HOSTEND; + mapname = "host"; + } + else + { + endtoken = LOOKUPEND; + mapname = *++rvp; + } + map = stab(mapname, ST_MAP, ST_FIND); + if (map == NULL) + syserr("554 rewrite: map %s not found", mapname); + + /* extract the match part */ + key_rvp = ++rvp; + default_rvp = NULL; + arg_rvp = argvect; + xpvp = NULL; + replac = pvpbuf; + while (*rvp != NULL && (**rvp & 0377) != endtoken) + { + int nodetype = **rvp & 0377; + + if (nodetype != CANONHOST && nodetype != CANONUSER) + { + rvp++; + continue; + } + + *rvp++ = NULL; + + if (xpvp != NULL) + { + cataddr(xpvp, NULL, replac, + &pvpbuf[sizeof pvpbuf] - replac, + '\0'); + *++arg_rvp = replac; + replac += strlen(replac) + 1; + xpvp = NULL; + } + switch (nodetype) + { + case CANONHOST: + xpvp = rvp; + break; + + case CANONUSER: + default_rvp = rvp; + break; + } + } + if (*rvp != NULL) + *rvp++ = NULL; + if (xpvp != NULL) + { + cataddr(xpvp, NULL, replac, + &pvpbuf[sizeof pvpbuf] - replac, + '\0'); + *++arg_rvp = replac; + } + *++arg_rvp = NULL; + + /* save the remainder of the input string */ + trsize = (int) (avp - rvp + 1) * sizeof *rvp; + bcopy((char *) rvp, (char *) pvpb1, trsize); + + /* look it up */ + cataddr(key_rvp, NULL, buf, sizeof buf, '\0'); + argvect[0] = buf; + if (e->e_sendmode == SM_DEFER) + { + /* don't do any map lookups */ + if (tTd(60, 1)) + printf("map_lookup(%s, %s) => DEFERRED\n", + mapname, buf); + replac = NULL; + rstat = EX_TEMPFAIL; + } + else if (map != NULL && bitset(MF_OPEN, map->s_map.map_mflags)) + { + auto int stat = EX_OK; + + if (!bitset(MF_KEEPQUOTES, map->s_map.map_mflags)) + stripquotes(buf); + + /* XXX should try to auto-open the map here */ + + if (tTd(60, 1)) + printf("map_lookup(%s, %s) => ", + mapname, buf); + replac = (*map->s_map.map_class->map_lookup)(&map->s_map, + buf, argvect, &stat); + if (tTd(60, 1)) + printf("%s (%d)\n", + replac ? replac : "NOT FOUND", + stat); + + /* should recover if stat == EX_TEMPFAIL */ + if (stat == EX_TEMPFAIL) + { + rstat = EX_TEMPFAIL; + if (tTd(60, 1)) + printf("map_lookup(%s, %s) tempfail: errno=%d\n", + mapname, buf, errno); + if (e->e_message == NULL) + { + char mbuf[300]; + + sprintf(mbuf, "%.80s map: lookup (%s): deferred", + mapname, + shortenstring(buf, 203)); + e->e_message = newstr(mbuf); + } + } + } + else + replac = NULL; + + /* if no replacement, use default */ + if (replac == NULL && default_rvp != NULL) + { + /* create the default */ + cataddr(default_rvp, NULL, buf, sizeof buf, '\0'); + replac = buf; + } + + if (replac == NULL) + { + xpvp = key_rvp; + } + else if (*replac == '\0') + { + /* null replacement */ + nullpvp[0] = NULL; + xpvp = nullpvp; + } + else + { + /* scan the new replacement */ + xpvp = prescan(replac, '\0', pvpbuf, + sizeof pvpbuf, NULL, NULL); + if (xpvp == NULL) + { + /* prescan already printed error */ + return EX_DATAERR; + } + } + + /* append it to the token list */ + for (avp = hbrvp; *xpvp != NULL; xpvp++) + { + *avp++ = newstr(*xpvp); + if (avp >= &npvp[MAXATOM]) + goto toolong; + } + + /* restore the old trailing information */ + for (xpvp = pvpb1; (*avp++ = *xpvp++) != NULL; ) + if (avp >= &npvp[MAXATOM]) + goto toolong; + + break; + } + + /* + ** Check for subroutine calls. + */ + + if (*npvp != NULL && (**npvp & 0377) == CALLSUBR) + { + int stat; + + if (npvp[1] == NULL) + { + syserr("parseaddr: NULL subroutine call in ruleset %d, rule %d", + ruleset, ruleno); + *pvp = NULL; + } + else + { + int ruleset; + STAB *s; + + bcopy((char *) &npvp[2], (char *) pvp, + (int) (avp - npvp - 2) * sizeof *avp); + if (tTd(21, 3)) + printf("-----callsubr %s\n", npvp[1]); + ruleset = strtorwset(npvp[1], NULL, ST_FIND); + stat = rewrite(pvp, ruleset, reclevel, e); + if (rstat == EX_OK || stat == EX_TEMPFAIL) + rstat = stat; + if (*pvp != NULL && (**pvp & 0377) == CANONNET) + rwr = NULL; + } + } + else + { + bcopy((char *) npvp, (char *) pvp, + (int) (avp - npvp) * sizeof *avp); + } + if (tTd(21, 4)) + { + printf("rewritten as:"); + printav(pvp); + } + } + + if (OpMode == MD_TEST || tTd(21, 1)) + { + printf("rewrite: ruleset %2d returns:", ruleset); + printav(pvp); + } + + return rstat; +} +/* +** BUILDADDR -- build address from token vector. +** +** Parameters: +** tv -- token vector. +** a -- pointer to address descriptor to fill. +** If NULL, one will be allocated. +** flags -- info regarding whether this is a sender or +** a recipient. +** e -- the current envelope. +** +** Returns: +** NULL if there was an error. +** 'a' otherwise. +** +** Side Effects: +** fills in 'a' +*/ + +struct errcodes +{ + char *ec_name; /* name of error code */ + int ec_code; /* numeric code */ +} ErrorCodes[] = +{ + "usage", EX_USAGE, + "nouser", EX_NOUSER, + "nohost", EX_NOHOST, + "unavailable", EX_UNAVAILABLE, + "software", EX_SOFTWARE, + "tempfail", EX_TEMPFAIL, + "protocol", EX_PROTOCOL, +#ifdef EX_CONFIG + "config", EX_CONFIG, +#endif + NULL, EX_UNAVAILABLE, +}; + +ADDRESS * +buildaddr(tv, a, flags, e) + register char **tv; + register ADDRESS *a; + int flags; + register ENVELOPE *e; +{ + struct mailer **mp; + register struct mailer *m; + register char *p; + char *mname; + char **hostp; + char hbuf[MAXNAME + 1]; + static MAILER errormailer; + static char *errorargv[] = { "ERROR", NULL }; + static char ubuf[MAXNAME + 1]; + + if (tTd(24, 5)) + { + printf("buildaddr, flags=%x, tv=", flags); + printav(tv); + } + + if (a == NULL) + a = (ADDRESS *) xalloc(sizeof *a); + bzero((char *) a, sizeof *a); + + /* set up default error return flags */ + a->q_flags |= QPINGONFAILURE|QPINGONDELAY; + + /* figure out what net/mailer to use */ + if (*tv == NULL || (**tv & 0377) != CANONNET) + { + syserr("554 buildaddr: no mailer in parsed address"); +badaddr: + a->q_flags |= QBADADDR; + a->q_mailer = &errormailer; + if (errormailer.m_name == NULL) + { + /* initialize the bogus mailer */ + errormailer.m_name = "*error*"; + errormailer.m_mailer = "ERROR"; + errormailer.m_argv = errorargv; + } + return a; + } + mname = *++tv; + + /* extract host and user portions */ + if ((**++tv & 0377) == CANONHOST) + hostp = ++tv; + else + hostp = NULL; + while (*tv != NULL && (**tv & 0377) != CANONUSER) + tv++; + if (*tv == NULL) + { + syserr("554 buildaddr: no user"); + goto badaddr; + } + if (tv == hostp) + hostp = NULL; + else if (hostp != NULL) + cataddr(hostp, tv - 1, hbuf, sizeof hbuf, '\0'); + cataddr(++tv, NULL, ubuf, sizeof ubuf, ' '); + + /* save away the host name */ + if (strcasecmp(mname, "error") == 0) + { + if (hostp != NULL) + { + register struct errcodes *ep; + + if (strchr(hbuf, '.') != NULL) + { + a->q_status = newstr(hbuf); + setstat(dsntoexitstat(hbuf)); + } + else if (isascii(hbuf[0]) && isdigit(hbuf[0])) + { + setstat(atoi(hbuf)); + } + else + { + for (ep = ErrorCodes; ep->ec_name != NULL; ep++) + if (strcasecmp(ep->ec_name, hbuf) == 0) + break; + setstat(ep->ec_code); + } + } + else + setstat(EX_UNAVAILABLE); + stripquotes(ubuf); + if (isascii(ubuf[0]) && isdigit(ubuf[0]) && + isascii(ubuf[1]) && isdigit(ubuf[1]) && + isascii(ubuf[2]) && isdigit(ubuf[2]) && + ubuf[3] == ' ') + { + char fmt[10]; + + strncpy(fmt, ubuf, 3); + strcpy(&fmt[3], " %s"); + usrerr(fmt, ubuf + 4); + + /* + ** If this is a 4xx code and we aren't running + ** SMTP on our input, bounce this message; + ** otherwise it disappears without a trace. + */ + + if (fmt[0] == '4' && OpMode != MD_SMTP && + OpMode != MD_DAEMON) + { + e->e_flags |= EF_FATALERRS; + } + } + else + { + usrerr("553 %s", ubuf); + } + goto badaddr; + } + + for (mp = Mailer; (m = *mp++) != NULL; ) + { + if (strcasecmp(m->m_name, mname) == 0) + break; + } + if (m == NULL) + { + syserr("554 buildaddr: unknown mailer %s", mname); + goto badaddr; + } + a->q_mailer = m; + + /* figure out what host (if any) */ + if (hostp == NULL) + { + if (!bitnset(M_LOCALMAILER, m->m_flags)) + { + syserr("554 buildaddr: no host"); + goto badaddr; + } + a->q_host = NULL; + } + else + a->q_host = newstr(hbuf); + + /* figure out the user */ + p = ubuf; + if (bitnset(M_CHECKUDB, m->m_flags) && *p == '@') + { + p++; + tv++; + a->q_flags |= QNOTREMOTE; + } + + /* do special mapping for local mailer */ + if (*p == '"') + p++; + if (*p == '|' && bitnset(M_CHECKPROG, m->m_flags)) + a->q_mailer = m = ProgMailer; + else if (*p == '/' && bitnset(M_CHECKFILE, m->m_flags)) + a->q_mailer = m = FileMailer; + else if (*p == ':' && bitnset(M_CHECKINCLUDE, m->m_flags)) + { + /* may be :include: */ + stripquotes(ubuf); + if (strncasecmp(ubuf, ":include:", 9) == 0) + { + /* if :include:, don't need further rewriting */ + a->q_mailer = m = InclMailer; + a->q_user = newstr(&ubuf[9]); + return a; + } + } + + /* rewrite according recipient mailer rewriting rules */ + define('h', a->q_host, e); + if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags)) + { + /* sender addresses done later */ + (void) rewrite(tv, 2, 0, e); + if (m->m_re_rwset > 0) + (void) rewrite(tv, m->m_re_rwset, 0, e); + } + (void) rewrite(tv, 4, 0, e); + + /* save the result for the command line/RCPT argument */ + cataddr(tv, NULL, ubuf, sizeof ubuf, '\0'); + a->q_user = ubuf; + + /* + ** Do mapping to lower case as requested by mailer + */ + + if (a->q_host != NULL && !bitnset(M_HST_UPPER, m->m_flags)) + makelower(a->q_host); + if (!bitnset(M_USR_UPPER, m->m_flags)) + makelower(a->q_user); + + if (tTd(24, 6)) + { + printf("buildaddr => "); + printaddr(a, FALSE); + } + return a; +} +/* +** CATADDR -- concatenate pieces of addresses (putting in <LWSP> subs) +** +** Parameters: +** pvp -- parameter vector to rebuild. +** evp -- last parameter to include. Can be NULL to +** use entire pvp. +** buf -- buffer to build the string into. +** sz -- size of buf. +** spacesub -- the space separator character; if null, +** use SpaceSub. +** +** Returns: +** none. +** +** Side Effects: +** Destroys buf. +*/ + +void +cataddr(pvp, evp, buf, sz, spacesub) + char **pvp; + char **evp; + char *buf; + register int sz; + int spacesub; +{ + bool oatomtok = FALSE; + bool natomtok = FALSE; + register int i; + register char *p; + + if (spacesub == '\0') + spacesub = SpaceSub; + + if (pvp == NULL) + { + (void) strcpy(buf, ""); + return; + } + p = buf; + sz -= 2; + while (*pvp != NULL && (i = strlen(*pvp)) < sz) + { + natomtok = (TokTypeTab[**pvp & 0xff] == ATM); + if (oatomtok && natomtok) + *p++ = spacesub; + (void) strcpy(p, *pvp); + oatomtok = natomtok; + p += i; + sz -= i + 1; + if (pvp++ == evp) + break; + } + *p = '\0'; +} +/* +** SAMEADDR -- Determine if two addresses are the same +** +** This is not just a straight comparison -- if the mailer doesn't +** care about the host we just ignore it, etc. +** +** Parameters: +** a, b -- pointers to the internal forms to compare. +** +** Returns: +** TRUE -- they represent the same mailbox. +** FALSE -- they don't. +** +** Side Effects: +** none. +*/ + +bool +sameaddr(a, b) + register ADDRESS *a; + register ADDRESS *b; +{ + register ADDRESS *ca, *cb; + + /* if they don't have the same mailer, forget it */ + if (a->q_mailer != b->q_mailer) + return (FALSE); + + /* if the user isn't the same, we can drop out */ + if (strcmp(a->q_user, b->q_user) != 0) + return (FALSE); + + /* if we have good uids for both but they differ, these are different */ + if (a->q_mailer == ProgMailer) + { + ca = getctladdr(a); + cb = getctladdr(b); + if (ca != NULL && cb != NULL && + bitset(QGOODUID, ca->q_flags & cb->q_flags) && + ca->q_uid != cb->q_uid) + return (FALSE); + } + + /* otherwise compare hosts (but be careful for NULL ptrs) */ + if (a->q_host == b->q_host) + { + /* probably both null pointers */ + return (TRUE); + } + if (a->q_host == NULL || b->q_host == NULL) + { + /* only one is a null pointer */ + return (FALSE); + } + if (strcmp(a->q_host, b->q_host) != 0) + return (FALSE); + + return (TRUE); +} +/* +** PRINTADDR -- print address (for debugging) +** +** Parameters: +** a -- the address to print +** follow -- follow the q_next chain. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +struct qflags +{ + char *qf_name; + u_long qf_bit; +}; + +struct qflags AddressFlags[] = +{ + "QDONTSEND", QDONTSEND, + "QBADADDR", QBADADDR, + "QGOODUID", QGOODUID, + "QPRIMARY", QPRIMARY, + "QQUEUEUP", QQUEUEUP, + "QSENT", QSENT, + "QNOTREMOTE", QNOTREMOTE, + "QSELFREF", QSELFREF, + "QVERIFIED", QVERIFIED, + "QBOGUSSHELL", QBOGUSSHELL, + "QUNSAFEADDR", QUNSAFEADDR, + "QPINGONSUCCESS", QPINGONSUCCESS, + "QPINGONFAILURE", QPINGONFAILURE, + "QPINGONDELAY", QPINGONDELAY, + "QHASNOTIFY", QHASNOTIFY, + "QRELAYED", QRELAYED, + "QEXPANDED", QEXPANDED, + "QDELIVERED", QDELIVERED, + "QDELAYED", QDELAYED, + "QTHISPASS", QTHISPASS, + NULL +}; + +void +printaddr(a, follow) + register ADDRESS *a; + bool follow; +{ + register MAILER *m; + MAILER pseudomailer; + register struct qflags *qfp; + bool firstone; + + if (a == NULL) + { + printf("[NULL]\n"); + return; + } + + while (a != NULL) + { + printf("%x=", a); + (void) fflush(stdout); + + /* find the mailer -- carefully */ + m = a->q_mailer; + if (m == NULL) + { + m = &pseudomailer; + m->m_mno = -1; + m->m_name = "NULL"; + } + + printf("%s:\n\tmailer %d (%s), host `%s'\n", + a->q_paddr == NULL ? "<null>" : a->q_paddr, + m->m_mno, m->m_name, + a->q_host == NULL ? "<null>" : a->q_host); + printf("\tuser `%s', ruser `%s'\n", + a->q_user, + a->q_ruser == NULL ? "<null>" : a->q_ruser); + printf("\tnext=%x, alias %x, uid %d, gid %d\n", + a->q_next, a->q_alias, a->q_uid, a->q_gid); + printf("\tflags=%lx<", a->q_flags); + firstone = TRUE; + for (qfp = AddressFlags; qfp->qf_name != NULL; qfp++) + { + if (!bitset(qfp->qf_bit, a->q_flags)) + continue; + if (!firstone) + printf(","); + firstone = FALSE; + printf("%s", qfp->qf_name); + } + printf(">\n"); + printf("\towner=%s, home=\"%s\", fullname=\"%s\"\n", + a->q_owner == NULL ? "(none)" : a->q_owner, + a->q_home == NULL ? "(none)" : a->q_home, + a->q_fullname == NULL ? "(none)" : a->q_fullname); + printf("\torcpt=\"%s\", statmta=%s, rstatus=%s\n", + a->q_orcpt == NULL ? "(none)" : a->q_orcpt, + a->q_statmta == NULL ? "(none)" : a->q_statmta, + a->q_rstatus == NULL ? "(none)" : a->q_rstatus); + + if (!follow) + return; + a = a->q_next; + } +} +/* +** EMPTYADDR -- return TRUE if this address is empty (``<>'') +** +** Parameters: +** a -- pointer to the address +** +** Returns: +** TRUE -- if this address is "empty" (i.e., no one should +** ever generate replies to it. +** FALSE -- if it is a "regular" (read: replyable) address. +*/ + +bool +emptyaddr(a) + register ADDRESS *a; +{ + return a->q_paddr == NULL || strcmp(a->q_paddr, "<>") == 0 || + a->q_user == NULL || strcmp(a->q_user, "<>") == 0; +} +/* +** REMOTENAME -- return the name relative to the current mailer +** +** Parameters: +** name -- the name to translate. +** m -- the mailer that we want to do rewriting relative +** to. +** flags -- fine tune operations. +** pstat -- pointer to status word. +** e -- the current envelope. +** +** Returns: +** the text string representing this address relative to +** the receiving mailer. +** +** Side Effects: +** none. +** +** Warnings: +** The text string returned is tucked away locally; +** copy it if you intend to save it. +*/ + +char * +remotename(name, m, flags, pstat, e) + char *name; + struct mailer *m; + int flags; + int *pstat; + register ENVELOPE *e; +{ + register char **pvp; + char *fancy; + char *oldg = macvalue('g', e); + int rwset; + static char buf[MAXNAME + 1]; + char lbuf[MAXNAME + 1]; + char pvpbuf[PSBUFSIZE]; + extern char *crackaddr(); + + if (tTd(12, 1)) + printf("remotename(%s)\n", name); + + /* don't do anything if we are tagging it as special */ + if (bitset(RF_SENDERADDR, flags)) + rwset = bitset(RF_HEADERADDR, flags) ? m->m_sh_rwset + : m->m_se_rwset; + else + rwset = bitset(RF_HEADERADDR, flags) ? m->m_rh_rwset + : m->m_re_rwset; + if (rwset < 0) + return (name); + + /* + ** Do a heuristic crack of this name to extract any comment info. + ** This will leave the name as a comment and a $g macro. + */ + + if (bitset(RF_CANONICAL, flags) || bitnset(M_NOCOMMENT, m->m_flags)) + fancy = "\201g"; + else + fancy = crackaddr(name); + + /* + ** Turn the name into canonical form. + ** Normally this will be RFC 822 style, i.e., "user@domain". + ** If this only resolves to "user", and the "C" flag is + ** specified in the sending mailer, then the sender's + ** domain will be appended. + */ + + pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL); + if (pvp == NULL) + return (name); + if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL) + *pstat = EX_TEMPFAIL; + if (bitset(RF_ADDDOMAIN, flags) && e->e_fromdomain != NULL) + { + /* append from domain to this address */ + register char **pxp = pvp; + + /* see if there is an "@domain" in the current name */ + while (*pxp != NULL && strcmp(*pxp, "@") != 0) + pxp++; + if (*pxp == NULL) + { + /* no.... append the "@domain" from the sender */ + register char **qxq = e->e_fromdomain; + + while ((*pxp++ = *qxq++) != NULL) + continue; + if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL) + *pstat = EX_TEMPFAIL; + } + } + + /* + ** Do more specific rewriting. + ** Rewrite using ruleset 1 or 2 depending on whether this is + ** a sender address or not. + ** Then run it through any receiving-mailer-specific rulesets. + */ + + if (bitset(RF_SENDERADDR, flags)) + { + if (rewrite(pvp, 1, 0, e) == EX_TEMPFAIL) + *pstat = EX_TEMPFAIL; + } + else + { + if (rewrite(pvp, 2, 0, e) == EX_TEMPFAIL) + *pstat = EX_TEMPFAIL; + } + if (rwset > 0) + { + if (rewrite(pvp, rwset, 0, e) == EX_TEMPFAIL) + *pstat = EX_TEMPFAIL; + } + + /* + ** Do any final sanitation the address may require. + ** This will normally be used to turn internal forms + ** (e.g., user@host.LOCAL) into external form. This + ** may be used as a default to the above rules. + */ + + if (rewrite(pvp, 4, 0, e) == EX_TEMPFAIL) + *pstat = EX_TEMPFAIL; + + /* + ** Now restore the comment information we had at the beginning. + */ + + cataddr(pvp, NULL, lbuf, sizeof lbuf, '\0'); + define('g', lbuf, e); + + /* need to make sure route-addrs have <angle brackets> */ + if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@') + expand("<\201g>", buf, sizeof buf, e); + else + expand(fancy, buf, sizeof buf, e); + + define('g', oldg, e); + + if (tTd(12, 1)) + printf("remotename => `%s'\n", buf); + return (buf); +} +/* +** MAPLOCALUSER -- run local username through ruleset 5 for final redirection +** +** Parameters: +** a -- the address to map (but just the user name part). +** sendq -- the sendq in which to install any replacement +** addresses. +** aliaslevel -- the alias nesting depth. +** e -- the envelope. +** +** Returns: +** none. +*/ + +void +maplocaluser(a, sendq, aliaslevel, e) + register ADDRESS *a; + ADDRESS **sendq; + int aliaslevel; + ENVELOPE *e; +{ + register char **pvp; + register ADDRESS *a1 = NULL; + auto char *delimptr; + char pvpbuf[PSBUFSIZE]; + + if (tTd(29, 1)) + { + printf("maplocaluser: "); + printaddr(a, FALSE); + } + pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr, NULL); + if (pvp == NULL) + return; + + (void) rewrite(pvp, 5, 0, e); + if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET) + return; + + /* if non-null, mailer destination specified -- has it changed? */ + a1 = buildaddr(pvp, NULL, 0, e); + if (a1 == NULL || sameaddr(a, a1)) + return; + + /* mark old address as dead; insert new address */ + a->q_flags |= QDONTSEND; + if (tTd(29, 5)) + { + printf("maplocaluser: QDONTSEND "); + printaddr(a, FALSE); + } + a1->q_alias = a; + allocaddr(a1, RF_COPYALL, a->q_paddr); + (void) recipient(a1, sendq, aliaslevel, e); +} +/* +** DEQUOTE_INIT -- initialize dequote map +** +** This is a no-op. +** +** Parameters: +** map -- the internal map structure. +** args -- arguments. +** +** Returns: +** TRUE. +*/ + +bool +dequote_init(map, args) + MAP *map; + char *args; +{ + register char *p = args; + + map->map_mflags |= MF_KEEPQUOTES; + for (;;) + { + while (isascii(*p) && isspace(*p)) + p++; + if (*p != '-') + break; + switch (*++p) + { + case 'a': + map->map_app = ++p; + break; + + case 's': + map->map_coldelim = *++p; + break; + } + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p = '\0'; + } + if (map->map_app != NULL) + map->map_app = newstr(map->map_app); + + return TRUE; +} +/* +** DEQUOTE_MAP -- unquote an address +** +** Parameters: +** map -- the internal map structure (ignored). +** name -- the name to dequote. +** av -- arguments (ignored). +** statp -- pointer to status out-parameter. +** +** Returns: +** NULL -- if there were no quotes, or if the resulting +** unquoted buffer would not be acceptable to prescan. +** else -- The dequoted buffer. +*/ + +char * +dequote_map(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + register char *p; + register char *q; + register char c; + int anglecnt = 0; + int cmntcnt = 0; + int quotecnt = 0; + int spacecnt = 0; + bool quotemode = FALSE; + bool bslashmode = FALSE; + char spacesub = map->map_coldelim; + + for (p = q = name; (c = *p++) != '\0'; ) + { + if (bslashmode) + { + bslashmode = FALSE; + *q++ = c; + continue; + } + + if (c == ' ' && spacesub != '\0') + c = spacesub; + + switch (c) + { + case '\\': + bslashmode = TRUE; + break; + + case '(': + cmntcnt++; + break; + + case ')': + if (cmntcnt-- <= 0) + return NULL; + break; + + case ' ': + spacecnt++; + break; + } + + if (cmntcnt > 0) + { + *q++ = c; + continue; + } + + switch (c) + { + case '"': + quotemode = !quotemode; + quotecnt++; + continue; + + case '<': + anglecnt++; + break; + + case '>': + if (anglecnt-- <= 0) + return NULL; + break; + } + *q++ = c; + } + + if (anglecnt != 0 || cmntcnt != 0 || bslashmode || + quotemode || quotecnt <= 0 || spacecnt != 0) + return NULL; + *q++ = '\0'; + return name; +} diff --git a/usr.sbin/sendmail/src/pathnames.h b/usr.sbin/sendmail/src/pathnames.h new file mode 100644 index 000000000000..a364fbab33a7 --- /dev/null +++ b/usr.sbin/sendmail/src/pathnames.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pathnames.h 8.4 (Berkeley) 6/19/95 + */ + +#ifndef _PATH_SENDMAILCF +# if defined(USE_VENDOR_CF_PATH) && defined(_PATH_VENDOR_CF) +# define _PATH_SENDMAILCF _PATH_VENDOR_CF +# else +# define _PATH_SENDMAILCF "/etc/sendmail.cf" +# endif +#endif + +#ifndef _PATH_SENDMAILPID +# ifdef BSD4_4 +# define _PATH_SENDMAILPID "/var/run/sendmail.pid" +# else +# define _PATH_SENDMAILPID "/etc/sendmail.pid" +# endif +#endif + +#ifndef _PATH_HOSTS +# define _PATH_HOSTS "/etc/hosts" +#endif diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c new file mode 100644 index 000000000000..97bf36cd8086 --- /dev/null +++ b/usr.sbin/sendmail/src/queue.c @@ -0,0 +1,2071 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +# include "sendmail.h" + +#ifndef lint +#ifdef QUEUE +static char sccsid[] = "@(#)queue.c 8.98 (Berkeley) 11/11/95 (with queueing)"; +#else +static char sccsid[] = "@(#)queue.c 8.98 (Berkeley) 11/11/95 (without queueing)"; +#endif +#endif /* not lint */ + +# include <errno.h> +# include <dirent.h> + +# ifdef QUEUE + +/* +** Work queue. +*/ + +struct work +{ + char *w_name; /* name of control file */ + char *w_host; /* name of recipient host */ + bool w_lock; /* is message locked? */ + bool w_tooyoung; /* is it too young to run? */ + long w_pri; /* priority of message, see below */ + time_t w_ctime; /* creation time of message */ + struct work *w_next; /* next in queue */ +}; + +typedef struct work WORK; + +WORK *WorkQ; /* queue of things to be done */ + +#define QF_VERSION 1 /* version number of this queue format */ + +#if !defined(NGROUPS_MAX) && defined(NGROUPS) +# define NGROUPS_MAX NGROUPS /* POSIX naming convention */ +#endif +/* +** QUEUEUP -- queue a message up for future transmission. +** +** Parameters: +** e -- the envelope to queue up. +** announce -- if TRUE, tell when you are queueing up. +** +** Returns: +** none. +** +** Side Effects: +** The current request are saved in a control file. +** The queue file is left locked. +*/ + +void +queueup(e, announce) + register ENVELOPE *e; + bool announce; +{ + char *qf; + register FILE *tfp; + register HDR *h; + register ADDRESS *q; + int fd; + int i; + bool newid; + register char *p; + MAILER nullmailer; + MCI mcibuf; + char buf[MAXLINE], tf[MAXLINE]; + extern void printctladdr __P((ADDRESS *, FILE *)); + + /* + ** Create control file. + */ + + newid = (e->e_id == NULL) || !bitset(EF_INQUEUE, e->e_flags); + + /* if newid, queuename will create a locked qf file in e->lockfp */ + strcpy(tf, queuename(e, 't')); + tfp = e->e_lockfp; + if (tfp == NULL) + newid = FALSE; + + /* if newid, just write the qf file directly (instead of tf file) */ + if (!newid) + { + /* get a locked tf file */ + for (i = 0; i < 128; i++) + { + fd = open(tf, O_CREAT|O_WRONLY|O_EXCL, FileMode); + if (fd < 0) + { + if (errno != EEXIST) + break; +#ifdef LOG + if (LogLevel > 0 && (i % 32) == 0) + syslog(LOG_ALERT, "queueup: cannot create %s, uid=%d: %s", + tf, geteuid(), errstring(errno)); +#endif + } + else + { + if (lockfile(fd, tf, NULL, LOCK_EX|LOCK_NB)) + break; +#ifdef LOG + else if (LogLevel > 0 && (i % 32) == 0) + syslog(LOG_ALERT, "queueup: cannot lock %s: %s", + tf, errstring(errno)); +#endif + close(fd); + } + + if ((i % 32) == 31) + { + /* save the old temp file away */ + (void) rename(tf, queuename(e, 'T')); + } + else + sleep(i % 32); + } + if (fd < 0 || (tfp = fdopen(fd, "w")) == NULL) + { + printopenfds(TRUE); + syserr("!queueup: cannot create queue temp file %s, uid=%d", + tf, geteuid()); + } + } + + if (tTd(40, 1)) + printf("\n>>>>> queueing %s%s >>>>>\n", e->e_id, + newid ? " (new id)" : ""); + if (tTd(40, 3)) + { + extern void printenvflags(); + + printf(" e_flags="); + printenvflags(e); + } + if (tTd(40, 32)) + { + printf(" sendq="); + printaddr(e->e_sendqueue, TRUE); + } + if (tTd(40, 9)) + { + printf(" tfp="); + dumpfd(fileno(tfp), TRUE, FALSE); + printf(" lockfp="); + if (e->e_lockfp == NULL) + printf("NULL\n"); + else + dumpfd(fileno(e->e_lockfp), TRUE, FALSE); + } + + /* + ** If there is no data file yet, create one. + */ + + if (!bitset(EF_HAS_DF, e->e_flags)) + { + register FILE *dfp; + char dfname[20]; + struct stat stbuf; + + strcpy(dfname, queuename(e, 'd')); + fd = open(dfname, O_WRONLY|O_CREAT|O_TRUNC, FileMode); + if (fd < 0 || (dfp = fdopen(fd, "w")) == NULL) + syserr("!queueup: cannot create data temp file %s, uid=%d", + dfname, geteuid()); + if (fstat(fd, &stbuf) < 0) + e->e_dfino = -1; + else + { + e->e_dfdev = stbuf.st_dev; + e->e_dfino = stbuf.st_ino; + } + e->e_flags |= EF_HAS_DF; + bzero(&mcibuf, sizeof mcibuf); + mcibuf.mci_out = dfp; + mcibuf.mci_mailer = FileMailer; + (*e->e_putbody)(&mcibuf, e, NULL); + (void) xfclose(dfp, "queueup dfp", e->e_id); + e->e_putbody = putbody; + } + + /* + ** Output future work requests. + ** Priority and creation time should be first, since + ** they are required by orderq. + */ + + /* output queue version number (must be first!) */ + fprintf(tfp, "V%d\n", QF_VERSION); + + /* output creation time */ + fprintf(tfp, "T%ld\n", e->e_ctime); + + /* output last delivery time */ + fprintf(tfp, "K%ld\n", e->e_dtime); + + /* output number of delivery attempts */ + fprintf(tfp, "N%d\n", e->e_ntries); + + /* output message priority */ + fprintf(tfp, "P%ld\n", e->e_msgpriority); + + /* output inode number of data file */ + /* XXX should probably include device major/minor too */ + if (e->e_dfino != -1) + fprintf(tfp, "I%d/%d/%ld\n", + major(e->e_dfdev), minor(e->e_dfdev), e->e_dfino); + + /* output body type */ + if (e->e_bodytype != NULL) + fprintf(tfp, "B%s\n", e->e_bodytype); + + /* message from envelope, if it exists */ + if (e->e_message != NULL) + fprintf(tfp, "M%s\n", denlstring(e->e_message, TRUE, FALSE)); + + /* send various flag bits through */ + p = buf; + if (bitset(EF_WARNING, e->e_flags)) + *p++ = 'w'; + if (bitset(EF_RESPONSE, e->e_flags)) + *p++ = 'r'; + if (bitset(EF_HAS8BIT, e->e_flags)) + *p++ = '8'; + *p++ = '\0'; + if (buf[0] != '\0') + fprintf(tfp, "F%s\n", buf); + + /* $r and $s and $_ macro values */ + if ((p = macvalue('r', e)) != NULL) + fprintf(tfp, "$r%s\n", denlstring(p, TRUE, FALSE)); + if ((p = macvalue('s', e)) != NULL) + fprintf(tfp, "$s%s\n", denlstring(p, TRUE, FALSE)); + if ((p = macvalue('_', e)) != NULL) + fprintf(tfp, "$_%s\n", denlstring(p, TRUE, FALSE)); + + /* output name of sender */ + if (bitnset(M_UDBENVELOPE, e->e_from.q_mailer->m_flags)) + p = e->e_sender; + else + p = e->e_from.q_paddr; + fprintf(tfp, "S%s\n", denlstring(p, TRUE, FALSE)); + + /* output ESMTP-supplied "original" information */ + if (e->e_envid != NULL) + fprintf(tfp, "Z%s\n", denlstring(e->e_envid, TRUE, FALSE)); + + /* output list of recipient addresses */ + printctladdr(NULL, NULL); + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (bitset(QQUEUEUP, q->q_flags) || + !bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags)) + { + printctladdr(q, tfp); + if (q->q_orcpt != NULL) + fprintf(tfp, "Q%s\n", + denlstring(q->q_orcpt, TRUE, FALSE)); + putc('R', tfp); + if (bitset(QPRIMARY, q->q_flags)) + putc('P', tfp); + if (bitset(QPINGONSUCCESS, q->q_flags)) + putc('S', tfp); + if (bitset(QPINGONFAILURE, q->q_flags)) + putc('F', tfp); + if (bitset(QPINGONDELAY, q->q_flags)) + putc('D', tfp); + putc(':', tfp); + fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE)); + if (announce) + { + e->e_to = q->q_paddr; + message("queued"); + if (LogLevel > 8) + logdelivery(q->q_mailer, NULL, "queued", + NULL, (time_t) 0, e); + e->e_to = NULL; + } + if (tTd(40, 1)) + { + printf("queueing "); + printaddr(q, FALSE); + } + } + } + + /* + ** Output headers for this message. + ** Expand macros completely here. Queue run will deal with + ** everything as absolute headers. + ** All headers that must be relative to the recipient + ** can be cracked later. + ** We set up a "null mailer" -- i.e., a mailer that will have + ** no effect on the addresses as they are output. + */ + + bzero((char *) &nullmailer, sizeof nullmailer); + nullmailer.m_re_rwset = nullmailer.m_rh_rwset = + nullmailer.m_se_rwset = nullmailer.m_sh_rwset = -1; + nullmailer.m_eol = "\n"; + bzero(&mcibuf, sizeof mcibuf); + mcibuf.mci_mailer = &nullmailer; + mcibuf.mci_out = tfp; + + define('g', "\201f", e); + for (h = e->e_header; h != NULL; h = h->h_link) + { + extern bool bitzerop(); + + /* don't output null headers */ + if (h->h_value == NULL || h->h_value[0] == '\0') + continue; + + /* don't output resent headers on non-resent messages */ + if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags)) + continue; + + /* expand macros; if null, don't output header at all */ + if (bitset(H_DEFAULT, h->h_flags)) + { + (void) expand(h->h_value, buf, sizeof buf, e); + if (buf[0] == '\0') + continue; + } + + /* output this header */ + fprintf(tfp, "H"); + + /* if conditional, output the set of conditions */ + if (!bitzerop(h->h_mflags) && bitset(H_CHECK|H_ACHECK, h->h_flags)) + { + int j; + + (void) putc('?', tfp); + for (j = '\0'; j <= '\177'; j++) + if (bitnset(j, h->h_mflags)) + (void) putc(j, tfp); + (void) putc('?', tfp); + } + + /* output the header: expand macros, convert addresses */ + if (bitset(H_DEFAULT, h->h_flags)) + { + fprintf(tfp, "%s: %s\n", h->h_field, buf); + } + else if (bitset(H_FROM|H_RCPT, h->h_flags)) + { + bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags); + FILE *savetrace = TrafficLogFile; + + TrafficLogFile = NULL; + + if (bitset(H_FROM, h->h_flags)) + oldstyle = FALSE; + + commaize(h, h->h_value, oldstyle, &mcibuf, e); + + TrafficLogFile = savetrace; + } + else + fprintf(tfp, "%s: %s\n", h->h_field, h->h_value); + } + + /* + ** Clean up. + ** + ** Write a terminator record -- this is to prevent + ** scurrilous crackers from appending any data. + */ + + fprintf(tfp, ".\n"); + + if (fflush(tfp) < 0 || fsync(fileno(tfp)) < 0 || ferror(tfp)) + { + if (newid) + syserr("!552 Error writing control file %s", tf); + else + syserr("!452 Error writing control file %s", tf); + } + + if (!newid) + { + /* rename (locked) tf to be (locked) qf */ + qf = queuename(e, 'q'); + if (rename(tf, qf) < 0) + syserr("cannot rename(%s, %s), uid=%d", + tf, qf, geteuid()); + + /* close and unlock old (locked) qf */ + if (e->e_lockfp != NULL) + (void) xfclose(e->e_lockfp, "queueup lockfp", e->e_id); + e->e_lockfp = tfp; + } + else + qf = tf; + errno = 0; + e->e_flags |= EF_INQUEUE; + +# ifdef LOG + /* save log info */ + if (LogLevel > 79) + syslog(LOG_DEBUG, "%s: queueup, qf=%s", e->e_id, qf); +# endif /* LOG */ + + if (tTd(40, 1)) + printf("<<<<< done queueing %s <<<<<\n\n", e->e_id); + return; +} + +void +printctladdr(a, tfp) + register ADDRESS *a; + FILE *tfp; +{ + char *uname; + register struct passwd *pw; + register ADDRESS *q; + uid_t uid; + static ADDRESS *lastctladdr; + static uid_t lastuid; + + /* initialization */ + if (a == NULL || a->q_alias == NULL || tfp == NULL) + { + if (lastctladdr != NULL && tfp != NULL) + fprintf(tfp, "C\n"); + lastctladdr = NULL; + lastuid = 0; + return; + } + + /* find the active uid */ + q = getctladdr(a); + if (q == NULL) + uid = 0; + else + uid = q->q_uid; + a = a->q_alias; + + /* check to see if this is the same as last time */ + if (lastctladdr != NULL && uid == lastuid && + strcmp(lastctladdr->q_paddr, a->q_paddr) == 0) + return; + lastuid = uid; + lastctladdr = a; + + if (uid == 0 || (pw = sm_getpwuid(uid)) == NULL) + uname = ""; + else + uname = pw->pw_name; + + fprintf(tfp, "C%s:%s\n", uname, denlstring(a->q_paddr, TRUE, FALSE)); +} +/* +** RUNQUEUE -- run the jobs in the queue. +** +** Gets the stuff out of the queue in some presumably logical +** order and processes them. +** +** Parameters: +** forkflag -- TRUE if the queue scanning should be done in +** a child process. We double-fork so it is not our +** child and we don't have to clean up after it. +** +** Returns: +** none. +** +** Side Effects: +** runs things in the mail queue. +*/ + +ENVELOPE QueueEnvelope; /* the queue run envelope */ + +void +runqueue(forkflag) + bool forkflag; +{ + register ENVELOPE *e; + int njobs; + int sequenceno = 0; + extern ENVELOPE BlankEnvelope; + + /* + ** If no work will ever be selected, don't even bother reading + ** the queue. + */ + + CurrentLA = getla(); /* get load average */ + + if (shouldqueue(0L, curtime())) + { + char *msg = "Skipping queue run -- load average too high"; + + if (Verbose) + printf("%s\n", msg); +#ifdef LOG + if (LogLevel > 8) + syslog(LOG_INFO, "runqueue: %s", msg); +#endif + if (forkflag && QueueIntvl != 0) + (void) setevent(QueueIntvl, runqueue, TRUE); + return; + } + + /* + ** See if we want to go off and do other useful work. + */ + + if (forkflag) + { + int pid; + extern void intsig(); +#ifdef SIGCHLD + extern void reapchild(); + + (void) setsignal(SIGCHLD, reapchild); +#endif + + pid = dofork(); + if (pid != 0) + { + /* parent -- pick up intermediate zombie */ +#ifndef SIGCHLD + (void) waitfor(pid); +#else + CurChildren++; +#endif /* SIGCHLD */ + if (QueueIntvl != 0) + (void) setevent(QueueIntvl, runqueue, TRUE); + return; + } + /* child -- double fork and clean up signals */ +#ifndef SIGCHLD + if (fork() != 0) + exit(EX_OK); +#else /* SIGCHLD */ + (void) setsignal(SIGCHLD, SIG_DFL); +#endif /* SIGCHLD */ + (void) setsignal(SIGHUP, intsig); + } + + setproctitle("running queue: %s", QueueDir); + +# ifdef LOG + if (LogLevel > 69) + syslog(LOG_DEBUG, "runqueue %s, pid=%d, forkflag=%d", + QueueDir, getpid(), forkflag); +# endif /* LOG */ + + /* + ** Release any resources used by the daemon code. + */ + +# ifdef DAEMON + clrdaemon(); +# endif /* DAEMON */ + + /* force it to run expensive jobs */ + NoConnect = FALSE; + + /* + ** Create ourselves an envelope + */ + + CurEnv = &QueueEnvelope; + e = newenvelope(&QueueEnvelope, CurEnv); + e->e_flags = BlankEnvelope.e_flags; + + /* + ** Make sure the alias database is open. + */ + + initmaps(FALSE, e); + + /* + ** Start making passes through the queue. + ** First, read and sort the entire queue. + ** Then, process the work in that order. + ** But if you take too long, start over. + */ + + /* order the existing work requests */ + njobs = orderq(FALSE); + + /* process them once at a time */ + while (WorkQ != NULL) + { + WORK *w = WorkQ; + + WorkQ = WorkQ->w_next; + + /* + ** Ignore jobs that are too expensive for the moment. + */ + + sequenceno++; + if (shouldqueue(w->w_pri, w->w_ctime)) + { + if (Verbose) + printf("\nSkipping %s (sequence %d of %d)\n", + w->w_name + 2, sequenceno, njobs); + } + else + { + pid_t pid; + extern pid_t dowork(); + + if (Verbose) + printf("\nRunning %s (sequence %d of %d)\n", + w->w_name + 2, sequenceno, njobs); + pid = dowork(w->w_name + 2, ForkQueueRuns, FALSE, e); + errno = 0; + if (pid != 0) + (void) waitfor(pid); + } + free(w->w_name); + if (w->w_host) + free(w->w_host); + free((char *) w); + } + + /* exit without the usual cleanup */ + e->e_id = NULL; + finis(); +} +/* +** ORDERQ -- order the work queue. +** +** Parameters: +** doall -- if set, include everything in the queue (even +** the jobs that cannot be run because the load +** average is too high). Otherwise, exclude those +** jobs. +** +** Returns: +** The number of request in the queue (not necessarily +** the number of requests in WorkQ however). +** +** Side Effects: +** Sets WorkQ to the queue of available work, in order. +*/ + +# define NEED_P 001 +# define NEED_T 002 +# define NEED_R 004 +# define NEED_S 010 + +static WORK *WorkList = NULL; +static int WorkListSize = 0; + +int +orderq(doall) + bool doall; +{ + register struct dirent *d; + register WORK *w; + DIR *f; + register int i; + int wn = -1; + int wc; + + if (tTd(41, 1)) + { + printf("orderq:\n"); + if (QueueLimitId != NULL) + printf("\tQueueLimitId = %s\n", QueueLimitId); + if (QueueLimitSender != NULL) + printf("\tQueueLimitSender = %s\n", QueueLimitSender); + if (QueueLimitRecipient != NULL) + printf("\tQueueLimitRecipient = %s\n", QueueLimitRecipient); + } + + /* clear out old WorkQ */ + for (w = WorkQ; w != NULL; ) + { + register WORK *nw = w->w_next; + + WorkQ = nw; + free(w->w_name); + if (w->w_host) + free(w->w_host); + free((char *) w); + w = nw; + } + + /* open the queue directory */ + f = opendir("."); + if (f == NULL) + { + syserr("orderq: cannot open \"%s\" as \".\"", QueueDir); + return (0); + } + + /* + ** Read the work directory. + */ + + while ((d = readdir(f)) != NULL) + { + FILE *cf; + register char *p; + char lbuf[MAXNAME + 1]; + extern bool strcontainedin(); + + if (tTd(41, 50)) + printf("orderq: checking %s\n", d->d_name); + + /* is this an interesting entry? */ + if (d->d_name[0] != 'q' || d->d_name[1] != 'f') + continue; + + if (QueueLimitId != NULL && + !strcontainedin(QueueLimitId, d->d_name)) + continue; + +#ifdef PICKY_QF_NAME_CHECK + /* + ** Check queue name for plausibility. This handles + ** both old and new type ids. + */ + + p = d->d_name + 2; + if (isupper(p[0]) && isupper(p[2])) + p += 3; + else if (isupper(p[1])) + p += 2; + else + p = d->d_name; + for (i = 0; isdigit(*p); p++) + i++; + if (i < 5 || *p != '\0') + { + if (Verbose) + printf("orderq: bogus qf name %s\n", d->d_name); +# ifdef LOG + if (LogLevel > 0) + syslog(LOG_ALERT, "orderq: bogus qf name %s", + d->d_name); +# endif + if (strlen(d->d_name) > (SIZE_T) MAXNAME) + d->d_name[MAXNAME] = '\0'; + strcpy(lbuf, d->d_name); + lbuf[0] = 'Q'; + (void) rename(d->d_name, lbuf); + continue; + } +#endif + + /* open control file (if not too many files) */ + if (++wn >= MaxQueueRun && MaxQueueRun > 0) + { +# ifdef LOG + if (wn == MaxQueueRun && LogLevel > 0) + syslog(LOG_ALERT, "WorkList for %s maxed out at %d", + QueueDir, MaxQueueRun); +# endif + continue; + } + if (wn >= WorkListSize) + { + extern void grow_wlist __P((void)); + + grow_wlist(); + if (wn >= WorkListSize) + continue; + } + + cf = fopen(d->d_name, "r"); + if (cf == NULL) + { + /* this may be some random person sending hir msgs */ + /* syserr("orderq: cannot open %s", cbuf); */ + if (tTd(41, 2)) + printf("orderq: cannot open %s: %s\n", + d->d_name, errstring(errno)); + errno = 0; + wn--; + continue; + } + w = &WorkList[wn]; + w->w_name = newstr(d->d_name); + w->w_host = NULL; + w->w_lock = !lockfile(fileno(cf), w->w_name, NULL, LOCK_SH|LOCK_NB); + w->w_tooyoung = FALSE; + + /* make sure jobs in creation don't clog queue */ + w->w_pri = 0x7fffffff; + w->w_ctime = 0; + + /* extract useful information */ + i = NEED_P | NEED_T; + if (QueueLimitSender != NULL) + i |= NEED_S; + if (QueueSortOrder == QS_BYHOST || QueueLimitRecipient != NULL) + i |= NEED_R; + while (i != 0 && fgets(lbuf, sizeof lbuf, cf) != NULL) + { + extern bool strcontainedin(); + + switch (lbuf[0]) + { + case 'P': + w->w_pri = atol(&lbuf[1]); + i &= ~NEED_P; + break; + + case 'T': + w->w_ctime = atol(&lbuf[1]); + i &= ~NEED_T; + break; + + case 'R': + if (w->w_host == NULL && + (p = strrchr(&lbuf[1], '@')) != NULL) + w->w_host = newstr(&p[1]); + if (QueueLimitRecipient == NULL || + strcontainedin(QueueLimitRecipient, &lbuf[1])) + i &= ~NEED_R; + break; + + case 'S': + if (QueueLimitSender != NULL && + strcontainedin(QueueLimitSender, &lbuf[1])) + i &= ~NEED_S; + break; + + case 'K': + if ((curtime() - (time_t) atol(&lbuf[1])) < MinQueueAge) + w->w_tooyoung = TRUE; + break; + + case 'N': + if (atol(&lbuf[1]) == 0) + w->w_tooyoung = FALSE; + break; + } + } + (void) fclose(cf); + + if ((!doall && shouldqueue(w->w_pri, w->w_ctime)) || + bitset(NEED_R|NEED_S, i)) + { + /* don't even bother sorting this job in */ + if (tTd(41, 49)) + printf("skipping %s (%x)\n", w->w_name, i); + free(w->w_name); + if (w->w_host) + free(w->w_host); + wn--; + } + } + (void) closedir(f); + wn++; + + wc = min(wn, WorkListSize); + if (wc > MaxQueueRun && MaxQueueRun > 0) + wc = MaxQueueRun; + + if (QueueSortOrder == QS_BYHOST) + { + extern workcmpf1(); + extern workcmpf2(); + + /* + ** Sort the work directory for the first time, + ** based on host name, lock status, and priority. + */ + + qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf1); + + /* + ** If one message to host is locked, "lock" all messages + ** to that host. + */ + + i = 0; + while (i < wc) + { + if (!WorkList[i].w_lock) + { + i++; + continue; + } + w = &WorkList[i]; + while (++i < wc) + { + if (WorkList[i].w_host == NULL && + w->w_host == NULL) + WorkList[i].w_lock = TRUE; + else if (WorkList[i].w_host != NULL && + w->w_host != NULL && + strcmp(WorkList[i].w_host, w->w_host) == 0) + WorkList[i].w_lock = TRUE; + else + break; + } + } + + /* + ** Sort the work directory for the second time, + ** based on lock status, host name, and priority. + */ + + qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf2); + } + else + { + extern workcmpf0(); + + /* + ** Simple sort based on queue priority only. + */ + + qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf0); + } + + /* + ** Convert the work list into canonical form. + ** Should be turning it into a list of envelopes here perhaps. + */ + + WorkQ = NULL; + for (i = wc; --i >= 0; ) + { + w = (WORK *) xalloc(sizeof *w); + w->w_name = WorkList[i].w_name; + w->w_host = WorkList[i].w_host; + w->w_lock = WorkList[i].w_lock; + w->w_tooyoung = WorkList[i].w_tooyoung; + w->w_pri = WorkList[i].w_pri; + w->w_ctime = WorkList[i].w_ctime; + w->w_next = WorkQ; + WorkQ = w; + } + if (WorkList != NULL) + free(WorkList); + WorkList = NULL; + + if (tTd(40, 1)) + { + for (w = WorkQ; w != NULL; w = w->w_next) + printf("%32s: pri=%ld\n", w->w_name, w->w_pri); + } + + return (wn); +} +/* +** GROW_WLIST -- make the work list larger +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Adds another QUEUESEGSIZE entries to WorkList if possible. +** It can fail if there isn't enough memory, so WorkListSize +** should be checked again upon return. +*/ + +void +grow_wlist() +{ + if (tTd(41, 1)) + printf("grow_wlist: WorkListSize=%d\n", WorkListSize); + if (WorkList == NULL) + { + WorkList = (WORK *) xalloc(sizeof(WORK) * (QUEUESEGSIZE + 1)); + WorkListSize = QUEUESEGSIZE; + } + else + { + int newsize = WorkListSize + QUEUESEGSIZE; + WORK *newlist = (WORK *) realloc((char *)WorkList, + (unsigned)sizeof(WORK) * (newsize + 1)); + + if (newlist != NULL) + { + WorkListSize = newsize; + WorkList = newlist; +# ifdef LOG + if (LogLevel > 1) + { + syslog(LOG_NOTICE, "grew WorkList for %s to %d", + QueueDir, WorkListSize); + } + } + else if (LogLevel > 0) + { + syslog(LOG_ALERT, "FAILED to grow WorkList for %s to %d", + QueueDir, newsize); +# endif + } + } + if (tTd(41, 1)) + printf("grow_wlist: WorkListSize now %d\n", WorkListSize); +} +/* +** WORKCMPF0 -- simple priority-only compare function. +** +** Parameters: +** a -- the first argument. +** b -- the second argument. +** +** Returns: +** -1 if a < b +** 0 if a == b +** +1 if a > b +** +** Side Effects: +** none. +*/ + +int +workcmpf0(a, b) + register WORK *a; + register WORK *b; +{ + long pa = a->w_pri; + long pb = b->w_pri; + + if (pa == pb) + return 0; + else if (pa > pb) + return 1; + else + return -1; +} +/* +** WORKCMPF1 -- first compare function for ordering work based on host name. +** +** Sorts on host name, lock status, and priority in that order. +** +** Parameters: +** a -- the first argument. +** b -- the second argument. +** +** Returns: +** <0 if a < b +** 0 if a == b +** >0 if a > b +** +** Side Effects: +** none. +*/ + +int +workcmpf1(a, b) + register WORK *a; + register WORK *b; +{ + int i; + + /* host name */ + if (a->w_host != NULL && b->w_host == NULL) + return 1; + else if (a->w_host == NULL && b->w_host != NULL) + return -1; + if (a->w_host != NULL && b->w_host != NULL && + (i = strcmp(a->w_host, b->w_host))) + return i; + + /* lock status */ + if (a->w_lock != b->w_lock) + return b->w_lock - a->w_lock; + + /* job priority */ + return a->w_pri - b->w_pri; +} +/* +** WORKCMPF2 -- second compare function for ordering work based on host name. +** +** Sorts on lock status, host name, and priority in that order. +** +** Parameters: +** a -- the first argument. +** b -- the second argument. +** +** Returns: +** <0 if a < b +** 0 if a == b +** >0 if a > b +** +** Side Effects: +** none. +*/ + +int +workcmpf2(a, b) + register WORK *a; + register WORK *b; +{ + int i; + + /* lock status */ + if (a->w_lock != b->w_lock) + return a->w_lock - b->w_lock; + + /* host name */ + if (a->w_host != NULL && b->w_host == NULL) + return 1; + else if (a->w_host == NULL && b->w_host != NULL) + return -1; + if (a->w_host != NULL && b->w_host != NULL && + (i = strcmp(a->w_host, b->w_host))) + return i; + + /* job priority */ + return a->w_pri - b->w_pri; +} +/* +** DOWORK -- do a work request. +** +** Parameters: +** id -- the ID of the job to run. +** forkflag -- if set, run this in background. +** requeueflag -- if set, reinstantiate the queue quickly. +** This is used when expanding aliases in the queue. +** If forkflag is also set, it doesn't wait for the +** child. +** e - the envelope in which to run it. +** +** Returns: +** process id of process that is running the queue job. +** +** Side Effects: +** The work request is satisfied if possible. +*/ + +pid_t +dowork(id, forkflag, requeueflag, e) + char *id; + bool forkflag; + bool requeueflag; + register ENVELOPE *e; +{ + register pid_t pid; + extern bool readqf(); + + if (tTd(40, 1)) + printf("dowork(%s)\n", id); + + /* + ** Fork for work. + */ + + if (forkflag) + { + pid = fork(); + if (pid < 0) + { + syserr("dowork: cannot fork"); + return 0; + } + else if (pid > 0) + { + /* parent -- clean out connection cache */ + mci_flush(FALSE, NULL); + } + } + else + { + pid = 0; + } + + if (pid == 0) + { + /* + ** CHILD + ** Lock the control file to avoid duplicate deliveries. + ** Then run the file as though we had just read it. + ** We save an idea of the temporary name so we + ** can recover on interrupt. + */ + + /* set basic modes, etc. */ + (void) alarm(0); + clearenvelope(e, FALSE); + e->e_flags |= EF_QUEUERUN|EF_GLOBALERRS; + e->e_sendmode = SM_DELIVER; + e->e_errormode = EM_MAIL; + e->e_id = id; + GrabTo = UseErrorsTo = FALSE; + ExitStat = EX_OK; + if (forkflag) + { + disconnect(1, e); + OpMode = MD_DELIVER; + } +# ifdef LOG + if (LogLevel > 76) + syslog(LOG_DEBUG, "%s: dowork, pid=%d", e->e_id, + getpid()); +# endif /* LOG */ + + /* don't use the headers from sendmail.cf... */ + e->e_header = NULL; + + /* read the queue control file -- return if locked */ + if (!readqf(e)) + { + if (tTd(40, 4)) + printf("readqf(%s) failed\n", e->e_id); + if (forkflag) + exit(EX_OK); + else + return 0; + } + + e->e_flags |= EF_INQUEUE; + eatheader(e, requeueflag); + + if (requeueflag) + queueup(e, FALSE); + + /* do the delivery */ + sendall(e, SM_DELIVER); + + /* finish up and exit */ + if (forkflag) + finis(); + else + dropenvelope(e); + } + e->e_id = NULL; + return pid; +} +/* +** READQF -- read queue file and set up environment. +** +** Parameters: +** e -- the envelope of the job to run. +** +** Returns: +** TRUE if it successfully read the queue file. +** FALSE otherwise. +** +** Side Effects: +** The queue file is returned locked. +*/ + +bool +readqf(e) + register ENVELOPE *e; +{ + register FILE *qfp; + ADDRESS *ctladdr; + struct stat st; + char *bp; + int qfver = 0; + register char *p; + char *orcpt = NULL; + bool nomore = FALSE; + char qf[20]; + char buf[MAXLINE]; + extern ADDRESS *setctluser(); + extern void loseqfile(); + + /* + ** Read and process the file. + */ + + strcpy(qf, queuename(e, 'q')); + qfp = fopen(qf, "r+"); + if (qfp == NULL) + { + if (tTd(40, 8)) + printf("readqf(%s): fopen failure (%s)\n", + qf, errstring(errno)); + if (errno != ENOENT) + syserr("readqf: no control file %s", qf); + return FALSE; + } + + if (!lockfile(fileno(qfp), qf, NULL, LOCK_EX|LOCK_NB)) + { + /* being processed by another queuer */ + if (Verbose || tTd(40, 8)) + printf("%s: locked\n", e->e_id); +# ifdef LOG + if (LogLevel > 19) + syslog(LOG_DEBUG, "%s: locked", e->e_id); +# endif /* LOG */ + (void) fclose(qfp); + return FALSE; + } + + /* + ** Check the queue file for plausibility to avoid attacks. + */ + + if (fstat(fileno(qfp), &st) < 0) + { + /* must have been being processed by someone else */ + if (tTd(40, 8)) + printf("readqf(%s): fstat failure (%s)\n", + qf, errstring(errno)); + fclose(qfp); + return FALSE; + } + + if (st.st_uid != geteuid() || bitset(S_IWOTH|S_IWGRP, st.st_mode)) + { +# ifdef LOG + if (LogLevel > 0) + { + syslog(LOG_ALERT, "%s: bogus queue file, uid=%d, mode=%o", + e->e_id, st.st_uid, st.st_mode); + } +# endif /* LOG */ + if (tTd(40, 8)) + printf("readqf(%s): bogus file\n", qf); + loseqfile(e, "bogus file uid in mqueue"); + fclose(qfp); + return FALSE; + } + + if (st.st_size == 0) + { + /* must be a bogus file -- just remove it */ + (void) unlink(qf); + fclose(qfp); + return FALSE; + } + + if (st.st_nlink == 0) + { + /* + ** Race condition -- we got a file just as it was being + ** unlinked. Just assume it is zero length. + */ + + fclose(qfp); + return FALSE; + } + + /* good file -- save this lock */ + e->e_lockfp = qfp; + + /* do basic system initialization */ + initsys(e); + define('i', e->e_id, e); + + LineNumber = 0; + e->e_flags |= EF_GLOBALERRS; + OpMode = MD_DELIVER; + ctladdr = NULL; + e->e_dfino = -1; + e->e_msgsize = -1; + while ((bp = fgetfolded(buf, sizeof buf, qfp)) != NULL) + { + register char *p; + u_long qflags; + ADDRESS *q; + + if (tTd(40, 4)) + printf("+++++ %s\n", bp); + if (nomore) + { + /* hack attack */ + syserr("SECURITY ALERT: extra data in qf: %s", bp); + fclose(qfp); + loseqfile(e, "bogus queue line"); + return FALSE; + } + switch (bp[0]) + { + case 'V': /* queue file version number */ + qfver = atoi(&bp[1]); + if (qfver > QF_VERSION) + { + syserr("Version number in qf (%d) greater than max (%d)", + qfver, QF_VERSION); + } + break; + + case 'C': /* specify controlling user */ + ctladdr = setctluser(&bp[1]); + break; + + case 'Q': /* original recipient */ + orcpt = newstr(&bp[1]); + break; + + case 'R': /* specify recipient */ + p = bp; + qflags = 0; + if (qfver >= 1) + { + /* get flag bits */ + while (*++p != '\0' && *p != ':') + { + switch (*p) + { + case 'S': + qflags |= QPINGONSUCCESS; + break; + + case 'F': + qflags |= QPINGONFAILURE; + break; + + case 'D': + qflags |= QPINGONDELAY; + break; + + case 'P': + qflags |= QPRIMARY; + break; + } + } + } + else + qflags |= QPRIMARY; + q = parseaddr(++p, NULLADDR, RF_COPYALL, '\0', NULL, e); + if (q != NULL) + { + q->q_alias = ctladdr; + q->q_flags |= qflags; + q->q_orcpt = orcpt; + (void) recipient(q, &e->e_sendqueue, 0, e); + } + orcpt = NULL; + break; + + case 'E': /* specify error recipient */ + /* no longer used */ + break; + + case 'H': /* header */ + (void) chompheader(&bp[1], FALSE, NULL, e); + break; + + case 'M': /* message */ + /* ignore this; we want a new message next time */ + break; + + case 'S': /* sender */ + setsender(newstr(&bp[1]), e, NULL, TRUE); + break; + + case 'B': /* body type */ + e->e_bodytype = newstr(&bp[1]); + break; + + case 'D': /* data file name */ + /* obsolete -- ignore */ + break; + + case 'T': /* init time */ + e->e_ctime = atol(&bp[1]); + break; + + case 'I': /* data file's inode number */ + if (e->e_dfino == -1) + e->e_dfino = atol(&buf[1]); + break; + + case 'K': /* time of last deliver attempt */ + e->e_dtime = atol(&buf[1]); + break; + + case 'N': /* number of delivery attempts */ + e->e_ntries = atoi(&buf[1]); + break; + + case 'P': /* message priority */ + e->e_msgpriority = atol(&bp[1]) + WkTimeFact; + break; + + case 'F': /* flag bits */ + if (strncmp(bp, "From ", 5) == 0) + { + /* we are being spoofed! */ + syserr("SECURITY ALERT: bogus qf line %s", bp); + fclose(qfp); + loseqfile(e, "bogus queue line"); + return FALSE; + } + for (p = &bp[1]; *p != '\0'; p++) + { + switch (*p) + { + case 'w': /* warning sent */ + e->e_flags |= EF_WARNING; + break; + + case 'r': /* response */ + e->e_flags |= EF_RESPONSE; + break; + + case '8': /* has 8 bit data */ + e->e_flags |= EF_HAS8BIT; + break; + } + } + break; + + case 'Z': /* original envelope id from ESMTP */ + e->e_envid = newstr(&bp[1]); + break; + + case '$': /* define macro */ + define(bp[1], newstr(&bp[2]), e); + break; + + case '.': /* terminate file */ + nomore = TRUE; + break; + + default: + syserr("readqf: %s: line %d: bad line \"%s\"", + qf, LineNumber, bp); + fclose(qfp); + loseqfile(e, "unrecognized line"); + return FALSE; + } + + if (bp != buf) + free(bp); + } + + /* + ** If we haven't read any lines, this queue file is empty. + ** Arrange to remove it without referencing any null pointers. + */ + + if (LineNumber == 0) + { + errno = 0; + e->e_flags |= EF_CLRQUEUE | EF_FATALERRS | EF_RESPONSE; + return TRUE; + } + + /* if this has been tried recently, let it be */ + if (e->e_ntries > 0 && (curtime() - e->e_dtime) < MinQueueAge) + { + char *howlong = pintvl(curtime() - e->e_dtime, TRUE); + extern void unlockqueue(); + + if (Verbose || tTd(40, 8)) + printf("%s: too young (%s)\n", + e->e_id, howlong); +#ifdef LOG + if (LogLevel > 19) + syslog(LOG_DEBUG, "%s: too young (%s)", + e->e_id, howlong); +#endif + e->e_id = NULL; + unlockqueue(e); + return FALSE; + } + + /* + ** Arrange to read the data file. + */ + + p = queuename(e, 'd'); + e->e_dfp = fopen(p, "r"); + if (e->e_dfp == NULL) + { + syserr("readqf: cannot open %s", p); + } + else + { + e->e_flags |= EF_HAS_DF; + if (fstat(fileno(e->e_dfp), &st) >= 0) + { + e->e_msgsize = st.st_size; + e->e_dfdev = st.st_dev; + e->e_dfino = st.st_ino; + } + } + + return TRUE; +} +/* +** PRINTQUEUE -- print out a representation of the mail queue +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Prints a listing of the mail queue on the standard output. +*/ + +void +printqueue() +{ + register WORK *w; + FILE *f; + int nrequests; + char buf[MAXLINE]; + + /* + ** Check for permission to print the queue + */ + + if (bitset(PRIV_RESTRICTMAILQ, PrivacyFlags) && RealUid != 0) + { + struct stat st; +# ifdef NGROUPS_MAX + int n; + GIDSET_T gidset[NGROUPS_MAX]; +# endif + + if (stat(QueueDir, &st) < 0) + { + syserr("Cannot stat %s", QueueDir); + return; + } +# ifdef NGROUPS_MAX + n = getgroups(NGROUPS_MAX, gidset); + while (--n >= 0) + { + if (gidset[n] == st.st_gid) + break; + } + if (n < 0 && RealGid != st.st_gid) +# else + if (RealGid != st.st_gid) +# endif + { + usrerr("510 You are not permitted to see the queue"); + setstat(EX_NOPERM); + return; + } + } + + /* + ** Read and order the queue. + */ + + nrequests = orderq(TRUE); + + /* + ** Print the work list that we have read. + */ + + /* first see if there is anything */ + if (nrequests <= 0) + { + printf("Mail queue is empty\n"); + return; + } + + CurrentLA = getla(); /* get load average */ + + printf("\t\tMail Queue (%d request%s", nrequests, nrequests == 1 ? "" : "s"); + if (nrequests > WorkListSize) + printf(", only %d printed", WorkListSize); + if (Verbose) + printf(")\n--Q-ID-- --Size-- -Priority- ---Q-Time--- -----------Sender/Recipient-----------\n"); + else + printf(")\n--Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient------------\n"); + for (w = WorkQ; w != NULL; w = w->w_next) + { + struct stat st; + auto time_t submittime = 0; + long dfsize; + int flags = 0; + int qfver; + char statmsg[MAXLINE]; + char bodytype[MAXNAME + 1]; + + printf("%8s", w->w_name + 2); + f = fopen(w->w_name, "r"); + if (f == NULL) + { + printf(" (job completed)\n"); + errno = 0; + continue; + } + w->w_name[0] = 'd'; + if (stat(w->w_name, &st) >= 0) + dfsize = st.st_size; + else + dfsize = -1; + if (w->w_lock) + printf("*"); + else if (w->w_tooyoung) + printf("-"); + else if (shouldqueue(w->w_pri, w->w_ctime)) + printf("X"); + else + printf(" "); + errno = 0; + + statmsg[0] = bodytype[0] = '\0'; + qfver = 0; + while (fgets(buf, sizeof buf, f) != NULL) + { + register int i; + register char *p; + + fixcrlf(buf, TRUE); + switch (buf[0]) + { + case 'V': /* queue file version */ + qfver = atoi(&buf[1]); + break; + + case 'M': /* error message */ + if ((i = strlen(&buf[1])) >= sizeof statmsg) + i = sizeof statmsg - 1; + bcopy(&buf[1], statmsg, i); + statmsg[i] = '\0'; + break; + + case 'B': /* body type */ + if ((i = strlen(&buf[1])) >= sizeof bodytype) + i = sizeof bodytype - 1; + bcopy(&buf[1], bodytype, i); + bodytype[i] = '\0'; + break; + + case 'S': /* sender name */ + if (Verbose) + printf("%8ld %10ld%c%.12s %.38s", + dfsize, + w->w_pri, + bitset(EF_WARNING, flags) ? '+' : ' ', + ctime(&submittime) + 4, + &buf[1]); + else + printf("%8ld %.16s %.45s", dfsize, + ctime(&submittime), &buf[1]); + if (statmsg[0] != '\0' || bodytype[0] != '\0') + { + printf("\n %10.10s", bodytype); + if (statmsg[0] != '\0') + printf(" (%.60s)", statmsg); + } + break; + + case 'C': /* controlling user */ + if (Verbose) + printf("\n\t\t\t\t (---%.34s---)", + &buf[1]); + break; + + case 'R': /* recipient name */ + p = &buf[1]; + if (qfver >= 1) + { + p = strchr(p, ':'); + if (p == NULL) + break; + p++; + } + if (Verbose) + printf("\n\t\t\t\t\t %.38s", p); + else + printf("\n\t\t\t\t %.45s", p); + break; + + case 'T': /* creation time */ + submittime = atol(&buf[1]); + break; + + case 'F': /* flag bits */ + for (p = &buf[1]; *p != '\0'; p++) + { + switch (*p) + { + case 'w': + flags |= EF_WARNING; + break; + } + } + } + } + if (submittime == (time_t) 0) + printf(" (no control file)"); + printf("\n"); + (void) fclose(f); + } +} + +# endif /* QUEUE */ +/* +** QUEUENAME -- build a file name in the queue directory for this envelope. +** +** Assigns an id code if one does not already exist. +** This code is very careful to avoid trashing existing files +** under any circumstances. +** +** Parameters: +** e -- envelope to build it in/from. +** type -- the file type, used as the first character +** of the file name. +** +** Returns: +** a pointer to the new file name (in a static buffer). +** +** Side Effects: +** If no id code is already assigned, queuename will +** assign an id code, create a qf file, and leave a +** locked, open-for-write file pointer in the envelope. +*/ + +char * +queuename(e, type) + register ENVELOPE *e; + int type; +{ + static int pid = -1; + static char c0; + static char c1; + static char c2; + time_t now; + struct tm *tm; + static char buf[MAXNAME + 1]; + + if (e->e_id == NULL) + { + char qf[20]; + + /* find a unique id */ + if (pid != getpid()) + { + /* new process -- start back at "AA" */ + pid = getpid(); + now = curtime(); + tm = localtime(&now); + c0 = 'A' + tm->tm_hour; + c1 = 'A'; + c2 = 'A' - 1; + } + (void) sprintf(qf, "qf%cAA%05d", c0, pid); + + while (c1 < '~' || c2 < 'Z') + { + int i; + + if (c2 >= 'Z') + { + c1++; + c2 = 'A' - 1; + } + qf[3] = c1; + qf[4] = ++c2; + if (tTd(7, 20)) + printf("queuename: trying \"%s\"\n", qf); + + i = open(qf, O_WRONLY|O_CREAT|O_EXCL, FileMode); + if (i < 0) + { + if (errno == EEXIST) + continue; + syserr("queuename: Cannot create \"%s\" in \"%s\" (euid=%d)", + qf, QueueDir, geteuid()); + exit(EX_UNAVAILABLE); + } + if (lockfile(i, qf, NULL, LOCK_EX|LOCK_NB)) + { + e->e_lockfp = fdopen(i, "w"); + break; + } + + /* a reader got the file; abandon it and try again */ + (void) close(i); + } + if (c1 >= '~' && c2 >= 'Z') + { + syserr("queuename: Cannot create \"%s\" in \"%s\" (euid=%d)", + qf, QueueDir, geteuid()); + exit(EX_OSERR); + } + e->e_id = newstr(&qf[2]); + define('i', e->e_id, e); + if (tTd(7, 1)) + printf("queuename: assigned id %s, env=%x\n", e->e_id, e); + if (tTd(7, 9)) + { + printf(" lockfd="); + dumpfd(fileno(e->e_lockfp), TRUE, FALSE); + } +# ifdef LOG + if (LogLevel > 93) + syslog(LOG_DEBUG, "%s: assigned id", e->e_id); +# endif /* LOG */ + } + + if (type == '\0') + return (NULL); + (void) sprintf(buf, "%cf%s", type, e->e_id); + if (tTd(7, 2)) + printf("queuename: %s\n", buf); + return (buf); +} +/* +** UNLOCKQUEUE -- unlock the queue entry for a specified envelope +** +** Parameters: +** e -- the envelope to unlock. +** +** Returns: +** none +** +** Side Effects: +** unlocks the queue for `e'. +*/ + +void +unlockqueue(e) + ENVELOPE *e; +{ + if (tTd(51, 4)) + printf("unlockqueue(%s)\n", e->e_id); + + /* if there is a lock file in the envelope, close it */ + if (e->e_lockfp != NULL) + xfclose(e->e_lockfp, "unlockqueue", e->e_id); + e->e_lockfp = NULL; + + /* don't create a queue id if we don't already have one */ + if (e->e_id == NULL) + return; + + /* remove the transcript */ +# ifdef LOG + if (LogLevel > 87) + syslog(LOG_DEBUG, "%s: unlock", e->e_id); +# endif /* LOG */ + if (!tTd(51, 104)) + xunlink(queuename(e, 'x')); + +} +/* +** SETCTLUSER -- create a controlling address +** +** Create a fake "address" given only a local login name; this is +** used as a "controlling user" for future recipient addresses. +** +** Parameters: +** user -- the user name of the controlling user. +** +** Returns: +** An address descriptor for the controlling user. +** +** Side Effects: +** none. +*/ + +ADDRESS * +setctluser(user) + char *user; +{ + register ADDRESS *a; + struct passwd *pw; + char *p; + + /* + ** See if this clears our concept of controlling user. + */ + + if (user == NULL || *user == '\0') + return NULL; + + /* + ** Set up addr fields for controlling user. + */ + + a = (ADDRESS *) xalloc(sizeof *a); + bzero((char *) a, sizeof *a); + + p = strchr(user, ':'); + if (p != NULL) + *p++ = '\0'; + if (*user != '\0' && (pw = sm_getpwnam(user)) != NULL) + { + if (strcmp(pw->pw_dir, "/") == 0) + a->q_home = ""; + else + a->q_home = newstr(pw->pw_dir); + a->q_uid = pw->pw_uid; + a->q_gid = pw->pw_gid; + a->q_flags |= QGOODUID; + } + + if (*user != '\0') + a->q_user = newstr(user); + else if (p != NULL) + a->q_user = newstr(p); + else + a->q_user = newstr(DefUser); + + a->q_flags |= QPRIMARY; /* flag as a "ctladdr" */ + a->q_mailer = LocalMailer; + if (p == NULL) + a->q_paddr = a->q_user; + else + a->q_paddr = newstr(p); + return a; +} +/* +** LOSEQFILE -- save the qf as Qf and try to let someone know +** +** Parameters: +** e -- the envelope (e->e_id will be used). +** why -- reported to whomever can hear. +** +** Returns: +** none. +*/ + +void +loseqfile(e, why) + register ENVELOPE *e; + char *why; +{ + char *p; + char buf[40]; + + if (e == NULL || e->e_id == NULL) + return; + if (strlen(e->e_id) > sizeof buf - 4) + return; + strcpy(buf, queuename(e, 'q')); + p = queuename(e, 'Q'); + if (rename(buf, p) < 0) + syserr("cannot rename(%s, %s), uid=%d", buf, p, geteuid()); +#ifdef LOG + else if (LogLevel > 0) + syslog(LOG_ALERT, "Losing %s: %s", buf, why); +#endif +} diff --git a/usr.sbin/sendmail/src/readcf.c b/usr.sbin/sendmail/src/readcf.c new file mode 100644 index 000000000000..c98d82c5054f --- /dev/null +++ b/usr.sbin/sendmail/src/readcf.c @@ -0,0 +1,2554 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)readcf.c 8.138 (Berkeley) 11/20/95"; +#endif /* not lint */ + +# include "sendmail.h" +# include <grp.h> +#if NAMED_BIND +# include <resolv.h> +#endif + +/* +** READCF -- read control file. +** +** This routine reads the control file and builds the internal +** form. +** +** The file is formatted as a sequence of lines, each taken +** atomically. The first character of each line describes how +** the line is to be interpreted. The lines are: +** Dxval Define macro x to have value val. +** Cxword Put word into class x. +** Fxfile [fmt] Read file for lines to put into +** class x. Use scanf string 'fmt' +** or "%s" if not present. Fmt should +** only produce one string-valued result. +** Hname: value Define header with field-name 'name' +** and value as specified; this will be +** macro expanded immediately before +** use. +** Sn Use rewriting set n. +** Rlhs rhs Rewrite addresses that match lhs to +** be rhs. +** Mn arg=val... Define mailer. n is the internal name. +** Args specify mailer parameters. +** Oxvalue Set option x to value. +** Pname=value Set precedence name to value. +** Vversioncode[/vendorcode] +** Version level/vendor name of +** configuration syntax. +** Kmapname mapclass arguments.... +** Define keyed lookup of a given class. +** Arguments are class dependent. +** Eenvar=value Set the environment value to the given value. +** +** Parameters: +** cfname -- control file name. +** safe -- TRUE if this is the system config file; +** FALSE otherwise. +** e -- the main envelope. +** +** Returns: +** none. +** +** Side Effects: +** Builds several internal tables. +*/ + +void +readcf(cfname, safe, e) + char *cfname; + bool safe; + register ENVELOPE *e; +{ + FILE *cf; + int ruleset = 0; + char *q; + struct rewrite *rwp = NULL; + char *bp; + auto char *ep; + int nfuzzy; + char *file; + bool optional; + int mid; + char buf[MAXLINE]; + register char *p; + extern char **copyplist(); + struct stat statb; + char exbuf[MAXLINE]; + char pvpbuf[MAXLINE + MAXATOM]; + static char *null_list[1] = { NULL }; + extern char *munchstring __P((char *, char **)); + extern void fileclass __P((int, char *, char *, bool, bool)); + extern void toomany __P((int, int)); + extern void translate_dollars __P((char *)); + + FileName = cfname; + LineNumber = 0; + + cf = fopen(cfname, "r"); + if (cf == NULL) + { + syserr("cannot open"); + exit(EX_OSFILE); + } + + if (fstat(fileno(cf), &statb) < 0) + { + syserr("cannot fstat"); + exit(EX_OSFILE); + } + + if (!S_ISREG(statb.st_mode)) + { + syserr("not a plain file"); + exit(EX_OSFILE); + } + + if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode)) + { + if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS) + fprintf(stderr, "%s: WARNING: dangerous write permissions\n", + FileName); +#ifdef LOG + if (LogLevel > 0) + syslog(LOG_CRIT, "%s: WARNING: dangerous write permissions", + FileName); +#endif + } + +#ifdef XLA + xla_zero(); +#endif + + while ((bp = fgetfolded(buf, sizeof buf, cf)) != NULL) + { + if (bp[0] == '#') + { + if (bp != buf) + free(bp); + continue; + } + + /* do macro expansion mappings */ + translate_dollars(bp); + + /* interpret this line */ + errno = 0; + switch (bp[0]) + { + case '\0': + case '#': /* comment */ + break; + + case 'R': /* rewriting rule */ + for (p = &bp[1]; *p != '\0' && *p != '\t'; p++) + continue; + + if (*p == '\0') + { + syserr("invalid rewrite line \"%s\" (tab expected)", bp); + break; + } + + /* allocate space for the rule header */ + if (rwp == NULL) + { + RewriteRules[ruleset] = rwp = + (struct rewrite *) xalloc(sizeof *rwp); + } + else + { + rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp); + rwp = rwp->r_next; + } + rwp->r_next = NULL; + + /* expand and save the LHS */ + *p = '\0'; + expand(&bp[1], exbuf, sizeof exbuf, e); + rwp->r_lhs = prescan(exbuf, '\t', pvpbuf, + sizeof pvpbuf, NULL, NULL); + nfuzzy = 0; + if (rwp->r_lhs != NULL) + { + register char **ap; + + rwp->r_lhs = copyplist(rwp->r_lhs, TRUE); + + /* count the number of fuzzy matches in LHS */ + for (ap = rwp->r_lhs; *ap != NULL; ap++) + { + char *botch; + + botch = NULL; + switch (**ap & 0377) + { + case MATCHZANY: + case MATCHANY: + case MATCHONE: + case MATCHCLASS: + case MATCHNCLASS: + nfuzzy++; + break; + + case MATCHREPL: + botch = "$0-$9"; + break; + + case CANONNET: + botch = "$#"; + break; + + case CANONUSER: + botch = "$:"; + break; + + case CALLSUBR: + botch = "$>"; + break; + + case CONDIF: + botch = "$?"; + break; + + case CONDELSE: + botch = "$|"; + break; + + case CONDFI: + botch = "$."; + break; + + case HOSTBEGIN: + botch = "$["; + break; + + case HOSTEND: + botch = "$]"; + break; + + case LOOKUPBEGIN: + botch = "$("; + break; + + case LOOKUPEND: + botch = "$)"; + break; + } + if (botch != NULL) + syserr("Inappropriate use of %s on LHS", + botch); + } + } + else + { + syserr("R line: null LHS"); + rwp->r_lhs = null_list; + } + + /* expand and save the RHS */ + while (*++p == '\t') + continue; + q = p; + while (*p != '\0' && *p != '\t') + p++; + *p = '\0'; + expand(q, exbuf, sizeof exbuf, e); + rwp->r_rhs = prescan(exbuf, '\t', pvpbuf, + sizeof pvpbuf, NULL, NULL); + if (rwp->r_rhs != NULL) + { + register char **ap; + + rwp->r_rhs = copyplist(rwp->r_rhs, TRUE); + + /* check no out-of-bounds replacements */ + nfuzzy += '0'; + for (ap = rwp->r_rhs; *ap != NULL; ap++) + { + char *botch; + + botch = NULL; + switch (**ap & 0377) + { + case MATCHREPL: + if ((*ap)[1] <= '0' || (*ap)[1] > nfuzzy) + { + syserr("replacement $%c out of bounds", + (*ap)[1]); + } + break; + + case MATCHZANY: + botch = "$*"; + break; + + case MATCHANY: + botch = "$+"; + break; + + case MATCHONE: + botch = "$-"; + break; + + case MATCHCLASS: + botch = "$="; + break; + + case MATCHNCLASS: + botch = "$~"; + break; + } + if (botch != NULL) + syserr("Inappropriate use of %s on RHS", + botch); + } + } + else + { + syserr("R line: null RHS"); + rwp->r_rhs = null_list; + } + break; + + case 'S': /* select rewriting set */ + expand(&bp[1], exbuf, sizeof exbuf, e); + ruleset = strtorwset(exbuf, NULL, ST_ENTER); + if (ruleset < 0) + break; + rwp = RewriteRules[ruleset]; + if (rwp != NULL) + { + while (rwp->r_next != NULL) + rwp = rwp->r_next; + fprintf(stderr, "WARNING: Ruleset %s redefined\n", + &bp[1]); + } + break; + + case 'D': /* macro definition */ + mid = macid(&bp[1], &ep); + p = munchstring(ep, NULL); + define(mid, newstr(p), e); + break; + + case 'H': /* required header line */ + (void) chompheader(&bp[1], TRUE, NULL, e); + break; + + case 'C': /* word class */ + case 'T': /* trusted user (set class `t') */ + if (bp[0] == 'C') + { + mid = macid(&bp[1], &ep); + expand(ep, exbuf, sizeof exbuf, e); + p = exbuf; + } + else + { + mid = 't'; + p = &bp[1]; + } + while (*p != '\0') + { + register char *wd; + char delim; + + while (*p != '\0' && isascii(*p) && isspace(*p)) + p++; + wd = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + delim = *p; + *p = '\0'; + if (wd[0] != '\0') + setclass(mid, wd); + *p = delim; + } + break; + + case 'F': /* word class from file */ + mid = macid(&bp[1], &ep); + for (p = ep; isascii(*p) && isspace(*p); ) + p++; + if (p[0] == '-' && p[1] == 'o') + { + optional = TRUE; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + while (isascii(*p) && isspace(*p)) + p++; + } + else + optional = FALSE; + file = p; + if (*file == '|') + p = "%s"; + else + { + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p == '\0') + p = "%s"; + else + { + *p = '\0'; + while (isascii(*++p) && isspace(*p)) + continue; + } + } + fileclass(mid, file, p, safe, optional); + break; + +#ifdef XLA + case 'L': /* extended load average description */ + xla_init(&bp[1]); + break; +#endif + + case 'M': /* define mailer */ + makemailer(&bp[1]); + break; + + case 'O': /* set option */ + setoption(bp[1], &bp[2], safe, FALSE, e); + break; + + case 'P': /* set precedence */ + if (NumPriorities >= MAXPRIORITIES) + { + toomany('P', MAXPRIORITIES); + break; + } + for (p = &bp[1]; *p != '\0' && *p != '='; p++) + continue; + if (*p == '\0') + goto badline; + *p = '\0'; + Priorities[NumPriorities].pri_name = newstr(&bp[1]); + Priorities[NumPriorities].pri_val = atoi(++p); + NumPriorities++; + break; + + case 'V': /* configuration syntax version */ + for (p = &bp[1]; isascii(*p) && isspace(*p); p++) + continue; + if (!isascii(*p) || !isdigit(*p)) + { + syserr("invalid argument to V line: \"%.20s\"", + &bp[1]); + break; + } + ConfigLevel = strtol(p, &ep, 10); + + /* + ** Do heuristic tweaking for back compatibility. + */ + + if (ConfigLevel >= 5) + { + /* level 5 configs have short name in $w */ + p = macvalue('w', e); + if (p != NULL && (p = strchr(p, '.')) != NULL) + *p = '\0'; + define('w', macvalue('w', e), e); + } + if (ConfigLevel >= 6) + { + ColonOkInAddr = FALSE; + } + + /* + ** Look for vendor code. + */ + + if (*ep++ == '/') + { + /* extract vendor code */ + for (p = ep; isascii(*p) && isalpha(*p); ) + p++; + *p = '\0'; + + if (!setvendor(ep)) + syserr("invalid V line vendor code: \"%s\"", + ep); + } + break; + + case 'K': + expand(&bp[1], exbuf, sizeof exbuf, e); + (void) makemapentry(exbuf); + break; + + case 'E': + p = strchr(bp, '='); + if (p != NULL) + *p++ = '\0'; + setuserenv(&bp[1], p); + break; + + default: + badline: + syserr("unknown control line \"%s\"", bp); + } + if (bp != buf) + free(bp); + } + if (ferror(cf)) + { + syserr("I/O read error"); + exit(EX_OSFILE); + } + fclose(cf); + FileName = NULL; + + /* initialize host maps from local service tables */ + inithostmaps(); + + /* determine if we need to do special name-server frotz */ + { + int nmaps; + char *maptype[MAXMAPSTACK]; + short mapreturn[MAXMAPACTIONS]; + + nmaps = switch_map_find("hosts", maptype, mapreturn); + UseNameServer = FALSE; + if (nmaps > 0 && nmaps <= MAXMAPSTACK) + { + register int mapno; + + for (mapno = 0; mapno < nmaps && !UseNameServer; mapno++) + { + if (strcmp(maptype[mapno], "dns") == 0) + UseNameServer = TRUE; + } + } + +#ifdef HESIOD + nmaps = switch_map_find("passwd", maptype, mapreturn); + UseHesiod = FALSE; + if (nmaps > 0 && nmaps <= MAXMAPSTACK) + { + register int mapno; + + for (mapno = 0; mapno < nmaps && !UseHesiod; mapno++) + { + if (strcmp(maptype[mapno], "hesiod") == 0) + UseHesiod = TRUE; + } + } +#endif + } +} +/* +** TRANSLATE_DOLLARS -- convert $x into internal form +** +** Actually does all appropriate pre-processing of a config line +** to turn it into internal form. +** +** Parameters: +** bp -- the buffer to translate. +** +** Returns: +** None. The buffer is translated in place. Since the +** translations always make the buffer shorter, this is +** safe without a size parameter. +*/ + +void +translate_dollars(bp) + char *bp; +{ + register char *p; + auto char *ep; + + for (p = bp; *p != '\0'; p++) + { + if (*p == '#' && p > bp && ConfigLevel >= 3) + { + /* this is an on-line comment */ + register char *e; + + switch (*--p & 0377) + { + case MACROEXPAND: + /* it's from $# -- let it go through */ + p++; + break; + + case '\\': + /* it's backslash escaped */ + (void) strcpy(p, p + 1); + break; + + default: + /* delete preceeding white space */ + while (isascii(*p) && isspace(*p) && + *p != '\n' && p > bp) + p--; + if ((e = strchr(++p, '\n')) != NULL) + (void) strcpy(p, e); + else + *p-- = '\0'; + break; + } + continue; + } + + if (*p != '$' || p[1] == '\0') + continue; + + if (p[1] == '$') + { + /* actual dollar sign.... */ + (void) strcpy(p, p + 1); + continue; + } + + /* convert to macro expansion character */ + *p++ = MACROEXPAND; + + /* special handling for $=, $~, $&, and $? */ + if (*p == '=' || *p == '~' || *p == '&' || *p == '?') + p++; + + /* convert macro name to code */ + *p = macid(p, &ep); + if (ep != p) + strcpy(p + 1, ep); + } + + /* strip trailing white space from the line */ + while (--p > bp && isascii(*p) && isspace(*p)) + *p = '\0'; +} +/* +** TOOMANY -- signal too many of some option +** +** Parameters: +** id -- the id of the error line +** maxcnt -- the maximum possible values +** +** Returns: +** none. +** +** Side Effects: +** gives a syserr. +*/ + +void +toomany(id, maxcnt) + int id; + int maxcnt; +{ + syserr("too many %c lines, %d max", id, maxcnt); +} +/* +** FILECLASS -- read members of a class from a file +** +** Parameters: +** class -- class to define. +** filename -- name of file to read. +** fmt -- scanf string to use for match. +** safe -- if set, this is a safe read. +** optional -- if set, it is not an error for the file to +** not exist. +** +** Returns: +** none +** +** Side Effects: +** +** puts all lines in filename that match a scanf into +** the named class. +*/ + +void +fileclass(class, filename, fmt, safe, optional) + int class; + char *filename; + char *fmt; + bool safe; + bool optional; +{ + FILE *f; + int sff; + int pid; + register char *p; + char buf[MAXLINE]; + + if (tTd(37, 2)) + printf("fileclass(%s, fmt=%s)\n", filename, fmt); + + if (filename[0] == '|') + { + auto int fd; + int i; + char *argv[MAXPV + 1]; + + i = 0; + for (p = strtok(&filename[1], " \t"); p != NULL; p = strtok(NULL, " \t")) + { + if (i >= MAXPV) + break; + argv[i++] = p; + } + argv[i] = NULL; + pid = prog_open(argv, &fd, CurEnv); + if (pid < 0) + f = NULL; + else + f = fdopen(fd, "r"); + } + else + { + pid = -1; + sff = SFF_REGONLY; + if (safe) + sff |= SFF_OPENASROOT; + f = safefopen(filename, O_RDONLY, 0, sff); + } + if (f == NULL) + { + if (!optional) + syserr("fileclass: cannot open %s", filename); + return; + } + + while (fgets(buf, sizeof buf, f) != NULL) + { + register char *p; +# if SCANF + char wordbuf[MAXNAME+1]; +# endif + + if (buf[0] == '#') + continue; +# if SCANF + if (sscanf(buf, fmt, wordbuf) != 1) + continue; + p = wordbuf; +# else /* SCANF */ + p = buf; +# endif /* SCANF */ + + /* + ** Break up the match into words. + */ + + while (*p != '\0') + { + register char *q; + + /* strip leading spaces */ + while (isascii(*p) && isspace(*p)) + p++; + if (*p == '\0') + break; + + /* find the end of the word */ + q = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + + /* enter the word in the symbol table */ + setclass(class, q); + } + } + + (void) fclose(f); + if (pid > 0) + (void) waitfor(pid); +} +/* +** MAKEMAILER -- define a new mailer. +** +** Parameters: +** line -- description of mailer. This is in labeled +** fields. The fields are: +** A -- the argv for this mailer +** C -- the character set for MIME conversions +** D -- the directory to run in +** E -- the eol string +** F -- the flags associated with the mailer +** L -- the maximum line length +** M -- the maximum message size +** N -- the niceness at which to run +** P -- the path to the mailer +** R -- the recipient rewriting set +** S -- the sender rewriting set +** T -- the mailer type (for DSNs) +** U -- the uid to run as +** The first word is the canonical name of the mailer. +** +** Returns: +** none. +** +** Side Effects: +** enters the mailer into the mailer table. +*/ + +void +makemailer(line) + char *line; +{ + register char *p; + register struct mailer *m; + register STAB *s; + int i; + char fcode; + auto char *endp; + extern int NextMailer; + extern char **makeargv(); + extern char *munchstring(); + + /* allocate a mailer and set up defaults */ + m = (struct mailer *) xalloc(sizeof *m); + bzero((char *) m, sizeof *m); + m->m_eol = "\n"; + m->m_uid = m->m_gid = 0; + + /* collect the mailer name */ + for (p = line; *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); p++) + continue; + if (*p != '\0') + *p++ = '\0'; + if (line[0] == '\0') + syserr("name required for mailer"); + m->m_name = newstr(line); + + /* now scan through and assign info from the fields */ + while (*p != '\0') + { + auto char *delimptr; + + while (*p != '\0' && (*p == ',' || (isascii(*p) && isspace(*p)))) + p++; + + /* p now points to field code */ + fcode = *p; + while (*p != '\0' && *p != '=' && *p != ',') + p++; + if (*p++ != '=') + { + syserr("mailer %s: `=' expected", m->m_name); + return; + } + while (isascii(*p) && isspace(*p)) + p++; + + /* p now points to the field body */ + p = munchstring(p, &delimptr); + + /* install the field into the mailer struct */ + switch (fcode) + { + case 'P': /* pathname */ + if (*p == '\0') + syserr("mailer %s: empty path name", m->m_name); + m->m_mailer = newstr(p); + break; + + case 'F': /* flags */ + for (; *p != '\0'; p++) + if (!(isascii(*p) && isspace(*p))) + setbitn(*p, m->m_flags); + break; + + case 'S': /* sender rewriting ruleset */ + case 'R': /* recipient rewriting ruleset */ + i = strtorwset(p, &endp, ST_ENTER); + if (i < 0) + return; + if (fcode == 'S') + m->m_sh_rwset = m->m_se_rwset = i; + else + m->m_rh_rwset = m->m_re_rwset = i; + + p = endp; + if (*p++ == '/') + { + i = strtorwset(p, NULL, ST_ENTER); + if (i < 0) + return; + if (fcode == 'S') + m->m_sh_rwset = i; + else + m->m_rh_rwset = i; + } + break; + + case 'E': /* end of line string */ + if (*p == '\0') + syserr("mailer %s: null end-of-line string", + m->m_name); + m->m_eol = newstr(p); + break; + + case 'A': /* argument vector */ + if (*p == '\0') + syserr("mailer %s: null argument vector", + m->m_name); + m->m_argv = makeargv(p); + break; + + case 'M': /* maximum message size */ + m->m_maxsize = atol(p); + break; + + case 'L': /* maximum line length */ + m->m_linelimit = atoi(p); + break; + + case 'N': /* run niceness */ + m->m_nice = atoi(p); + break; + + case 'D': /* working directory */ + if (*p == '\0') + syserr("mailer %s: null working directory", + m->m_name); + m->m_execdir = newstr(p); + break; + + case 'C': /* default charset */ + if (*p == '\0') + syserr("mailer %s: null charset", m->m_name); + m->m_defcharset = newstr(p); + break; + + case 'T': /* MTA-Name/Address/Diagnostic types */ + /* extract MTA name type; default to "dns" */ + m->m_mtatype = newstr(p); + p = strchr(m->m_mtatype, '/'); + if (p != NULL) + { + *p++ = '\0'; + if (*p == '\0') + p = NULL; + } + if (*m->m_mtatype == '\0') + m->m_mtatype = "dns"; + + /* extract address type; default to "rfc822" */ + m->m_addrtype = p; + if (p != NULL) + p = strchr(p, '/'); + if (p != NULL) + { + *p++ = '\0'; + if (*p == '\0') + p = NULL; + } + if (m->m_addrtype == NULL || *m->m_addrtype == '\0') + m->m_addrtype = "rfc822"; + + /* extract diagnostic type; default to "smtp" */ + m->m_diagtype = p; + if (m->m_diagtype == NULL || *m->m_diagtype == '\0') + m->m_diagtype = "smtp"; + break; + + case 'U': /* user id */ + if (isascii(*p) && !isdigit(*p)) + { + char *q = p; + struct passwd *pw; + + while (*p != '\0' && isascii(*p) && + (isalnum(*p) || strchr("-_", *p) != NULL)) + p++; + while (isascii(*p) && isspace(*p)) + *p++ = '\0'; + if (*p != '\0') + *p++ = '\0'; + if (*q == '\0') + syserr("mailer %s: null user name", + m->m_name); + pw = sm_getpwnam(q); + if (pw == NULL) + syserr("readcf: mailer U= flag: unknown user %s", q); + else + { + m->m_uid = pw->pw_uid; + m->m_gid = pw->pw_gid; + } + } + else + { + auto char *q; + + m->m_uid = strtol(p, &q, 0); + p = q; + } + while (isascii(*p) && isspace(*p)) + p++; + if (*p == '\0') + break; + if (isascii(*p) && !isdigit(*p)) + { + char *q = p; + struct group *gr; + + while (isascii(*p) && isalnum(*p)) + p++; + *p++ = '\0'; + if (*q == '\0') + syserr("mailer %s: null group name", + m->m_name); + gr = getgrnam(q); + if (gr == NULL) + syserr("readcf: mailer U= flag: unknown group %s", q); + else + m->m_gid = gr->gr_gid; + } + else + { + m->m_gid = strtol(p, NULL, 0); + } + break; + } + + p = delimptr; + } + + /* do some rationality checking */ + if (m->m_argv == NULL) + { + syserr("M%s: A= argument required", m->m_name); + return; + } + if (m->m_mailer == NULL) + { + syserr("M%s: P= argument required", m->m_name); + return; + } + + if (NextMailer >= MAXMAILERS) + { + syserr("too many mailers defined (%d max)", MAXMAILERS); + return; + } + + /* do some heuristic cleanup for back compatibility */ + if (bitnset(M_LIMITS, m->m_flags)) + { + if (m->m_linelimit == 0) + m->m_linelimit = SMTPLINELIM; + if (ConfigLevel < 2) + setbitn(M_7BITS, m->m_flags); + } + + if (strcmp(m->m_mailer, "[IPC]") == 0 || + strcmp(m->m_mailer, "[TCP]") == 0) + { + if (m->m_mtatype == NULL) + m->m_mtatype = "dns"; + if (m->m_addrtype == NULL) + m->m_addrtype = "rfc822"; + if (m->m_diagtype == NULL) + m->m_diagtype = "smtp"; + } + + /* enter the mailer into the symbol table */ + s = stab(m->m_name, ST_MAILER, ST_ENTER); + if (s->s_mailer != NULL) + { + i = s->s_mailer->m_mno; + free(s->s_mailer); + } + else + { + i = NextMailer++; + } + Mailer[i] = s->s_mailer = m; + m->m_mno = i; +} +/* +** MUNCHSTRING -- translate a string into internal form. +** +** Parameters: +** p -- the string to munch. +** delimptr -- if non-NULL, set to the pointer of the +** field delimiter character. +** +** Returns: +** the munched string. +*/ + +char * +munchstring(p, delimptr) + register char *p; + char **delimptr; +{ + register char *q; + bool backslash = FALSE; + bool quotemode = FALSE; + static char buf[MAXLINE]; + + for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++) + { + if (backslash) + { + /* everything is roughly literal */ + backslash = FALSE; + switch (*p) + { + case 'r': /* carriage return */ + *q++ = '\r'; + continue; + + case 'n': /* newline */ + *q++ = '\n'; + continue; + + case 'f': /* form feed */ + *q++ = '\f'; + continue; + + case 'b': /* backspace */ + *q++ = '\b'; + continue; + } + *q++ = *p; + } + else + { + if (*p == '\\') + backslash = TRUE; + else if (*p == '"') + quotemode = !quotemode; + else if (quotemode || *p != ',') + *q++ = *p; + else + break; + } + } + + if (delimptr != NULL) + *delimptr = p; + *q++ = '\0'; + return (buf); +} +/* +** MAKEARGV -- break up a string into words +** +** Parameters: +** p -- the string to break up. +** +** Returns: +** a char **argv (dynamically allocated) +** +** Side Effects: +** munges p. +*/ + +char ** +makeargv(p) + register char *p; +{ + char *q; + int i; + char **avp; + char *argv[MAXPV + 1]; + + /* take apart the words */ + i = 0; + while (*p != '\0' && i < MAXPV) + { + q = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + while (isascii(*p) && isspace(*p)) + *p++ = '\0'; + argv[i++] = newstr(q); + } + argv[i++] = NULL; + + /* now make a copy of the argv */ + avp = (char **) xalloc(sizeof *avp * i); + bcopy((char *) argv, (char *) avp, sizeof *avp * i); + + return (avp); +} +/* +** PRINTRULES -- print rewrite rules (for debugging) +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** prints rewrite rules. +*/ + +void +printrules() +{ + register struct rewrite *rwp; + register int ruleset; + + for (ruleset = 0; ruleset < 10; ruleset++) + { + if (RewriteRules[ruleset] == NULL) + continue; + printf("\n----Rule Set %d:", ruleset); + + for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) + { + printf("\nLHS:"); + printav(rwp->r_lhs); + printf("RHS:"); + printav(rwp->r_rhs); + } + } +} +/* +** PRINTMAILER -- print mailer structure (for debugging) +** +** Parameters: +** m -- the mailer to print +** +** Returns: +** none. +*/ + +void +printmailer(m) + register MAILER *m; +{ + int j; + + printf("mailer %d (%s): P=%s S=%d/%d R=%d/%d M=%ld U=%d:%d F=", + m->m_mno, m->m_name, + m->m_mailer, m->m_se_rwset, m->m_sh_rwset, + m->m_re_rwset, m->m_rh_rwset, m->m_maxsize, + m->m_uid, m->m_gid); + for (j = '\0'; j <= '\177'; j++) + if (bitnset(j, m->m_flags)) + (void) putchar(j); + printf(" L=%d E=", m->m_linelimit); + xputs(m->m_eol); + if (m->m_defcharset != NULL) + printf(" C=%s", m->m_defcharset); + printf(" T=%s/%s/%s", + m->m_mtatype == NULL ? "<undefined>" : m->m_mtatype, + m->m_addrtype == NULL ? "<undefined>" : m->m_addrtype, + m->m_diagtype == NULL ? "<undefined>" : m->m_diagtype); + if (m->m_argv != NULL) + { + char **a = m->m_argv; + + printf(" A="); + while (*a != NULL) + { + if (a != m->m_argv) + printf(" "); + xputs(*a++); + } + } + printf("\n"); +} +/* +** SETOPTION -- set global processing option +** +** Parameters: +** opt -- option name. +** val -- option value (as a text string). +** safe -- set if this came from a configuration file. +** Some options (if set from the command line) will +** reset the user id to avoid security problems. +** sticky -- if set, don't let other setoptions override +** this value. +** e -- the main envelope. +** +** Returns: +** none. +** +** Side Effects: +** Sets options as implied by the arguments. +*/ + +static BITMAP StickyOpt; /* set if option is stuck */ +extern void settimeout __P((char *, char *)); + + +#if NAMED_BIND + +struct resolverflags +{ + char *rf_name; /* name of the flag */ + long rf_bits; /* bits to set/clear */ +} ResolverFlags[] = +{ + "debug", RES_DEBUG, + "aaonly", RES_AAONLY, + "usevc", RES_USEVC, + "primary", RES_PRIMARY, + "igntc", RES_IGNTC, + "recurse", RES_RECURSE, + "defnames", RES_DEFNAMES, + "stayopen", RES_STAYOPEN, + "dnsrch", RES_DNSRCH, + "true", 0, /* to avoid error on old syntax */ + NULL, 0 +}; + +#endif + +struct optioninfo +{ + char *o_name; /* long name of option */ + u_char o_code; /* short name of option */ + bool o_safe; /* safe for random people to use */ +} OptionTab[] = +{ + "SevenBitInput", '7', TRUE, +#if MIME8TO7 + "EightBitMode", '8', TRUE, +#endif + "AliasFile", 'A', FALSE, + "AliasWait", 'a', FALSE, + "BlankSub", 'B', FALSE, + "MinFreeBlocks", 'b', TRUE, + "CheckpointInterval", 'C', TRUE, + "HoldExpensive", 'c', FALSE, + "AutoRebuildAliases", 'D', FALSE, + "DeliveryMode", 'd', TRUE, + "ErrorHeader", 'E', FALSE, + "ErrorMode", 'e', TRUE, + "TempFileMode", 'F', FALSE, + "SaveFromLine", 'f', FALSE, + "MatchGECOS", 'G', FALSE, + "HelpFile", 'H', FALSE, + "MaxHopCount", 'h', FALSE, + "ResolverOptions", 'I', FALSE, + "IgnoreDots", 'i', TRUE, + "ForwardPath", 'J', FALSE, + "SendMimeErrors", 'j', TRUE, + "ConnectionCacheSize", 'k', FALSE, + "ConnectionCacheTimeout", 'K', FALSE, + "UseErrorsTo", 'l', FALSE, + "LogLevel", 'L', FALSE, + "MeToo", 'm', TRUE, + "CheckAliases", 'n', FALSE, + "OldStyleHeaders", 'o', TRUE, + "DaemonPortOptions", 'O', FALSE, + "PrivacyOptions", 'p', TRUE, + "PostmasterCopy", 'P', FALSE, + "QueueFactor", 'q', FALSE, + "QueueDirectory", 'Q', FALSE, + "DontPruneRoutes", 'R', FALSE, + "Timeout", 'r', TRUE, + "StatusFile", 'S', FALSE, + "SuperSafe", 's', TRUE, + "QueueTimeout", 'T', FALSE, + "TimeZoneSpec", 't', FALSE, + "UserDatabaseSpec", 'U', FALSE, + "DefaultUser", 'u', FALSE, + "FallbackMXhost", 'V', FALSE, + "Verbose", 'v', TRUE, + "TryNullMXList", 'w', TRUE, + "QueueLA", 'x', FALSE, + "RefuseLA", 'X', FALSE, + "RecipientFactor", 'y', FALSE, + "ForkEachJob", 'Y', FALSE, + "ClassFactor", 'z', FALSE, + "RetryFactor", 'Z', FALSE, +#define O_QUEUESORTORD 0x81 + "QueueSortOrder", O_QUEUESORTORD, TRUE, +#define O_HOSTSFILE 0x82 + "HostsFile", O_HOSTSFILE, FALSE, +#define O_MQA 0x83 + "MinQueueAge", O_MQA, TRUE, +#define O_MHSA 0x84 +/* + "MaxHostStatAge", O_MHSA, TRUE, +*/ +#define O_DEFCHARSET 0x85 + "DefaultCharSet", O_DEFCHARSET, TRUE, +#define O_SSFILE 0x86 + "ServiceSwitchFile", O_SSFILE, FALSE, +#define O_DIALDELAY 0x87 + "DialDelay", O_DIALDELAY, TRUE, +#define O_NORCPTACTION 0x88 + "NoRecipientAction", O_NORCPTACTION, TRUE, +#define O_SAFEFILEENV 0x89 + "SafeFileEnvironment", O_SAFEFILEENV, FALSE, +#define O_MAXMSGSIZE 0x8a + "MaxMessageSize", O_MAXMSGSIZE, FALSE, +#define O_COLONOKINADDR 0x8b + "ColonOkInAddr", O_COLONOKINADDR, TRUE, +#define O_MAXQUEUERUN 0x8c + "MaxQueueRunSize", O_MAXQUEUERUN, TRUE, +#define O_MAXCHILDREN 0x8d +/* + "MaxDaemonChildren", O_MAXCHILDREN, FALSE, +*/ +#define O_KEEPCNAMES 0x8e + "DontExpandCnames", O_KEEPCNAMES, FALSE, +#define O_MUSTQUOTE 0x8f +/* + "MustQuoteChars", O_MUSTQUOTE, FALSE, +*/ +#define O_SMTPGREETING 0x90 + "SmtpGreetingMessage", O_SMTPGREETING, FALSE, +#define O_UNIXFROM 0x91 + "UnixFromLine", O_UNIXFROM, FALSE, +#define O_OPCHARS 0x92 + "OperatorChars", O_OPCHARS, FALSE, +#define O_DONTINITGRPS 0x93 + "DontInitGroups", O_DONTINITGRPS, TRUE, +#define O_SLFH 0x94 +#ifdef LOTUS_NOTES_HACK + "SingleLineFromHeader", O_SLFH, TRUE, +#endif + + NULL, '\0', FALSE, +}; + + + +void +setoption(opt, val, safe, sticky, e) + int opt; + char *val; + bool safe; + bool sticky; + register ENVELOPE *e; +{ + register char *p; + register struct optioninfo *o; + char *subopt; + char buf[50]; + extern bool atobool(); + extern time_t convtime(); + extern int QueueLA; + extern int RefuseLA; + extern bool Warn_Q_option; + + errno = 0; + if (opt == ' ') + { + /* full word options */ + struct optioninfo *sel; + + p = strchr(val, '='); + if (p == NULL) + p = &val[strlen(val)]; + while (*--p == ' ') + continue; + while (*++p == ' ') + *p = '\0'; + if (p == val) + { + syserr("readcf: null option name"); + return; + } + if (*p == '=') + *p++ = '\0'; + while (*p == ' ') + p++; + subopt = strchr(val, '.'); + if (subopt != NULL) + *subopt++ = '\0'; + sel = NULL; + for (o = OptionTab; o->o_name != NULL; o++) + { + if (strncasecmp(o->o_name, val, strlen(val)) != 0) + continue; + if (strlen(o->o_name) == strlen(val)) + { + /* completely specified -- this must be it */ + sel = NULL; + break; + } + if (sel != NULL) + break; + sel = o; + } + if (sel != NULL && o->o_name == NULL) + o = sel; + else if (o->o_name == NULL) + { + syserr("readcf: unknown option name %s", val); + return; + } + else if (sel != NULL) + { + syserr("readcf: ambiguous option name %s (matches %s and %s)", + val, sel->o_name, o->o_name); + return; + } + if (strlen(val) != strlen(o->o_name)) + { + bool oldVerbose = Verbose; + + Verbose = TRUE; + message("Option %s used as abbreviation for %s", + val, o->o_name); + Verbose = oldVerbose; + } + opt = o->o_code; + val = p; + } + else + { + for (o = OptionTab; o->o_name != NULL; o++) + { + if (o->o_code == opt) + break; + } + subopt = NULL; + } + + if (tTd(37, 1)) + { + printf(isascii(opt) && isprint(opt) ? + "setoption %s (%c).%s=" : + "setoption %s (0x%x).%s=", + o->o_name == NULL ? "<unknown>" : o->o_name, + opt, + subopt == NULL ? "" : subopt); + xputs(val); + } + + /* + ** See if this option is preset for us. + */ + + if (!sticky && bitnset(opt, StickyOpt)) + { + if (tTd(37, 1)) + printf(" (ignored)\n"); + return; + } + + /* + ** Check to see if this option can be specified by this user. + */ + + if (!safe && RealUid == 0) + safe = TRUE; + if (!safe && !o->o_safe) + { + if (opt != 'M' || (val[0] != 'r' && val[0] != 's')) + { + if (tTd(37, 1)) + printf(" (unsafe)"); + if (RealUid != geteuid()) + { + if (tTd(37, 1)) + printf("(Resetting uid)"); + endpwent(); + (void) setgid(RealGid); + (void) setuid(RealUid); + } + } + } + if (tTd(37, 1)) + printf("\n"); + + switch (opt & 0xff) + { + case '7': /* force seven-bit input */ + SevenBitInput = atobool(val); + break; + +#if MIME8TO7 + case '8': /* handling of 8-bit input */ + switch (*val) + { + case 'm': /* convert 8-bit, convert MIME */ + MimeMode = MM_CVTMIME|MM_MIME8BIT; + break; + + case 'p': /* pass 8 bit, convert MIME */ + MimeMode = MM_CVTMIME|MM_PASS8BIT; + break; + + case 's': /* strict adherence */ + MimeMode = MM_CVTMIME; + break; + +#if 0 + case 'r': /* reject 8-bit, don't convert MIME */ + MimeMode = 0; + break; + + case 'j': /* "just send 8" */ + MimeMode = MM_PASS8BIT; + break; + + case 'a': /* encode 8 bit if available */ + MimeMode = MM_MIME8BIT|MM_PASS8BIT|MM_CVTMIME; + break; + + case 'c': /* convert 8 bit to MIME, never 7 bit */ + MimeMode = MM_MIME8BIT; + break; +#endif + + default: + syserr("Unknown 8-bit mode %c", *val); + exit(EX_USAGE); + } + break; +#endif + + case 'A': /* set default alias file */ + if (val[0] == '\0') + setalias("aliases"); + else + setalias(val); + break; + + case 'a': /* look N minutes for "@:@" in alias file */ + if (val[0] == '\0') + SafeAlias = 5 * 60; /* five minutes */ + else + SafeAlias = convtime(val, 'm'); + break; + + case 'B': /* substitution for blank character */ + SpaceSub = val[0]; + if (SpaceSub == '\0') + SpaceSub = ' '; + break; + + case 'b': /* min blocks free on queue fs/max msg size */ + p = strchr(val, '/'); + if (p != NULL) + { + *p++ = '\0'; + MaxMessageSize = atol(p); + } + MinBlocksFree = atol(val); + break; + + case 'c': /* don't connect to "expensive" mailers */ + NoConnect = atobool(val); + break; + + case 'C': /* checkpoint every N addresses */ + CheckpointInterval = atoi(val); + break; + + case 'd': /* delivery mode */ + switch (*val) + { + case '\0': + e->e_sendmode = SM_DELIVER; + break; + + case SM_QUEUE: /* queue only */ + case SM_DEFER: /* queue only and defer map lookups */ +#ifndef QUEUE + syserr("need QUEUE to set -odqueue or -oddefer"); +#endif /* QUEUE */ + /* fall through..... */ + + case SM_DELIVER: /* do everything */ + case SM_FORK: /* fork after verification */ + e->e_sendmode = *val; + break; + + default: + syserr("Unknown delivery mode %c", *val); + exit(EX_USAGE); + } + break; + + case 'D': /* rebuild alias database as needed */ + AutoRebuild = atobool(val); + break; + + case 'E': /* error message header/header file */ + if (*val != '\0') + ErrMsgFile = newstr(val); + break; + + case 'e': /* set error processing mode */ + switch (*val) + { + case EM_QUIET: /* be silent about it */ + case EM_MAIL: /* mail back */ + case EM_BERKNET: /* do berknet error processing */ + case EM_WRITE: /* write back (or mail) */ + case EM_PRINT: /* print errors normally (default) */ + e->e_errormode = *val; + break; + } + break; + + case 'F': /* file mode */ + FileMode = atooct(val) & 0777; + break; + + case 'f': /* save Unix-style From lines on front */ + SaveFrom = atobool(val); + break; + + case 'G': /* match recipients against GECOS field */ + MatchGecos = atobool(val); + break; + + case 'g': /* default gid */ + g_opt: + if (isascii(*val) && isdigit(*val)) + DefGid = atoi(val); + else + { + register struct group *gr; + + DefGid = -1; + gr = getgrnam(val); + if (gr == NULL) + syserr("readcf: option %c: unknown group %s", + opt, val); + else + DefGid = gr->gr_gid; + } + break; + + case 'H': /* help file */ + if (val[0] == '\0') + HelpFile = "sendmail.hf"; + else + HelpFile = newstr(val); + break; + + case 'h': /* maximum hop count */ + MaxHopCount = atoi(val); + break; + + case 'I': /* use internet domain name server */ +#if NAMED_BIND + for (p = val; *p != 0; ) + { + bool clearmode; + char *q; + struct resolverflags *rfp; + + while (*p == ' ') + p++; + if (*p == '\0') + break; + clearmode = FALSE; + if (*p == '-') + clearmode = TRUE; + else if (*p != '+') + p--; + p++; + q = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + if (strcasecmp(q, "HasWildcardMX") == 0) + { + HasWildcardMX = !clearmode; + continue; + } + for (rfp = ResolverFlags; rfp->rf_name != NULL; rfp++) + { + if (strcasecmp(q, rfp->rf_name) == 0) + break; + } + if (rfp->rf_name == NULL) + syserr("readcf: I option value %s unrecognized", q); + else if (clearmode) + _res.options &= ~rfp->rf_bits; + else + _res.options |= rfp->rf_bits; + } + if (tTd(8, 2)) + printf("_res.options = %x, HasWildcardMX = %d\n", + _res.options, HasWildcardMX); +#else + usrerr("name server (I option) specified but BIND not compiled in"); +#endif + break; + + case 'i': /* ignore dot lines in message */ + IgnrDot = atobool(val); + break; + + case 'j': /* send errors in MIME (RFC 1341) format */ + SendMIMEErrors = atobool(val); + break; + + case 'J': /* .forward search path */ + ForwardPath = newstr(val); + break; + + case 'k': /* connection cache size */ + MaxMciCache = atoi(val); + if (MaxMciCache < 0) + MaxMciCache = 0; + break; + + case 'K': /* connection cache timeout */ + MciCacheTimeout = convtime(val, 'm'); + break; + + case 'l': /* use Errors-To: header */ + UseErrorsTo = atobool(val); + break; + + case 'L': /* log level */ + if (safe || LogLevel < atoi(val)) + LogLevel = atoi(val); + break; + + case 'M': /* define macro */ + p = newstr(&val[1]); + if (!safe) + cleanstrcpy(p, p, MAXNAME); + define(val[0], p, CurEnv); + sticky = FALSE; + break; + + case 'm': /* send to me too */ + MeToo = atobool(val); + break; + + case 'n': /* validate RHS in newaliases */ + CheckAliases = atobool(val); + break; + + /* 'N' available -- was "net name" */ + + case 'O': /* daemon options */ +#ifdef DAEMON + setdaemonoptions(val); +#else + syserr("DaemonPortOptions (O option) set but DAEMON not compiled in"); +#endif + break; + + case 'o': /* assume old style headers */ + if (atobool(val)) + CurEnv->e_flags |= EF_OLDSTYLE; + else + CurEnv->e_flags &= ~EF_OLDSTYLE; + break; + + case 'p': /* select privacy level */ + p = val; + for (;;) + { + register struct prival *pv; + extern struct prival PrivacyValues[]; + + while (isascii(*p) && (isspace(*p) || ispunct(*p))) + p++; + if (*p == '\0') + break; + val = p; + while (isascii(*p) && isalnum(*p)) + p++; + if (*p != '\0') + *p++ = '\0'; + + for (pv = PrivacyValues; pv->pv_name != NULL; pv++) + { + if (strcasecmp(val, pv->pv_name) == 0) + break; + } + if (pv->pv_name == NULL) + syserr("readcf: Op line: %s unrecognized", val); + PrivacyFlags |= pv->pv_flag; + } + sticky = FALSE; + break; + + case 'P': /* postmaster copy address for returned mail */ + PostMasterCopy = newstr(val); + break; + + case 'q': /* slope of queue only function */ + QueueFactor = atoi(val); + break; + + case 'Q': /* queue directory */ + if (val[0] == '\0') + QueueDir = "mqueue"; + else + QueueDir = newstr(val); + if (RealUid != 0 && !safe) + Warn_Q_option = TRUE; + break; + + case 'R': /* don't prune routes */ + DontPruneRoutes = atobool(val); + break; + + case 'r': /* read timeout */ + if (subopt == NULL) + inittimeouts(val); + else + settimeout(subopt, val); + break; + + case 'S': /* status file */ + if (val[0] == '\0') + StatFile = "sendmail.st"; + else + StatFile = newstr(val); + break; + + case 's': /* be super safe, even if expensive */ + SuperSafe = atobool(val); + break; + + case 'T': /* queue timeout */ + p = strchr(val, '/'); + if (p != NULL) + { + *p++ = '\0'; + settimeout("queuewarn", p); + } + settimeout("queuereturn", val); + break; + + case 't': /* time zone name */ + TimeZoneSpec = newstr(val); + break; + + case 'U': /* location of user database */ + UdbSpec = newstr(val); + break; + + case 'u': /* set default uid */ + for (p = val; *p != '\0'; p++) + { + if (*p == '.' || *p == '/' || *p == ':') + { + *p++ = '\0'; + break; + } + } + if (isascii(*val) && isdigit(*val)) + DefUid = atoi(val); + else + { + register struct passwd *pw; + + DefUid = -1; + pw = sm_getpwnam(val); + if (pw == NULL) + syserr("readcf: option u: unknown user %s", val); + else + { + DefUid = pw->pw_uid; + DefGid = pw->pw_gid; + } + } + setdefuser(); + + /* handle the group if it is there */ + if (*p == '\0') + break; + val = p; + goto g_opt; + + case 'V': /* fallback MX host */ + FallBackMX = newstr(val); + break; + + case 'v': /* run in verbose mode */ + Verbose = atobool(val); + break; + + case 'w': /* if we are best MX, try host directly */ + TryNullMXList = atobool(val); + break; + + /* 'W' available -- was wizard password */ + + case 'x': /* load avg at which to auto-queue msgs */ + QueueLA = atoi(val); + break; + + case 'X': /* load avg at which to auto-reject connections */ + RefuseLA = atoi(val); + break; + + case 'y': /* work recipient factor */ + WkRecipFact = atoi(val); + break; + + case 'Y': /* fork jobs during queue runs */ + ForkQueueRuns = atobool(val); + break; + + case 'z': /* work message class factor */ + WkClassFact = atoi(val); + break; + + case 'Z': /* work time factor */ + WkTimeFact = atoi(val); + break; + + case O_QUEUESORTORD: /* queue sorting order */ + switch (*val) + { + case 'h': /* Host first */ + case 'H': + QueueSortOrder = QS_BYHOST; + break; + + case 'p': /* Priority order */ + case 'P': + QueueSortOrder = QS_BYPRIORITY; + break; + + default: + syserr("Invalid queue sort order \"%s\"", val); + } + break; + + case O_HOSTSFILE: /* pathname of /etc/hosts file */ + HostsFile = newstr(val); + break; + + case O_MQA: /* minimum queue age between deliveries */ + MinQueueAge = convtime(val, 'm'); + break; + + case O_MHSA: /* maximum age of cached host status */ + MaxHostStatAge = convtime(val, 'm'); + break; + + case O_DEFCHARSET: /* default character set for mimefying */ + DefaultCharSet = newstr(denlstring(val, TRUE, TRUE)); + break; + + case O_SSFILE: /* service switch file */ + ServiceSwitchFile = newstr(val); + break; + + case O_DIALDELAY: /* delay for dial-on-demand operation */ + DialDelay = convtime(val, 's'); + break; + + case O_NORCPTACTION: /* what to do if no recipient */ + if (strcasecmp(val, "none") == 0) + NoRecipientAction = NRA_NO_ACTION; + else if (strcasecmp(val, "add-to") == 0) + NoRecipientAction = NRA_ADD_TO; + else if (strcasecmp(val, "add-apparently-to") == 0) + NoRecipientAction = NRA_ADD_APPARENTLY_TO; + else if (strcasecmp(val, "add-bcc") == 0) + NoRecipientAction = NRA_ADD_BCC; + else if (strcasecmp(val, "add-to-undisclosed") == 0) + NoRecipientAction = NRA_ADD_TO_UNDISCLOSED; + else + syserr("Invalid NoRecipientAction: %s", val); + break; + + case O_SAFEFILEENV: /* chroot() environ for writing to files */ + SafeFileEnv = newstr(val); + break; + + case O_MAXMSGSIZE: /* maximum message size */ + MaxMessageSize = atol(val); + break; + + case O_COLONOKINADDR: /* old style handling of colon addresses */ + ColonOkInAddr = atobool(val); + break; + + case O_MAXQUEUERUN: /* max # of jobs in a single queue run */ + MaxQueueRun = atol(val); + break; + + case O_MAXCHILDREN: /* max # of children of daemon */ + MaxChildren = atoi(val); + break; + + case O_KEEPCNAMES: /* don't expand CNAME records */ + DontExpandCnames = atobool(val); + break; + + case O_MUSTQUOTE: /* must quote these characters in phrases */ + strcpy(buf, "@,;:\\()[]"); + if (strlen(val) < sizeof buf - 10) + strcat(buf, val); + MustQuoteChars = newstr(buf); + break; + + case O_SMTPGREETING: /* SMTP greeting message (old $e macro) */ + SmtpGreeting = newstr(munchstring(val, NULL)); + break; + + case O_UNIXFROM: /* UNIX From_ line (old $l macro) */ + UnixFromLine = newstr(munchstring(val, NULL)); + break; + + case O_OPCHARS: /* operator characters (old $o macro) */ + OperatorChars = newstr(munchstring(val, NULL)); + break; + + case O_DONTINITGRPS: /* don't call initgroups(3) */ + DontInitGroups = atobool(val); + break; + + case O_SLFH: /* make sure from fits on one line */ + SingleLineFromHeader = atobool(val); + break; + + default: + if (tTd(37, 1)) + { + if (isascii(opt) && isprint(opt)) + printf("Warning: option %c unknown\n", opt); + else + printf("Warning: option 0x%x unknown\n", opt); + } + break; + } + if (sticky) + setbitn(opt, StickyOpt); +} +/* +** SETCLASS -- set a string into a class +** +** Parameters: +** class -- the class to put the string in. +** str -- the string to enter +** +** Returns: +** none. +** +** Side Effects: +** puts the word into the symbol table. +*/ + +void +setclass(class, str) + int class; + char *str; +{ + register STAB *s; + + if (tTd(37, 8)) + printf("setclass(%s, %s)\n", macname(class), str); + s = stab(str, ST_CLASS, ST_ENTER); + setbitn(class, s->s_class); +} +/* +** MAKEMAPENTRY -- create a map entry +** +** Parameters: +** line -- the config file line +** +** Returns: +** A pointer to the map that has been created. +** NULL if there was a syntax error. +** +** Side Effects: +** Enters the map into the dictionary. +*/ + +MAP * +makemapentry(line) + char *line; +{ + register char *p; + char *mapname; + char *classname; + register STAB *s; + STAB *class; + + for (p = line; isascii(*p) && isspace(*p); p++) + continue; + if (!(isascii(*p) && isalnum(*p))) + { + syserr("readcf: config K line: no map name"); + return NULL; + } + + mapname = p; + while ((isascii(*++p) && isalnum(*p)) || *p == '_' || *p == '.') + continue; + if (*p != '\0') + *p++ = '\0'; + while (isascii(*p) && isspace(*p)) + p++; + if (!(isascii(*p) && isalnum(*p))) + { + syserr("readcf: config K line, map %s: no map class", mapname); + return NULL; + } + classname = p; + while (isascii(*++p) && isalnum(*p)) + continue; + if (*p != '\0') + *p++ = '\0'; + while (isascii(*p) && isspace(*p)) + p++; + + /* look up the class */ + class = stab(classname, ST_MAPCLASS, ST_FIND); + if (class == NULL) + { + syserr("readcf: map %s: class %s not available", mapname, classname); + return NULL; + } + + /* enter the map */ + s = stab(mapname, ST_MAP, ST_ENTER); + s->s_map.map_class = &class->s_mapclass; + s->s_map.map_mname = newstr(mapname); + + if (class->s_mapclass.map_parse(&s->s_map, p)) + s->s_map.map_mflags |= MF_VALID; + + if (tTd(37, 5)) + { + printf("map %s, class %s, flags %x, file %s,\n", + s->s_map.map_mname, s->s_map.map_class->map_cname, + s->s_map.map_mflags, + s->s_map.map_file == NULL ? "(null)" : s->s_map.map_file); + printf("\tapp %s, domain %s, rebuild %s\n", + s->s_map.map_app == NULL ? "(null)" : s->s_map.map_app, + s->s_map.map_domain == NULL ? "(null)" : s->s_map.map_domain, + s->s_map.map_rebuild == NULL ? "(null)" : s->s_map.map_rebuild); + } + + return &s->s_map; +} +/* +** STRTORWSET -- convert string to rewriting set number +** +** Parameters: +** p -- the pointer to the string to decode. +** endp -- if set, store the trailing delimiter here. +** stabmode -- ST_ENTER to create this entry, ST_FIND if +** it must already exist. +** +** Returns: +** The appropriate ruleset number. +** -1 if it is not valid (error already printed) +*/ + +int +strtorwset(p, endp, stabmode) + char *p; + char **endp; + int stabmode; +{ + int ruleset; + static int nextruleset = MAXRWSETS; + + while (isascii(*p) && isspace(*p)) + p++; + if (!isascii(*p)) + { + syserr("invalid ruleset name: \"%.20s\"", p); + return -1; + } + if (isdigit(*p)) + { + ruleset = strtol(p, endp, 10); + if (ruleset >= MAXRWSETS / 2 || ruleset < 0) + { + syserr("bad ruleset %d (%d max)", + ruleset, MAXRWSETS / 2); + ruleset = -1; + } + } + else + { + STAB *s; + char delim; + char *q; + + q = p; + while (*p != '\0' && isascii(*p) && + (isalnum(*p) || *p == '_')) + p++; + if (q == p || !isalpha(*q)) + { + /* no valid characters */ + syserr("invalid ruleset name: \"%.20s\"", q); + return -1; + } + while (isascii(*p) && isspace(*p)) + *p++ = '\0'; + delim = *p; + if (delim != '\0') + *p = '\0'; + s = stab(q, ST_RULESET, stabmode); + if (delim != '\0') + *p = delim; + + if (s == NULL) + { + syserr("unknown ruleset %s", q); + return -1; + } + + if (stabmode == ST_ENTER && delim == '=') + { + while (isascii(*++p) && isspace(*p)) + continue; + if (!isdigit(*p)) + { + syserr("bad ruleset definition \"%s\" (number required after `=')", q); + ruleset = -1; + } + else + { + ruleset = strtol(p, endp, 10); + if (ruleset >= MAXRWSETS / 2 || ruleset < 0) + { + syserr("bad ruleset number %d in \"%s\" (%d max)", + ruleset, q, MAXRWSETS / 2); + ruleset = -1; + } + } + } + else + { + if (endp != NULL) + *endp = p; + if (s->s_ruleset > 0) + ruleset = s->s_ruleset; + else if ((ruleset = --nextruleset) < MAXRWSETS / 2) + { + syserr("%s: too many named rulesets (%d max)", + q, MAXRWSETS / 2); + ruleset = -1; + } + } + if (s->s_ruleset > 0 && ruleset >= 0 && ruleset != s->s_ruleset) + { + syserr("%s: ruleset changed value (old %d, new %d)", + q, ruleset, s->s_ruleset); + ruleset = s->s_ruleset; + } + else if (ruleset > 0) + { + s->s_ruleset = ruleset; + } + } + return ruleset; +} +/* +** INITTIMEOUTS -- parse and set timeout values +** +** Parameters: +** val -- a pointer to the values. If NULL, do initial +** settings. +** +** Returns: +** none. +** +** Side Effects: +** Initializes the TimeOuts structure +*/ + +#define SECONDS +#define MINUTES * 60 +#define HOUR * 3600 + +void +inittimeouts(val) + register char *val; +{ + register char *p; + extern time_t convtime(); + + if (val == NULL) + { + TimeOuts.to_connect = (time_t) 0 SECONDS; + TimeOuts.to_initial = (time_t) 5 MINUTES; + TimeOuts.to_helo = (time_t) 5 MINUTES; + TimeOuts.to_mail = (time_t) 10 MINUTES; + TimeOuts.to_rcpt = (time_t) 1 HOUR; + TimeOuts.to_datainit = (time_t) 5 MINUTES; + TimeOuts.to_datablock = (time_t) 1 HOUR; + TimeOuts.to_datafinal = (time_t) 1 HOUR; + TimeOuts.to_rset = (time_t) 5 MINUTES; + TimeOuts.to_quit = (time_t) 2 MINUTES; + TimeOuts.to_nextcommand = (time_t) 1 HOUR; + TimeOuts.to_miscshort = (time_t) 2 MINUTES; +#if IDENTPROTO + TimeOuts.to_ident = (time_t) 30 SECONDS; +#else + TimeOuts.to_ident = (time_t) 0 SECONDS; +#endif + TimeOuts.to_fileopen = (time_t) 60 SECONDS; + return; + } + + for (;; val = p) + { + while (isascii(*val) && isspace(*val)) + val++; + if (*val == '\0') + break; + for (p = val; *p != '\0' && *p != ','; p++) + continue; + if (*p != '\0') + *p++ = '\0'; + + if (isascii(*val) && isdigit(*val)) + { + /* old syntax -- set everything */ + TimeOuts.to_mail = convtime(val, 'm'); + TimeOuts.to_rcpt = TimeOuts.to_mail; + TimeOuts.to_datainit = TimeOuts.to_mail; + TimeOuts.to_datablock = TimeOuts.to_mail; + TimeOuts.to_datafinal = TimeOuts.to_mail; + TimeOuts.to_nextcommand = TimeOuts.to_mail; + continue; + } + else + { + register char *q = strchr(val, ':'); + + if (q == NULL && (q = strchr(val, '=')) == NULL) + { + /* syntax error */ + continue; + } + *q++ = '\0'; + settimeout(val, q); + } + } +} +/* +** SETTIMEOUT -- set an individual timeout +** +** Parameters: +** name -- the name of the timeout. +** val -- the value of the timeout. +** +** Returns: +** none. +*/ + +void +settimeout(name, val) + char *name; + char *val; +{ + register char *p; + time_t to; + extern time_t convtime(); + + to = convtime(val, 'm'); + p = strchr(name, '.'); + if (p != NULL) + *p++ = '\0'; + + if (strcasecmp(name, "initial") == 0) + TimeOuts.to_initial = to; + else if (strcasecmp(name, "mail") == 0) + TimeOuts.to_mail = to; + else if (strcasecmp(name, "rcpt") == 0) + TimeOuts.to_rcpt = to; + else if (strcasecmp(name, "datainit") == 0) + TimeOuts.to_datainit = to; + else if (strcasecmp(name, "datablock") == 0) + TimeOuts.to_datablock = to; + else if (strcasecmp(name, "datafinal") == 0) + TimeOuts.to_datafinal = to; + else if (strcasecmp(name, "command") == 0) + TimeOuts.to_nextcommand = to; + else if (strcasecmp(name, "rset") == 0) + TimeOuts.to_rset = to; + else if (strcasecmp(name, "helo") == 0) + TimeOuts.to_helo = to; + else if (strcasecmp(name, "quit") == 0) + TimeOuts.to_quit = to; + else if (strcasecmp(name, "misc") == 0) + TimeOuts.to_miscshort = to; + else if (strcasecmp(name, "ident") == 0) + TimeOuts.to_ident = to; + else if (strcasecmp(name, "fileopen") == 0) + TimeOuts.to_fileopen = to; + else if (strcasecmp(name, "connect") == 0) + TimeOuts.to_connect = to; + else if (strcasecmp(name, "queuewarn") == 0) + { + to = convtime(val, 'h'); + if (p == NULL || strcmp(p, "*") == 0) + { + TimeOuts.to_q_warning[TOC_NORMAL] = to; + TimeOuts.to_q_warning[TOC_URGENT] = to; + TimeOuts.to_q_warning[TOC_NONURGENT] = to; + } + else if (strcasecmp(p, "normal") == 0) + TimeOuts.to_q_warning[TOC_NORMAL] = to; + else if (strcasecmp(p, "urgent") == 0) + TimeOuts.to_q_warning[TOC_URGENT] = to; + else if (strcasecmp(p, "non-urgent") == 0) + TimeOuts.to_q_warning[TOC_NONURGENT] = to; + else + syserr("settimeout: invalid queuewarn subtimeout %s", p); + } + else if (strcasecmp(name, "queuereturn") == 0) + { + to = convtime(val, 'd'); + if (p == NULL || strcmp(p, "*") == 0) + { + TimeOuts.to_q_return[TOC_NORMAL] = to; + TimeOuts.to_q_return[TOC_URGENT] = to; + TimeOuts.to_q_return[TOC_NONURGENT] = to; + } + else if (strcasecmp(p, "normal") == 0) + TimeOuts.to_q_return[TOC_NORMAL] = to; + else if (strcasecmp(p, "urgent") == 0) + TimeOuts.to_q_return[TOC_URGENT] = to; + else if (strcasecmp(p, "non-urgent") == 0) + TimeOuts.to_q_return[TOC_NONURGENT] = to; + else + syserr("settimeout: invalid queuereturn subtimeout %s", p); + } + else + syserr("settimeout: invalid timeout %s", name); +} diff --git a/usr.sbin/sendmail/src/recipient.c b/usr.sbin/sendmail/src/recipient.c new file mode 100644 index 000000000000..79126e9ccc5d --- /dev/null +++ b/usr.sbin/sendmail/src/recipient.c @@ -0,0 +1,1349 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)recipient.c 8.108 (Berkeley) 10/30/95"; +#endif /* not lint */ + +# include "sendmail.h" + +/* +** SENDTOLIST -- Designate a send list. +** +** The parameter is a comma-separated list of people to send to. +** This routine arranges to send to all of them. +** +** Parameters: +** list -- the send list. +** ctladdr -- the address template for the person to +** send to -- effective uid/gid are important. +** This is typically the alias that caused this +** expansion. +** sendq -- a pointer to the head of a queue to put +** these people into. +** aliaslevel -- the current alias nesting depth -- to +** diagnose loops. +** e -- the envelope in which to add these recipients. +** +** Returns: +** The number of addresses actually on the list. +** +** Side Effects: +** none. +*/ + +/* q_flags bits inherited from ctladdr */ +#define QINHERITEDBITS (QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY|QHASNOTIFY) + +int +sendtolist(list, ctladdr, sendq, aliaslevel, e) + char *list; + ADDRESS *ctladdr; + ADDRESS **sendq; + int aliaslevel; + register ENVELOPE *e; +{ + register char *p; + register ADDRESS *al; /* list of addresses to send to */ + bool firstone; /* set on first address sent */ + char delimiter; /* the address delimiter */ + int naddrs; + int i; + char *oldto = e->e_to; + char *bufp; + char buf[MAXNAME + 1]; + + if (list == NULL) + { + syserr("sendtolist: null list"); + return 0; + } + + if (tTd(25, 1)) + { + printf("sendto: %s\n ctladdr=", list); + printaddr(ctladdr, FALSE); + } + + /* heuristic to determine old versus new style addresses */ + if (ctladdr == NULL && + (strchr(list, ',') != NULL || strchr(list, ';') != NULL || + strchr(list, '<') != NULL || strchr(list, '(') != NULL)) + e->e_flags &= ~EF_OLDSTYLE; + delimiter = ' '; + if (!bitset(EF_OLDSTYLE, e->e_flags) || ctladdr != NULL) + delimiter = ','; + + firstone = TRUE; + al = NULL; + naddrs = 0; + + /* make sure we have enough space to copy the string */ + i = strlen(list) + 1; + if (i <= sizeof buf) + bufp = buf; + else + bufp = xalloc(i); + strcpy(bufp, denlstring(list, FALSE, TRUE)); + + for (p = bufp; *p != '\0'; ) + { + auto char *delimptr; + register ADDRESS *a; + + /* parse the address */ + while ((isascii(*p) && isspace(*p)) || *p == ',') + p++; + a = parseaddr(p, NULLADDR, RF_COPYALL, delimiter, &delimptr, e); + p = delimptr; + if (a == NULL) + continue; + a->q_next = al; + a->q_alias = ctladdr; + + /* arrange to inherit attributes from parent */ + if (ctladdr != NULL) + { + ADDRESS *b; + extern ADDRESS *self_reference(); + + /* self reference test */ + if (sameaddr(ctladdr, a)) + { + if (tTd(27, 5)) + { + printf("sendtolist: QSELFREF "); + printaddr(ctladdr, FALSE); + } + ctladdr->q_flags |= QSELFREF; + } + + /* check for address loops */ + b = self_reference(a, e); + if (b != NULL) + { + b->q_flags |= QSELFREF; + if (tTd(27, 5)) + { + printf("sendtolist: QSELFREF "); + printaddr(b, FALSE); + } + if (a != b) + { + if (tTd(27, 5)) + { + printf("sendtolist: QDONTSEND "); + printaddr(a, FALSE); + } + a->q_flags |= QDONTSEND; + b->q_flags |= a->q_flags & QNOTREMOTE; + continue; + } + } + + /* full name */ + if (a->q_fullname == NULL) + a->q_fullname = ctladdr->q_fullname; + + /* various flag bits */ + a->q_flags &= ~QINHERITEDBITS; + a->q_flags |= ctladdr->q_flags & QINHERITEDBITS; + + /* original recipient information */ + a->q_orcpt = ctladdr->q_orcpt; + } + + al = a; + firstone = FALSE; + } + + /* arrange to send to everyone on the local send list */ + while (al != NULL) + { + register ADDRESS *a = al; + + al = a->q_next; + a = recipient(a, sendq, aliaslevel, e); + naddrs++; + } + + e->e_to = oldto; + if (bufp != buf) + free(bufp); + return (naddrs); +} +/* +** RECIPIENT -- Designate a message recipient +** +** Saves the named person for future mailing. +** +** Parameters: +** a -- the (preparsed) address header for the recipient. +** sendq -- a pointer to the head of a queue to put the +** recipient in. Duplicate supression is done +** in this queue. +** aliaslevel -- the current alias nesting depth. +** e -- the current envelope. +** +** Returns: +** The actual address in the queue. This will be "a" if +** the address is not a duplicate, else the original address. +** +** Side Effects: +** none. +*/ + +ADDRESS * +recipient(a, sendq, aliaslevel, e) + register ADDRESS *a; + register ADDRESS **sendq; + int aliaslevel; + register ENVELOPE *e; +{ + register ADDRESS *q; + ADDRESS **pq; + register struct mailer *m; + register char *p; + bool quoted = FALSE; /* set if the addr has a quote bit */ + int findusercount = 0; + bool initialdontsend = bitset(QDONTSEND, a->q_flags); + int i; + char *buf; + char buf0[MAXNAME + 1]; /* unquoted image of the user name */ + extern int safefile(); + + e->e_to = a->q_paddr; + m = a->q_mailer; + errno = 0; + if (aliaslevel == 0) + a->q_flags |= QPRIMARY; + if (tTd(26, 1)) + { + printf("\nrecipient (%d): ", aliaslevel); + printaddr(a, FALSE); + } + + /* if this is primary, add it to the original recipient list */ + if (a->q_alias == NULL) + { + if (e->e_origrcpt == NULL) + e->e_origrcpt = a->q_paddr; + else if (e->e_origrcpt != a->q_paddr) + e->e_origrcpt = ""; + } + + /* break aliasing loops */ + if (aliaslevel > MaxAliasRecursion) + { + a->q_status = "5.4.6"; + usrerr("554 aliasing/forwarding loop broken (%d aliases deep; %d max", + aliaslevel, MaxAliasRecursion); + return (a); + } + + /* + ** Finish setting up address structure. + */ + + /* get unquoted user for file, program or user.name check */ + i = strlen(a->q_user); + if (i >= sizeof buf0) + buf = xalloc(i + 1); + else + buf = buf0; + (void) strcpy(buf, a->q_user); + for (p = buf; *p != '\0' && !quoted; p++) + { + if (*p == '\\') + quoted = TRUE; + } + stripquotes(buf); + + /* check for direct mailing to restricted mailers */ + if (m == ProgMailer) + { + if (a->q_alias == NULL) + { + a->q_flags |= QBADADDR; + a->q_status = "5.7.1"; + usrerr("550 Cannot mail directly to programs"); + } + else if (bitset(QBOGUSSHELL, a->q_alias->q_flags)) + { + a->q_flags |= QBADADDR; + a->q_status = "5.7.1"; + usrerr("550 User %s@%s doesn't have a valid shell for mailing to programs", + a->q_alias->q_ruser, MyHostName); + } + else if (bitset(QUNSAFEADDR, a->q_alias->q_flags)) + { + a->q_flags |= QBADADDR; + a->q_status = "5.7.1"; + usrerr("550 Address %s is unsafe for mailing to programs", + a->q_alias->q_paddr); + } + } + + /* + ** Look up this person in the recipient list. + ** If they are there already, return, otherwise continue. + ** If the list is empty, just add it. Notice the cute + ** hack to make from addresses suppress things correctly: + ** the QDONTSEND bit will be set in the send list. + ** [Please note: the emphasis is on "hack."] + */ + + for (pq = sendq; (q = *pq) != NULL; pq = &q->q_next) + { + if (sameaddr(q, a)) + { + if (tTd(26, 1)) + { + printf("%s in sendq: ", a->q_paddr); + printaddr(q, FALSE); + } + if (!bitset(QPRIMARY, q->q_flags)) + { + if (!bitset(QDONTSEND, a->q_flags)) + message("duplicate suppressed"); + q->q_flags |= a->q_flags; + } + else if (bitset(QSELFREF, q->q_flags)) + q->q_flags |= a->q_flags & ~QDONTSEND; + a = q; + goto done; + } + } + + /* add address on list */ + *pq = a; + a->q_next = NULL; + + /* + ** Alias the name and handle special mailer types. + */ + + trylocaluser: + if (tTd(29, 7)) + printf("at trylocaluser %s\n", a->q_user); + + if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags)) + goto testselfdestruct; + + if (m == InclMailer) + { + a->q_flags |= QDONTSEND; + if (a->q_alias == NULL) + { + a->q_flags |= QBADADDR; + a->q_status = "5.7.1"; + usrerr("550 Cannot mail directly to :include:s"); + } + else + { + int ret; + + message("including file %s", a->q_user); + ret = include(a->q_user, FALSE, a, sendq, aliaslevel, e); + if (transienterror(ret)) + { +#ifdef LOG + if (LogLevel > 2) + syslog(LOG_ERR, "%s: include %s: transient error: %s", + e->e_id == NULL ? "NOQUEUE" : e->e_id, + shortenstring(a->q_user, 203), + errstring(ret)); +#endif + a->q_flags |= QQUEUEUP; + a->q_flags &= ~QDONTSEND; + usrerr("451 Cannot open %s: %s", + shortenstring(a->q_user, 203), + errstring(ret)); + } + else if (ret != 0) + { + a->q_flags |= QBADADDR; + a->q_status = "5.2.4"; + usrerr("550 Cannot open %s: %s", + shortenstring(a->q_user, 203), + errstring(ret)); + } + } + } + else if (m == FileMailer) + { + extern bool writable(); + + /* check if writable or creatable */ + if (a->q_alias == NULL) + { + a->q_flags |= QBADADDR; + a->q_status = "5.7.1"; + usrerr("550 Cannot mail directly to files"); + } + else if (bitset(QBOGUSSHELL, a->q_alias->q_flags)) + { + a->q_flags |= QBADADDR; + a->q_status = "5.7.1"; + usrerr("550 User %s@%s doesn't have a valid shell for mailing to files", + a->q_alias->q_ruser, MyHostName); + } + else if (bitset(QUNSAFEADDR, a->q_alias->q_flags)) + { + a->q_flags |= QBADADDR; + a->q_status = "5.7.1"; + usrerr("550 Address %s is unsafe for mailing to files", + a->q_alias->q_paddr); + } + else if (!writable(buf, a->q_alias, SFF_CREAT)) + { + a->q_flags |= QBADADDR; + giveresponse(EX_CANTCREAT, m, NULL, a->q_alias, + (time_t) 0, e); + } + } + + /* try aliasing */ + if (!quoted && !bitset(QDONTSEND, a->q_flags) && + bitnset(M_ALIASABLE, m->m_flags)) + alias(a, sendq, aliaslevel, e); + +# if USERDB + /* if not aliased, look it up in the user database */ + if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags) && + bitnset(M_CHECKUDB, m->m_flags)) + { + extern int udbexpand(); + + if (udbexpand(a, sendq, aliaslevel, e) == EX_TEMPFAIL) + { + a->q_flags |= QQUEUEUP; + if (e->e_message == NULL) + e->e_message = newstr("Deferred: user database error"); +# ifdef LOG + if (LogLevel > 8) + syslog(LOG_INFO, "%s: deferred: udbexpand: %s", + e->e_id == NULL ? "NOQUEUE" : e->e_id, + errstring(errno)); +# endif + message("queued (user database error): %s", + errstring(errno)); + e->e_nrcpts++; + goto testselfdestruct; + } + } +# endif + + /* + ** If we have a level two config file, then pass the name through + ** Ruleset 5 before sending it off. Ruleset 5 has the right + ** to send rewrite it to another mailer. This gives us a hook + ** after local aliasing has been done. + */ + + if (tTd(29, 5)) + { + printf("recipient: testing local? cl=%d, rr5=%x\n\t", + ConfigLevel, RewriteRules[5]); + printaddr(a, FALSE); + } + if (!bitset(QNOTREMOTE|QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) && + ConfigLevel >= 2 && RewriteRules[5] != NULL && + bitnset(M_TRYRULESET5, m->m_flags)) + { + maplocaluser(a, sendq, aliaslevel + 1, e); + } + + /* + ** If it didn't get rewritten to another mailer, go ahead + ** and deliver it. + */ + + if (!bitset(QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) && + bitnset(M_HASPWENT, m->m_flags)) + { + auto bool fuzzy; + register struct passwd *pw; + extern struct passwd *finduser(); + + /* warning -- finduser may trash buf */ + pw = finduser(buf, &fuzzy); + if (pw == NULL) + { + a->q_flags |= QBADADDR; + a->q_status = "5.1.1"; + giveresponse(EX_NOUSER, m, NULL, a->q_alias, + (time_t) 0, e); + } + else + { + char nbuf[MAXNAME + 1]; + + if (fuzzy) + { + /* name was a fuzzy match */ + a->q_user = newstr(pw->pw_name); + if (findusercount++ > 3) + { + a->q_flags |= QBADADDR; + a->q_status = "5.4.6"; + usrerr("554 aliasing/forwarding loop for %s broken", + pw->pw_name); + goto done; + } + + /* see if it aliases */ + (void) strcpy(buf, pw->pw_name); + goto trylocaluser; + } + if (strcmp(pw->pw_dir, "/") == 0) + a->q_home = ""; + else + a->q_home = newstr(pw->pw_dir); + a->q_uid = pw->pw_uid; + a->q_gid = pw->pw_gid; + a->q_ruser = newstr(pw->pw_name); + a->q_flags |= QGOODUID; + buildfname(pw->pw_gecos, pw->pw_name, nbuf); + if (nbuf[0] != '\0') + a->q_fullname = newstr(nbuf); + if (!usershellok(pw->pw_name, pw->pw_shell)) + { + a->q_flags |= QBOGUSSHELL; + } + if (bitset(EF_VRFYONLY, e->e_flags)) + { + /* don't do any more now */ + a->q_flags |= QVERIFIED; + } + else if (!quoted) + forward(a, sendq, aliaslevel, e); + } + } + if (!bitset(QDONTSEND, a->q_flags)) + e->e_nrcpts++; + + testselfdestruct: + a->q_flags |= QTHISPASS; + if (tTd(26, 8)) + { + printf("testselfdestruct: "); + printaddr(a, FALSE); + if (tTd(26, 10)) + { + printf("SENDQ:\n"); + printaddr(*sendq, TRUE); + printf("----\n"); + } + } + if (a->q_alias == NULL && a != &e->e_from && + bitset(QDONTSEND, a->q_flags)) + { + for (q = *sendq; q != NULL; q = q->q_next) + { + if (!bitset(QDONTSEND, q->q_flags)) + break; + } + if (q == NULL) + { + a->q_flags |= QBADADDR; + a->q_status = "5.4.6"; + usrerr("554 aliasing/forwarding loop broken"); + } + } + + done: + a->q_flags |= QTHISPASS; + if (buf != buf0) + free(buf); + + /* + ** If we are at the top level, check to see if this has + ** expanded to exactly one address. If so, it can inherit + ** the primaryness of the address. + ** + ** While we're at it, clear the QTHISPASS bits. + */ + + if (aliaslevel == 0) + { + int nrcpts = 0; + ADDRESS *only; + + for (q = *sendq; q != NULL; q = q->q_next) + { + if (bitset(QTHISPASS, q->q_flags) && + !bitset(QDONTSEND|QBADADDR, q->q_flags)) + { + nrcpts++; + only = q; + } + q->q_flags &= ~QTHISPASS; + } + if (nrcpts == 1) + { + /* check to see if this actually got a new owner */ + q = only; + while ((q = q->q_alias) != NULL) + { + if (q->q_owner != NULL) + break; + } + if (q == NULL) + only->q_flags |= QPRIMARY; + } + else if (!initialdontsend && nrcpts > 0) + { + /* arrange for return receipt */ + e->e_flags |= EF_SENDRECEIPT; + a->q_flags |= QEXPANDED; + if (e->e_xfp != NULL && bitset(QPINGONSUCCESS, a->q_flags)) + fprintf(e->e_xfp, + "%s... expanded to multiple addresses\n", + a->q_paddr); + } + } + + return (a); +} +/* +** FINDUSER -- find the password entry for a user. +** +** This looks a lot like getpwnam, except that it may want to +** do some fancier pattern matching in /etc/passwd. +** +** This routine contains most of the time of many sendmail runs. +** It deserves to be optimized. +** +** Parameters: +** name -- the name to match against. +** fuzzyp -- an outarg that is set to TRUE if this entry +** was found using the fuzzy matching algorithm; +** set to FALSE otherwise. +** +** Returns: +** A pointer to a pw struct. +** NULL if name is unknown or ambiguous. +** +** Side Effects: +** may modify name. +*/ + +struct passwd * +finduser(name, fuzzyp) + char *name; + bool *fuzzyp; +{ + register struct passwd *pw; + register char *p; + bool tryagain; + + if (tTd(29, 4)) + printf("finduser(%s): ", name); + + *fuzzyp = FALSE; + +#ifdef HESIOD + /* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */ + for (p = name; *p != '\0'; p++) + if (!isascii(*p) || !isdigit(*p)) + break; + if (*p == '\0') + { + if (tTd(29, 4)) + printf("failed (numeric input)\n"); + return NULL; + } +#endif + + /* look up this login name using fast path */ + if ((pw = sm_getpwnam(name)) != NULL) + { + if (tTd(29, 4)) + printf("found (non-fuzzy)\n"); + return (pw); + } + + /* try mapping it to lower case */ + tryagain = FALSE; + for (p = name; *p != '\0'; p++) + { + if (isascii(*p) && isupper(*p)) + { + *p = tolower(*p); + tryagain = TRUE; + } + } + if (tryagain && (pw = sm_getpwnam(name)) != NULL) + { + if (tTd(29, 4)) + printf("found (lower case)\n"); + *fuzzyp = TRUE; + return pw; + } + +#if MATCHGECOS + /* see if fuzzy matching allowed */ + if (!MatchGecos) + { + if (tTd(29, 4)) + printf("not found (fuzzy disabled)\n"); + return NULL; + } + + /* search for a matching full name instead */ + for (p = name; *p != '\0'; p++) + { + if (*p == (SpaceSub & 0177) || *p == '_') + *p = ' '; + } + (void) setpwent(); + while ((pw = getpwent()) != NULL) + { + char buf[MAXNAME + 1]; + +# if 0 + if (strcasecmp(pw->pw_name, name) == 0) + { + if (tTd(29, 4)) + printf("found (case wrapped)\n"); + *fuzzyp = TRUE; + return pw; + } +# endif + + buildfname(pw->pw_gecos, pw->pw_name, buf); + if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name)) + { + if (tTd(29, 4)) + printf("fuzzy matches %s\n", pw->pw_name); + message("sending to login name %s", pw->pw_name); + *fuzzyp = TRUE; + return (pw); + } + } + if (tTd(29, 4)) + printf("no fuzzy match found\n"); +#else + if (tTd(29, 4)) + printf("not found (fuzzy disabled)\n"); +#endif + return (NULL); +} +/* +** WRITABLE -- predicate returning if the file is writable. +** +** This routine must duplicate the algorithm in sys/fio.c. +** Unfortunately, we cannot use the access call since we +** won't necessarily be the real uid when we try to +** actually open the file. +** +** Notice that ANY file with ANY execute bit is automatically +** not writable. This is also enforced by mailfile. +** +** Parameters: +** filename -- the file name to check. +** ctladdr -- the controlling address for this file. +** flags -- SFF_* flags to control the function. +** +** Returns: +** TRUE -- if we will be able to write this file. +** FALSE -- if we cannot write this file. +** +** Side Effects: +** none. +*/ + +bool +writable(filename, ctladdr, flags) + char *filename; + ADDRESS *ctladdr; + int flags; +{ + uid_t euid; + gid_t egid; + char *uname; + + if (tTd(44, 5)) + printf("writable(%s, 0x%x)\n", filename, flags); + + /* + ** File does exist -- check that it is writable. + */ + + if (ctladdr != NULL && geteuid() == 0) + { + euid = ctladdr->q_uid; + egid = ctladdr->q_gid; + uname = ctladdr->q_user; + } + else if (bitset(SFF_RUNASREALUID, flags)) + { + euid = RealUid; + egid = RealGid; + uname = RealUserName; + } + else if (FileMailer != NULL && !bitset(SFF_ROOTOK, flags)) + { + euid = FileMailer->m_uid; + egid = FileMailer->m_gid; + uname = NULL; + } + else + { + euid = egid = 0; + uname = NULL; + } + if (!bitset(SFF_ROOTOK, flags)) + { + if (euid == 0) + { + euid = DefUid; + uname = DefUser; + } + if (egid == 0) + egid = DefGid; + } + if (geteuid() == 0 && + (ctladdr == NULL || !bitset(QGOODUID, ctladdr->q_flags))) + flags |= SFF_SETUIDOK; + + errno = safefile(filename, euid, egid, uname, flags, S_IWRITE, NULL); + return errno == 0; +} +/* +** INCLUDE -- handle :include: specification. +** +** Parameters: +** fname -- filename to include. +** forwarding -- if TRUE, we are reading a .forward file. +** if FALSE, it's a :include: file. +** ctladdr -- address template to use to fill in these +** addresses -- effective user/group id are +** the important things. +** sendq -- a pointer to the head of the send queue +** to put these addresses in. +** aliaslevel -- the alias nesting depth. +** e -- the current envelope. +** +** Returns: +** open error status +** +** Side Effects: +** reads the :include: file and sends to everyone +** listed in that file. +** +** Security Note: +** If you have restricted chown (that is, you can't +** give a file away), it is reasonable to allow programs +** and files called from this :include: file to be to be +** run as the owner of the :include: file. This is bogus +** if there is any chance of someone giving away a file. +** We assume that pre-POSIX systems can give away files. +** +** There is an additional restriction that if you +** forward to a :include: file, it will not take on +** the ownership of the :include: file. This may not +** be necessary, but shouldn't hurt. +*/ + +static jmp_buf CtxIncludeTimeout; +static void includetimeout(); + +int +include(fname, forwarding, ctladdr, sendq, aliaslevel, e) + char *fname; + bool forwarding; + ADDRESS *ctladdr; + ADDRESS **sendq; + int aliaslevel; + ENVELOPE *e; +{ + FILE *volatile fp = NULL; + char *oldto = e->e_to; + char *oldfilename = FileName; + int oldlinenumber = LineNumber; + register EVENT *ev = NULL; + int nincludes; + register ADDRESS *ca; + volatile uid_t saveduid, uid; + volatile gid_t savedgid, gid; + char *volatile uname; + int rval = 0; + int sfflags = SFF_REGONLY; + struct stat st; + char buf[MAXLINE]; +#ifdef _POSIX_CHOWN_RESTRICTED +# if _POSIX_CHOWN_RESTRICTED == -1 +# define safechown FALSE +# else +# define safechown TRUE +# endif +#else +# ifdef _PC_CHOWN_RESTRICTED + bool safechown; +# else +# ifdef BSD +# define safechown TRUE +# else +# define safechown FALSE +# endif +# endif +#endif + extern bool chownsafe(); + + if (tTd(27, 2)) + printf("include(%s)\n", fname); + if (tTd(27, 4)) + printf(" ruid=%d euid=%d\n", getuid(), geteuid()); + if (tTd(27, 14)) + { + printf("ctladdr "); + printaddr(ctladdr, FALSE); + } + + if (tTd(27, 9)) + printf("include: old uid = %d/%d\n", getuid(), geteuid()); + + if (forwarding) + sfflags |= SFF_MUSTOWN|SFF_ROOTOK|SFF_NOSLINK; + + ca = getctladdr(ctladdr); + if (ca == NULL) + { + uid = DefUid; + gid = DefGid; + uname = DefUser; + } + else + { + uid = ca->q_uid; + gid = ca->q_gid; + uname = ca->q_user; + } +#if HASSETREUID || USESETEUID + saveduid = geteuid(); + savedgid = getegid(); + if (saveduid == 0) + { + if (!DontInitGroups) + initgroups(uname, gid); + if (gid != 0) + (void) setgid(gid); + if (uid != 0) + { +# if USESETEUID + if (seteuid(uid) < 0) + syserr("seteuid(%d) failure (real=%d, eff=%d)", + uid, getuid(), geteuid()); +# else + if (setreuid(0, uid) < 0) + syserr("setreuid(0, %d) failure (real=%d, eff=%d)", + uid, getuid(), geteuid()); +# endif + else + sfflags |= SFF_NOPATHCHECK; + } + } +#endif + + if (tTd(27, 9)) + printf("include: new uid = %d/%d\n", getuid(), geteuid()); + + /* + ** If home directory is remote mounted but server is down, + ** this can hang or give errors; use a timeout to avoid this + */ + + if (setjmp(CtxIncludeTimeout) != 0) + { + ctladdr->q_flags |= QQUEUEUP; + errno = 0; + + /* return pseudo-error code */ + rval = EOPENTIMEOUT; + goto resetuid; + } + if (TimeOuts.to_fileopen > 0) + ev = setevent(TimeOuts.to_fileopen, includetimeout, 0); + else + ev = NULL; + + /* the input file must be marked safe */ + rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, NULL); + if (rval != 0) + { + /* don't use this :include: file */ + if (tTd(27, 4)) + printf("include: not safe (uid=%d): %s\n", + uid, errstring(rval)); + } + else + { + fp = fopen(fname, "r"); + if (fp == NULL) + { + rval = errno; + if (tTd(27, 4)) + printf("include: open: %s\n", errstring(rval)); + } + } + if (ev != NULL) + clrevent(ev); + +resetuid: + +#if HASSETREUID || USESETEUID + if (saveduid == 0) + { + if (uid != 0) + { +# if USESETEUID + if (seteuid(0) < 0) + syserr("seteuid(0) failure (real=%d, eff=%d)", + getuid(), geteuid()); +# else + if (setreuid(-1, 0) < 0) + syserr("setreuid(-1, 0) failure (real=%d, eff=%d)", + getuid(), geteuid()); + if (setreuid(RealUid, 0) < 0) + syserr("setreuid(%d, 0) failure (real=%d, eff=%d)", + RealUid, getuid(), geteuid()); +# endif + } + setgid(savedgid); + } +#endif + + if (tTd(27, 9)) + printf("include: reset uid = %d/%d\n", getuid(), geteuid()); + + if (rval == EOPENTIMEOUT) + usrerr("451 open timeout on %s", fname); + + if (fp == NULL) + return rval; + + if (fstat(fileno(fp), &st) < 0) + { + rval = errno; + syserr("Cannot fstat %s!", fname); + return rval; + } + +#ifndef safechown + safechown = chownsafe(fileno(fp)); +#endif + if (ca == NULL && safechown) + { + ctladdr->q_uid = st.st_uid; + ctladdr->q_gid = st.st_gid; + ctladdr->q_flags |= QGOODUID; + } + if (ca != NULL && ca->q_uid == st.st_uid) + { + /* optimization -- avoid getpwuid if we already have info */ + ctladdr->q_flags |= ca->q_flags & QBOGUSSHELL; + ctladdr->q_ruser = ca->q_ruser; + } + else + { + register struct passwd *pw; + + pw = sm_getpwuid(st.st_uid); + if (pw == NULL) + ctladdr->q_flags |= QBOGUSSHELL; + else + { + char *sh; + + ctladdr->q_ruser = newstr(pw->pw_name); + if (safechown) + sh = pw->pw_shell; + else + sh = "/SENDMAIL/ANY/SHELL/"; + if (!usershellok(pw->pw_name, sh)) + { +#ifdef LOG + if (LogLevel >= 12) + syslog(LOG_INFO, "%s: user %s has bad shell %s, marked %s", + shortenstring(fname, 203), + pw->pw_name, sh, + safechown ? "bogus" : "unsafe"); +#endif + if (safechown) + ctladdr->q_flags |= QBOGUSSHELL; + else + ctladdr->q_flags |= QUNSAFEADDR; + } + } + } + + if (bitset(EF_VRFYONLY, e->e_flags)) + { + /* don't do any more now */ + ctladdr->q_flags |= QVERIFIED; + e->e_nrcpts++; + xfclose(fp, "include", fname); + return rval; + } + + /* + ** Check to see if some bad guy can write this file + ** + ** This should really do something clever with group + ** permissions; currently we just view world writable + ** as unsafe. Also, we don't check for writable + ** directories in the path. We've got to leave + ** something for the local sysad to do. + */ + + if (bitset(S_IWOTH, st.st_mode)) + { +#ifdef LOG + if (LogLevel >= 12) + syslog(LOG_INFO, "%s: world writable %s file, marked unsafe", + shortenstring(fname, 203), + forwarding ? "forward" : ":include:"); +#endif + ctladdr->q_flags |= QUNSAFEADDR; + } + + /* read the file -- each line is a comma-separated list. */ + FileName = fname; + LineNumber = 0; + ctladdr->q_flags &= ~QSELFREF; + nincludes = 0; + while (fgets(buf, sizeof buf, fp) != NULL) + { + register char *p = strchr(buf, '\n'); + + LineNumber++; + if (p != NULL) + *p = '\0'; + if (buf[0] == '#' || buf[0] == '\0') + continue; + + /* <sp>#@# introduces a comment anywhere */ + /* for Japanese character sets */ + for (p = buf; (p = strchr(++p, '#')) != NULL; ) + { + if (p[1] == '@' && p[2] == '#' && + isascii(p[-1]) && isspace(p[-1]) && + (p[3] == '\0' || (isascii(p[3]) && isspace(p[3])))) + { + p[-1] = '\0'; + break; + } + } + if (buf[0] == '\0') + continue; + + e->e_to = NULL; + message("%s to %s", + forwarding ? "forwarding" : "sending", buf); +#ifdef LOG + if (forwarding && LogLevel > 9) + syslog(LOG_INFO, "%s: forward %.200s => %s", + e->e_id == NULL ? "NOQUEUE" : e->e_id, + oldto, shortenstring(buf, 203)); +#endif + + nincludes += sendtolist(buf, ctladdr, sendq, aliaslevel + 1, e); + } + + if (ferror(fp) && tTd(27, 3)) + printf("include: read error: %s\n", errstring(errno)); + if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags)) + { + if (tTd(27, 5)) + { + printf("include: QDONTSEND "); + printaddr(ctladdr, FALSE); + } + ctladdr->q_flags |= QDONTSEND; + } + + (void) xfclose(fp, "include", fname); + FileName = oldfilename; + LineNumber = oldlinenumber; + e->e_to = oldto; + return rval; +} + +static void +includetimeout() +{ + longjmp(CtxIncludeTimeout, 1); +} +/* +** SENDTOARGV -- send to an argument vector. +** +** Parameters: +** argv -- argument vector to send to. +** e -- the current envelope. +** +** Returns: +** none. +** +** Side Effects: +** puts all addresses on the argument vector onto the +** send queue. +*/ + +void +sendtoargv(argv, e) + register char **argv; + register ENVELOPE *e; +{ + register char *p; + + while ((p = *argv++) != NULL) + { + (void) sendtolist(p, NULLADDR, &e->e_sendqueue, 0, e); + } +} +/* +** GETCTLADDR -- get controlling address from an address header. +** +** If none, get one corresponding to the effective userid. +** +** Parameters: +** a -- the address to find the controller of. +** +** Returns: +** the controlling address. +** +** Side Effects: +** none. +*/ + +ADDRESS * +getctladdr(a) + register ADDRESS *a; +{ + while (a != NULL && !bitset(QGOODUID, a->q_flags)) + a = a->q_alias; + return (a); +} +/* +** SELF_REFERENCE -- check to see if an address references itself +** +** The check is done through a chain of aliases. If it is part of +** a loop, break the loop at the "best" address, that is, the one +** that exists as a real user. +** +** This is to handle the case of: +** awc: Andrew.Chang +** Andrew.Chang: awc@mail.server +** which is a problem only on mail.server. +** +** Parameters: +** a -- the address to check. +** e -- the current envelope. +** +** Returns: +** The address that should be retained. +*/ + +ADDRESS * +self_reference(a, e) + ADDRESS *a; + ENVELOPE *e; +{ + ADDRESS *b; /* top entry in self ref loop */ + ADDRESS *c; /* entry that point to a real mail box */ + + if (tTd(27, 1)) + printf("self_reference(%s)\n", a->q_paddr); + + for (b = a->q_alias; b != NULL; b = b->q_alias) + { + if (sameaddr(a, b)) + break; + } + + if (b == NULL) + { + if (tTd(27, 1)) + printf("\t... no self ref\n"); + return NULL; + } + + /* + ** Pick the first address that resolved to a real mail box + ** i.e has a pw entry. The returned value will be marked + ** QSELFREF in recipient(), which in turn will disable alias() + ** from marking it QDONTSEND, which mean it will be used + ** as a deliverable address. + ** + ** The 2 key thing to note here are: + ** 1) we are in a recursive call sequence: + ** alias->sentolist->recipient->alias + ** 2) normally, when we return back to alias(), the address + ** will be marked QDONTSEND, since alias() assumes the + ** expanded form will be used instead of the current address. + ** This behaviour is turned off if the address is marked + ** QSELFREF We set QSELFREF when we return to recipient(). + */ + + c = a; + while (c != NULL) + { + if (bitnset(M_HASPWENT, c->q_mailer->m_flags)) + { + if (tTd(27, 2)) + printf("\t... getpwnam(%s)... ", c->q_user); + if (sm_getpwnam(c->q_user) != NULL) + { + if (tTd(27, 2)) + printf("found\n"); + + /* ought to cache results here */ + if (sameaddr(b, c)) + return b; + else + return c; + } + if (tTd(27, 2)) + printf("failed\n"); + } + c = c->q_alias; + } + + if (tTd(27, 1)) + printf("\t... cannot break loop for \"%s\"\n", a->q_paddr); + + return NULL; +} diff --git a/usr.sbin/sendmail/src/savemail.c b/usr.sbin/sendmail/src/savemail.c new file mode 100644 index 000000000000..78c9149980b2 --- /dev/null +++ b/usr.sbin/sendmail/src/savemail.c @@ -0,0 +1,1388 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)savemail.c 8.87 (Berkeley) 10/28/95"; +#endif /* not lint */ + +# include "sendmail.h" + +/* +** SAVEMAIL -- Save mail on error +** +** If mailing back errors, mail it back to the originator +** together with an error message; otherwise, just put it in +** dead.letter in the user's home directory (if he exists on +** this machine). +** +** Parameters: +** e -- the envelope containing the message in error. +** sendbody -- if TRUE, also send back the body of the +** message; otherwise just send the header. +** +** Returns: +** none +** +** Side Effects: +** Saves the letter, by writing or mailing it back to the +** sender, or by putting it in dead.letter in her home +** directory. +*/ + +/* defines for state machine */ +# define ESM_REPORT 0 /* report to sender's terminal */ +# define ESM_MAIL 1 /* mail back to sender */ +# define ESM_QUIET 2 /* messages have already been returned */ +# define ESM_DEADLETTER 3 /* save in ~/dead.letter */ +# define ESM_POSTMASTER 4 /* return to postmaster */ +# define ESM_USRTMP 5 /* save in /usr/tmp/dead.letter */ +# define ESM_PANIC 6 /* leave the locked queue/transcript files */ +# define ESM_DONE 7 /* the message is successfully delivered */ + +# ifndef _PATH_VARTMP +# define _PATH_VARTMP "/usr/tmp/" +# endif + + +void +savemail(e, sendbody) + register ENVELOPE *e; + bool sendbody; +{ + register struct passwd *pw; + register FILE *fp; + int state; + auto ADDRESS *q = NULL; + register char *p; + MCI mcibuf; + int sfflags; + char buf[MAXLINE+1]; + extern char *ttypath(); + typedef int (*fnptr)(); + extern bool writable(); + + if (tTd(6, 1)) + { + printf("\nsavemail, errormode = %c, id = %s, ExitStat = %d\n e_from=", + e->e_errormode, e->e_id == NULL ? "NONE" : e->e_id, + ExitStat); + printaddr(&e->e_from, FALSE); + } + + if (e->e_id == NULL) + { + /* can't return a message with no id */ + return; + } + + /* + ** In the unhappy event we don't know who to return the mail + ** to, make someone up. + */ + + if (e->e_from.q_paddr == NULL) + { + e->e_sender = "Postmaster"; + if (parseaddr(e->e_sender, &e->e_from, + RF_COPYPARSE|RF_SENDERADDR, '\0', NULL, e) == NULL) + { + syserr("553 Cannot parse Postmaster!"); + ExitStat = EX_SOFTWARE; + finis(); + } + } + e->e_to = NULL; + + /* + ** Basic state machine. + ** + ** This machine runs through the following states: + ** + ** ESM_QUIET Errors have already been printed iff the + ** sender is local. + ** ESM_REPORT Report directly to the sender's terminal. + ** ESM_MAIL Mail response to the sender. + ** ESM_DEADLETTER Save response in ~/dead.letter. + ** ESM_POSTMASTER Mail response to the postmaster. + ** ESM_PANIC Save response anywhere possible. + */ + + /* determine starting state */ + switch (e->e_errormode) + { + case EM_WRITE: + state = ESM_REPORT; + break; + + case EM_BERKNET: + case EM_MAIL: + state = ESM_MAIL; + break; + + case EM_PRINT: + case '\0': + state = ESM_QUIET; + break; + + case EM_QUIET: + /* no need to return anything at all */ + return; + + default: + syserr("554 savemail: bogus errormode x%x\n", e->e_errormode); + state = ESM_MAIL; + break; + } + + /* if this is already an error response, send to postmaster */ + if (bitset(EF_RESPONSE, e->e_flags)) + { + if (e->e_parent != NULL && + bitset(EF_RESPONSE, e->e_parent->e_flags)) + { + /* got an error sending a response -- can it */ + return; + } + state = ESM_POSTMASTER; + } + + while (state != ESM_DONE) + { + if (tTd(6, 5)) + printf(" state %d\n", state); + + switch (state) + { + case ESM_QUIET: + if (bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags)) + state = ESM_DEADLETTER; + else + state = ESM_MAIL; + break; + + case ESM_REPORT: + + /* + ** If the user is still logged in on the same terminal, + ** then write the error messages back to hir (sic). + */ + + p = ttypath(); + if (p == NULL || freopen(p, "w", stdout) == NULL) + { + state = ESM_MAIL; + break; + } + + expand("\201n", buf, sizeof buf, e); + printf("\r\nMessage from %s...\r\n", buf); + printf("Errors occurred while sending mail.\r\n"); + if (e->e_xfp != NULL) + { + (void) fflush(e->e_xfp); + fp = fopen(queuename(e, 'x'), "r"); + } + else + fp = NULL; + if (fp == NULL) + { + syserr("Cannot open %s", queuename(e, 'x')); + printf("Transcript of session is unavailable.\r\n"); + } + else + { + printf("Transcript follows:\r\n"); + while (fgets(buf, sizeof buf, fp) != NULL && + !ferror(stdout)) + fputs(buf, stdout); + (void) xfclose(fp, "savemail transcript", e->e_id); + } + printf("Original message will be saved in dead.letter.\r\n"); + state = ESM_DEADLETTER; + break; + + case ESM_MAIL: + /* + ** If mailing back, do it. + ** Throw away all further output. Don't alias, + ** since this could cause loops, e.g., if joe + ** mails to joe@x, and for some reason the network + ** for @x is down, then the response gets sent to + ** joe@x, which gives a response, etc. Also force + ** the mail to be delivered even if a version of + ** it has already been sent to the sender. + ** + ** If this is a configuration or local software + ** error, send to the local postmaster as well, + ** since the originator can't do anything + ** about it anyway. Note that this is a full + ** copy of the message (intentionally) so that + ** the Postmaster can forward things along. + */ + + if (ExitStat == EX_CONFIG || ExitStat == EX_SOFTWARE) + { + (void) sendtolist("postmaster", + NULLADDR, &e->e_errorqueue, 0, e); + } + if (!emptyaddr(&e->e_from)) + { + (void) sendtolist(e->e_from.q_paddr, + NULLADDR, &e->e_errorqueue, 0, e); + } + + /* + ** Deliver a non-delivery report to the + ** Postmaster-designate (not necessarily + ** Postmaster). This does not include the + ** body of the message, for privacy reasons. + ** You really shouldn't need this. + */ + + e->e_flags |= EF_PM_NOTIFY; + + /* check to see if there are any good addresses */ + for (q = e->e_errorqueue; q != NULL; q = q->q_next) + if (!bitset(QBADADDR|QDONTSEND, q->q_flags)) + break; + if (q == NULL) + { + /* this is an error-error */ + state = ESM_POSTMASTER; + break; + } + if (returntosender(e->e_message, e->e_errorqueue, + sendbody, e) == 0) + { + state = ESM_DONE; + break; + } + + /* didn't work -- return to postmaster */ + state = ESM_POSTMASTER; + break; + + case ESM_POSTMASTER: + /* + ** Similar to previous case, but to system postmaster. + */ + + q = NULL; + if (sendtolist("postmaster", NULL, &q, 0, e) <= 0) + { + syserr("553 cannot parse postmaster!"); + ExitStat = EX_SOFTWARE; + state = ESM_USRTMP; + break; + } + if (returntosender(e->e_message, q, sendbody, e) == 0) + { + state = ESM_DONE; + break; + } + + /* didn't work -- last resort */ + state = ESM_USRTMP; + break; + + case ESM_DEADLETTER: + /* + ** Save the message in dead.letter. + ** If we weren't mailing back, and the user is + ** local, we should save the message in + ** ~/dead.letter so that the poor person doesn't + ** have to type it over again -- and we all know + ** what poor typists UNIX users are. + */ + + p = NULL; + if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) + { + if (e->e_from.q_home != NULL) + p = e->e_from.q_home; + else if ((pw = sm_getpwnam(e->e_from.q_user)) != NULL) + p = pw->pw_dir; + } + if (p == NULL || e->e_dfp == NULL) + { + /* no local directory or no data file */ + state = ESM_MAIL; + break; + } + + /* we have a home directory; write dead.letter */ + define('z', p, e); + expand("\201z/dead.letter", buf, sizeof buf, e); + sfflags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID; + e->e_to = buf; + if (mailfile(buf, NULL, sfflags, e) == EX_OK) + { + bool oldverb = Verbose; + + Verbose = TRUE; + message("Saved message in %s", buf); + Verbose = oldverb; + state = ESM_DONE; + break; + } + state = ESM_MAIL; + break; + + case ESM_USRTMP: + /* + ** Log the mail in /usr/tmp/dead.letter. + */ + + if (e->e_class < 0) + { + state = ESM_DONE; + break; + } + + if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0') + { + state = ESM_PANIC; + break; + } + + strcpy(buf, _PATH_VARTMP); + strcat(buf, "dead.letter"); + + sfflags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_ROOTOK|SFF_OPENASROOT; + if (!writable(buf, NULL, sfflags) || + (fp = safefopen(buf, O_WRONLY|O_CREAT|O_APPEND, + FileMode, sfflags)) == NULL) + { + state = ESM_PANIC; + break; + } + + bzero(&mcibuf, sizeof mcibuf); + mcibuf.mci_out = fp; + mcibuf.mci_mailer = FileMailer; + if (bitnset(M_7BITS, FileMailer->m_flags)) + mcibuf.mci_flags |= MCIF_7BIT; + + putfromline(&mcibuf, e); + (*e->e_puthdr)(&mcibuf, e->e_header, e); + (*e->e_putbody)(&mcibuf, e, NULL); + putline("\n", &mcibuf); + (void) fflush(fp); + if (!ferror(fp)) + { + bool oldverb = Verbose; + + Verbose = TRUE; + message("Saved message in %s", buf); + Verbose = oldverb; +#ifdef LOG + if (LogLevel > 3) + syslog(LOG_NOTICE, "Saved message in %s", buf); +#endif + state = ESM_DONE; + break; + } + state = ESM_PANIC; + (void) xfclose(fp, "savemail", buf); + break; + + default: + syserr("554 savemail: unknown state %d", state); + + /* fall through ... */ + + case ESM_PANIC: + /* leave the locked queue & transcript files around */ + loseqfile(e, "savemail panic"); + syserr("!554 savemail: cannot save rejected email anywhere"); + } + } +} +/* +** RETURNTOSENDER -- return a message to the sender with an error. +** +** Parameters: +** msg -- the explanatory message. +** returnq -- the queue of people to send the message to. +** sendbody -- if TRUE, also send back the body of the +** message; otherwise just send the header. +** e -- the current envelope. +** +** Returns: +** zero -- if everything went ok. +** else -- some error. +** +** Side Effects: +** Returns the current message to the sender via +** mail. +*/ + +#define MAXRETURNS 6 /* max depth of returning messages */ +#define ERRORFUDGE 100 /* nominal size of error message text */ + +int +returntosender(msg, returnq, sendbody, e) + char *msg; + ADDRESS *returnq; + bool sendbody; + register ENVELOPE *e; +{ + register ENVELOPE *ee; + ENVELOPE *oldcur = CurEnv; + ENVELOPE errenvelope; + static int returndepth; + register ADDRESS *q; + char *p; + char buf[MAXNAME + 1]; + extern void errbody __P((MCI *, ENVELOPE *, char *)); + + if (returnq == NULL) + return (-1); + + if (msg == NULL) + msg = "Unable to deliver mail"; + + if (tTd(6, 1)) + { + printf("\n*** Return To Sender: msg=\"%s\", depth=%d, e=%x, returnq=", + msg, returndepth, e); + printaddr(returnq, TRUE); + if (tTd(6, 20)) + { + printf("Sendq="); + printaddr(e->e_sendqueue, TRUE); + } + } + + if (++returndepth >= MAXRETURNS) + { + if (returndepth != MAXRETURNS) + syserr("554 returntosender: infinite recursion on %s", returnq->q_paddr); + /* don't "unrecurse" and fake a clean exit */ + /* returndepth--; */ + return (0); + } + + define('g', e->e_from.q_paddr, e); + define('u', NULL, e); + + /* initialize error envelope */ + ee = newenvelope(&errenvelope, e); + define('a', "\201b", ee); + define('r', "internal", ee); + define('s', "localhost", ee); + define('_', "localhost", ee); + ee->e_puthdr = putheader; + ee->e_putbody = errbody; + ee->e_flags |= EF_RESPONSE|EF_METOO; + if (!bitset(EF_OLDSTYLE, e->e_flags)) + ee->e_flags &= ~EF_OLDSTYLE; + ee->e_sendqueue = returnq; + ee->e_msgsize = ERRORFUDGE; + if (sendbody) + ee->e_msgsize += e->e_msgsize; + else + ee->e_flags |= EF_NO_BODY_RETN; + initsys(ee); + for (q = returnq; q != NULL; q = q->q_next) + { + if (bitset(QBADADDR, q->q_flags)) + continue; + + if (!DontPruneRoutes && pruneroute(q->q_paddr)) + { + register ADDRESS *p; + + parseaddr(q->q_paddr, q, RF_COPYPARSE, '\0', NULL, e); + for (p = returnq; p != NULL; p = p->q_next) + { + if (p != q && sameaddr(p, q)) + q->q_flags |= QDONTSEND; + } + } + + if (!bitset(QDONTSEND, q->q_flags)) + ee->e_nrcpts++; + + if (q->q_alias == NULL) + addheader("To", q->q_paddr, &ee->e_header); + } + +# ifdef LOG + if (LogLevel > 5) + { + if (bitset(EF_RESPONSE|EF_WARNING, e->e_flags)) + p = "return to sender"; + else + p = "postmaster notify"; + syslog(LOG_INFO, "%s: %s: %s: %s", + e->e_id, ee->e_id, p, shortenstring(msg, 203)); + } +# endif + + if (SendMIMEErrors) + { + addheader("MIME-Version", "1.0", &ee->e_header); + + (void) sprintf(buf, "%s.%ld/%.100s", + ee->e_id, curtime(), MyHostName); + ee->e_msgboundary = newstr(buf); + (void) sprintf(buf, +#if DSN + "multipart/report; report-type=delivery-status;\n\tboundary=\"%s\"", +#else + "multipart/mixed; boundary=\"%s\"", +#endif + ee->e_msgboundary); + addheader("Content-Type", buf, &ee->e_header); + + p = hvalue("Content-Transfer-Encoding", e->e_header); + if (p != NULL && strcasecmp(p, "binary") != 0) + p = NULL; + if (p == NULL && bitset(EF_HAS8BIT, e->e_flags)) + p = "8bit"; + if (p != NULL) + addheader("Content-Transfer-Encoding", p, &ee->e_header); + } + if (strncmp(msg, "Warning:", 8) == 0) + { + addheader("Subject", msg, &ee->e_header); + p = "warning-timeout"; + } + else if (strncmp(msg, "Postmaster warning:", 19) == 0) + { + addheader("Subject", msg, &ee->e_header); + p = "postmaster-warning"; + } + else if (strcmp(msg, "Return receipt") == 0) + { + addheader("Subject", msg, &ee->e_header); + p = "return-receipt"; + } + else + { + sprintf(buf, "Returned mail: %.*s", sizeof buf - 20, msg); + addheader("Subject", buf, &ee->e_header); + p = "failure"; + } + (void) sprintf(buf, "auto-generated (%s)", p); + addheader("Auto-Submitted", buf, &ee->e_header); + + /* fake up an address header for the from person */ + expand("\201n", buf, sizeof buf, e); + if (parseaddr(buf, &ee->e_from, RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL) + { + syserr("553 Can't parse myself!"); + ExitStat = EX_SOFTWARE; + returndepth--; + return (-1); + } + ee->e_sender = ee->e_from.q_paddr; + + /* push state into submessage */ + CurEnv = ee; + define('f', "\201n", ee); + define('x', "Mail Delivery Subsystem", ee); + eatheader(ee, TRUE); + + /* mark statistics */ + markstats(ee, NULLADDR); + + /* actually deliver the error message */ + sendall(ee, SM_DEFAULT); + + /* restore state */ + dropenvelope(ee); + CurEnv = oldcur; + returndepth--; + + /* check for delivery errors */ + if (ee->e_parent == NULL || !bitset(EF_RESPONSE, ee->e_parent->e_flags)) + return 0; + for (q = ee->e_sendqueue; q != NULL; q = q->q_next) + { + if (bitset(QSENT, q->q_flags)) + return 0; + } + return -1; +} +/* +** ERRBODY -- output the body of an error message. +** +** Typically this is a copy of the transcript plus a copy of the +** original offending message. +** +** Parameters: +** mci -- the mailer connection information. +** e -- the envelope we are working in. +** separator -- any possible MIME separator. +** flags -- to modify the behaviour. +** +** Returns: +** none +** +** Side Effects: +** Outputs the body of an error message. +*/ + +void +errbody(mci, e, separator) + register MCI *mci; + register ENVELOPE *e; + char *separator; +{ + register FILE *xfile; + char *p; + register ADDRESS *q; + bool printheader; + bool sendbody; + char buf[MAXLINE]; + extern char *xuntextify(); + + if (bitset(MCIF_INHEADER, mci->mci_flags)) + { + putline("", mci); + mci->mci_flags &= ~MCIF_INHEADER; + } + if (e->e_parent == NULL) + { + syserr("errbody: null parent"); + putline(" ----- Original message lost -----\n", mci); + return; + } + + /* + ** Output MIME header. + */ + + if (e->e_msgboundary != NULL) + { + putline("This is a MIME-encapsulated message", mci); + putline("", mci); + (void) sprintf(buf, "--%s", e->e_msgboundary); + putline(buf, mci); + putline("", mci); + } + + /* + ** Output introductory information. + */ + + for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) + if (bitset(QBADADDR, q->q_flags)) + break; + if (q == NULL && + !bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags)) + { + putline(" **********************************************", + mci); + putline(" ** THIS IS A WARNING MESSAGE ONLY **", + mci); + putline(" ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **", + mci); + putline(" **********************************************", + mci); + putline("", mci); + } + sprintf(buf, "The original message was received at %s", + arpadate(ctime(&e->e_parent->e_ctime))); + putline(buf, mci); + expand("from \201_", buf, sizeof buf, e->e_parent); + putline(buf, mci); + putline("", mci); + + /* + ** Output error message header (if specified and available). + */ + + if (ErrMsgFile != NULL && !bitset(EF_SENDRECEIPT, e->e_parent->e_flags)) + { + if (*ErrMsgFile == '/') + { + xfile = fopen(ErrMsgFile, "r"); + if (xfile != NULL) + { + while (fgets(buf, sizeof buf, xfile) != NULL) + { + expand(buf, buf, sizeof buf, e); + putline(buf, mci); + } + (void) fclose(xfile); + putline("\n", mci); + } + } + else + { + expand(ErrMsgFile, buf, sizeof buf, e); + putline(buf, mci); + putline("", mci); + } + } + + /* + ** Output message introduction + */ + + printheader = TRUE; + for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) + { + if (bitset(QBADADDR, q->q_flags)) + { + if (!bitset(QPINGONFAILURE, q->q_flags)) + continue; + p = "unrecoverable error"; + } + else if (!bitset(QPRIMARY, q->q_flags)) + continue; + else if (bitset(QDELAYED, q->q_flags)) + p = "transient failure"; + else if (!bitset(QPINGONSUCCESS, q->q_flags)) + continue; + else if (bitset(QRELAYED, q->q_flags)) + p = "relayed to non-DSN-aware mailer"; + else if (bitset(QDELIVERED, q->q_flags)) + { + if (bitset(QEXPANDED, q->q_flags)) + p = "successfully delivered to mailing list"; + else + p = "successfully delivered to mailbox"; + } + else if (bitset(QEXPANDED, q->q_flags)) + p = "expanded by alias"; + else + continue; + + if (printheader) + { + putline(" ----- The following addresses have delivery notifications -----", + mci); + printheader = FALSE; + } + + sprintf(buf, "%s (%s)", shortenstring(q->q_paddr, 203), p); + putline(buf, mci); + if (q->q_alias != NULL) + { + sprintf(buf, " (expanded from: %s)", + shortenstring(q->q_alias->q_paddr, 203)); + putline(buf, mci); + } + } + if (!printheader) + putline("\n", mci); + + /* + ** Output transcript of errors + */ + + (void) fflush(stdout); + p = queuename(e->e_parent, 'x'); + if ((xfile = fopen(p, "r")) == NULL) + { + syserr("Cannot open %s", p); + putline(" ----- Transcript of session is unavailable -----\n", mci); + } + else + { + printheader = TRUE; + if (e->e_xfp != NULL) + (void) fflush(e->e_xfp); + while (fgets(buf, sizeof buf, xfile) != NULL) + { + if (printheader) + putline(" ----- Transcript of session follows -----\n", mci); + printheader = FALSE; + putline(buf, mci); + } + (void) xfclose(xfile, "errbody xscript", p); + } + errno = 0; + +#if DSN + /* + ** Output machine-readable version. + */ + + if (e->e_msgboundary != NULL) + { + putline("", mci); + (void) sprintf(buf, "--%s", e->e_msgboundary); + putline(buf, mci); + putline("Content-Type: message/delivery-status", mci); + putline("", mci); + + /* + ** Output per-message information. + */ + + /* original envelope id from MAIL FROM: line */ + if (e->e_parent->e_envid != NULL) + { + (void) sprintf(buf, "Original-Envelope-Id: %.800s", + xuntextify(e->e_parent->e_envid)); + putline(buf, mci); + } + + /* Reporting-MTA: is us (required) */ + (void) sprintf(buf, "Reporting-MTA: dns; %.800s", MyHostName); + putline(buf, mci); + + /* DSN-Gateway: not relevant since we are not translating */ + + /* Received-From-MTA: shows where we got this message from */ + if (RealHostName != NULL) + { + /* XXX use $s for type? */ + if (e->e_parent->e_from.q_mailer == NULL || + (p = e->e_parent->e_from.q_mailer->m_mtatype) == NULL) + p = "dns"; + (void) sprintf(buf, "Received-From-MTA: %s; %.800s", + p, RealHostName); + putline(buf, mci); + } + + /* Arrival-Date: -- when it arrived here */ + (void) sprintf(buf, "Arrival-Date: %s", + arpadate(ctime(&e->e_parent->e_ctime))); + putline(buf, mci); + + /* + ** Output per-address information. + */ + + for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) + { + register ADDRESS *r; + char *action; + + if (bitset(QBADADDR, q->q_flags)) + action = "failed"; + else if (!bitset(QPRIMARY, q->q_flags)) + continue; + else if (bitset(QDELIVERED, q->q_flags)) + { + if (bitset(QEXPANDED, q->q_flags)) + action = "delivered (to mailing list)"; + else + action = "delivered (to mailbox)"; + } + else if (bitset(QRELAYED, q->q_flags)) + action = "relayed (to non-DSN-aware mailer)"; + else if (bitset(QEXPANDED, q->q_flags)) + action = "expanded (to multi-recipient alias)"; + else if (bitset(QDELAYED, q->q_flags)) + action = "delayed"; + else + continue; + + putline("", mci); + + /* Original-Recipient: -- passed from on high */ + if (q->q_orcpt != NULL) + { + (void) sprintf(buf, "Original-Recipient: %.800s", + q->q_orcpt); + putline(buf, mci); + } + + /* Final-Recipient: -- the name from the RCPT command */ + p = e->e_parent->e_from.q_mailer->m_addrtype; + if (p == NULL) + p = "rfc822"; + for (r = q; r->q_alias != NULL; r = r->q_alias) + continue; + if (strchr(r->q_user, '@') == NULL) + { + (void) sprintf(buf, "Final-Recipient: %s; %.700s@%.100s", + p, r->q_user, MyHostName); + } + else + { + (void) sprintf(buf, "Final-Recipient: %s; %.800s", + p, r->q_user); + } + putline(buf, mci); + + /* X-Actual-Recipient: -- the real problem address */ + if (r != q && q->q_user[0] != '\0') + { + if (strchr(q->q_user, '@') == NULL) + { + (void) sprintf(buf, "X-Actual-Recipient: %s; %.700s@%.100s", + p, q->q_user, MyHostName); + } + else + { + (void) sprintf(buf, "X-Actual-Recipient: %s; %.800s", + p, q->q_user); + } + putline(buf, mci); + } + + /* Action: -- what happened? */ + sprintf(buf, "Action: %s", action); + putline(buf, mci); + + /* Status: -- what _really_ happened? */ + strcpy(buf, "Status: "); + if (q->q_status != NULL) + strcat(buf, q->q_status); + else if (bitset(QBADADDR, q->q_flags)) + strcat(buf, "5.0.0"); + else if (bitset(QQUEUEUP, q->q_flags)) + strcat(buf, "4.0.0"); + else + strcat(buf, "2.0.0"); + putline(buf, mci); + + /* Remote-MTA: -- who was I talking to? */ + if (q->q_statmta != NULL) + { + if (q->q_mailer == NULL || + (p = q->q_mailer->m_mtatype) == NULL) + p = "dns"; + (void) sprintf(buf, "Remote-MTA: %s; %.800s", + p, q->q_statmta); + p = &buf[strlen(buf) - 1]; + if (*p == '.') + *p = '\0'; + putline(buf, mci); + } + + /* Diagnostic-Code: -- actual result from other end */ + if (q->q_rstatus != NULL) + { + p = q->q_mailer->m_diagtype; + if (p == NULL) + p = "smtp"; + (void) sprintf(buf, "Diagnostic-Code: %s; %.800s", + p, q->q_rstatus); + putline(buf, mci); + } + + /* Last-Attempt-Date: -- fine granularity */ + if (q->q_statdate == (time_t) 0L) + q->q_statdate = curtime(); + (void) sprintf(buf, "Last-Attempt-Date: %s", + arpadate(ctime(&q->q_statdate))); + putline(buf, mci); + + /* Will-Retry-Until: -- for delayed messages only */ + if (bitset(QQUEUEUP, q->q_flags) && + !bitset(QBADADDR, q->q_flags)) + { + time_t xdate; + + xdate = e->e_parent->e_ctime + + TimeOuts.to_q_return[e->e_parent->e_timeoutclass]; + sprintf(buf, "Will-Retry-Until: %s", + arpadate(ctime(&xdate))); + putline(buf, mci); + } + } + } +#endif + + /* + ** Output text of original message + */ + + putline("", mci); + if (bitset(EF_HAS_DF, e->e_parent->e_flags)) + { + sendbody = !bitset(EF_NO_BODY_RETN, e->e_parent->e_flags) && + !bitset(EF_NO_BODY_RETN, e->e_flags); + + if (e->e_msgboundary == NULL) + { + if (sendbody) + putline(" ----- Original message follows -----\n", mci); + else + putline(" ----- Message header follows -----\n", mci); + (void) fflush(mci->mci_out); + } + else + { + (void) sprintf(buf, "--%s", e->e_msgboundary); + + putline(buf, mci); + (void) sprintf(buf, "Content-Type: %s", + sendbody ? "message/rfc822" + : "text/rfc822-headers"); + putline(buf, mci); + + p = hvalue("Content-Transfer-Encoding", e->e_parent->e_header); + if (p != NULL && strcasecmp(p, "binary") != 0) + p = NULL; + if (p == NULL && bitset(EF_HAS8BIT, e->e_parent->e_flags)) + p = "8bit"; + if (p != NULL) + { + (void) sprintf(buf, "Content-Transfer-Encoding: %s", + p); + putline(buf, mci); + } + } + putline("", mci); + putheader(mci, e->e_parent->e_header, e->e_parent); + if (sendbody) + putbody(mci, e->e_parent, e->e_msgboundary); + else if (e->e_msgboundary == NULL) + { + putline("", mci); + putline(" ----- Message body suppressed -----", mci); + } + } + else if (e->e_msgboundary == NULL) + { + putline(" ----- No message was collected -----\n", mci); + } + + if (e->e_msgboundary != NULL) + { + putline("", mci); + (void) sprintf(buf, "--%s--", e->e_msgboundary); + putline(buf, mci); + } + putline("", mci); + + /* + ** Cleanup and exit + */ + + if (errno != 0) + syserr("errbody: I/O error"); +} +/* +** SMTPTODSN -- convert SMTP to DSN status code +** +** Parameters: +** smtpstat -- the smtp status code (e.g., 550). +** +** Returns: +** The DSN version of the status code. +*/ + +char * +smtptodsn(smtpstat) + int smtpstat; +{ + if (smtpstat < 0) + return "4.4.2"; + + switch (smtpstat) + { + case 450: /* Req mail action not taken: mailbox unavailable */ + return "4.2.0"; + + case 451: /* Req action aborted: local error in processing */ + return "4.3.0"; + + case 452: /* Req action not taken: insufficient sys storage */ + return "4.3.1"; + + case 500: /* Syntax error, command unrecognized */ + return "5.5.2"; + + case 501: /* Syntax error in parameters or arguments */ + return "5.5.4"; + + case 502: /* Command not implemented */ + return "5.5.1"; + + case 503: /* Bad sequence of commands */ + return "5.5.1"; + + case 504: /* Command parameter not implemented */ + return "5.5.4"; + + case 550: /* Req mail action not taken: mailbox unavailable */ + return "5.2.0"; + + case 551: /* User not local; please try <...> */ + return "5.1.6"; + + case 552: /* Req mail action aborted: exceeded storage alloc */ + return "5.2.2"; + + case 553: /* Req action not taken: mailbox name not allowed */ + return "5.1.3"; + + case 554: /* Transaction failed */ + return "5.0.0"; + } + + if ((smtpstat / 100) == 2) + return "2.0.0"; + if ((smtpstat / 100) == 4) + return "4.0.0"; + return "5.0.0"; +} +/* +** XTEXTIFY -- take regular text and turn it into DSN-style xtext +** +** Parameters: +** t -- the text to convert. +** +** Returns: +** The xtext-ified version of the same string. +*/ + +char * +xtextify(t) + register char *t; +{ + register char *p; + int l; + int nbogus; + static char *bp = NULL; + static int bplen = 0; + + /* figure out how long this xtext will have to be */ + nbogus = l = 0; + for (p = t; *p != '\0'; p++) + { + register int c = (*p & 0xff); + + /* ASCII dependence here -- this is the way the spec words it */ + if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(') + nbogus++; + l++; + } + if (nbogus == 0) + return t; + l += nbogus * 2 + 1; + + /* now allocate space if necessary for the new string */ + if (l > bplen) + { + if (bp != NULL) + free(bp); + bp = xalloc(l); + bplen = l; + } + + /* ok, copy the text with byte expansion */ + for (p = bp; *t != '\0'; ) + { + register int c = (*t++ & 0xff); + + /* ASCII dependence here -- this is the way the spec words it */ + if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(') + { + *p++ = '+'; + *p++ = "0123456789abcdef"[c >> 4]; + *p++ = "0123456789abcdef"[c & 0xf]; + } + else + *p++ = c; + } + *p = '\0'; + return bp; +} +/* +** XUNTEXTIFY -- take xtext and turn it into plain text +** +** Parameters: +** t -- the xtextified text. +** +** Returns: +** The decoded text. No attempt is made to deal with +** null strings in the resulting text. +*/ + +char * +xuntextify(t) + register char *t; +{ + register char *p; + int l; + static char *bp = NULL; + static int bplen = 0; + + /* heuristic -- if no plus sign, just return the input */ + if (strchr(t, '+') == NULL) + return t; + + /* xtext is always longer than decoded text */ + l = strlen(t); + if (l > bplen) + { + if (bp != NULL) + free(bp); + bp = xalloc(l); + bplen = l; + } + + /* ok, copy the text with byte compression */ + for (p = bp; *t != '\0'; t++) + { + register int c = *t & 0xff; + + if (c != '+') + { + *p++ = c; + continue; + } + + c = *++t & 0xff; + if (!isascii(c) || !isxdigit(c)) + { + /* error -- first digit is not hex */ + usrerr("bogus xtext: +%c", c); + t--; + continue; + } + if (isdigit(c)) + c -= '0'; + else if (isupper(c)) + c -= 'A' - 10; + else + c -= 'a' - 10; + *p = c << 4; + + c = *++t & 0xff; + if (!isascii(c) || !isxdigit(c)) + { + /* error -- second digit is not hex */ + usrerr("bogus xtext: +%x%c", *p >> 4, c); + t--; + continue; + } + if (isdigit(c)) + c -= '0'; + else if (isupper(c)) + c -= 'A' - 10; + else + c -= 'a' - 10; + *p++ |= c; + } + return bp; +} +/* +** XTEXTOK -- check if a string is legal xtext +** +** Xtext is used in Delivery Status Notifications. The spec was +** taken from draft-ietf-notary-mime-delivery-04.txt. +** +** Parameters: +** s -- the string to check. +** +** Returns: +** TRUE -- if 's' is legal xtext. +** FALSE -- if it has any illegal characters in it. +*/ + +bool +xtextok(s) + char *s; +{ + int c; + + while ((c = *s++) != '\0') + { + if (c == '+') + { + c = *s++; + if (!isascii(c) || !isxdigit(c)) + return FALSE; + c = *s++; + if (!isascii(c) || !isxdigit(c)) + return FALSE; + } + else if (c < '!' || c > '~' || c == '=') + return FALSE; + } + return TRUE; +} +/* +** PRUNEROUTE -- prune an RFC-822 source route +** +** Trims down a source route to the last internet-registered hop. +** This is encouraged by RFC 1123 section 5.3.3. +** +** Parameters: +** addr -- the address +** +** Returns: +** TRUE -- address was modified +** FALSE -- address could not be pruned +** +** Side Effects: +** modifies addr in-place +*/ + +bool +pruneroute(addr) + char *addr; +{ +#if NAMED_BIND + char *start, *at, *comma; + char c; + int rcode; + char hostbuf[BUFSIZ]; + char *mxhosts[MAXMXHOSTS + 1]; + + /* check to see if this is really a route-addr */ + if (*addr != '<' || addr[1] != '@' || addr[strlen(addr) - 1] != '>') + return FALSE; + start = strchr(addr, ':'); + at = strrchr(addr, '@'); + if (start == NULL || at == NULL || at < start) + return FALSE; + + /* slice off the angle brackets */ + strcpy(hostbuf, at + 1); + hostbuf[strlen(hostbuf) - 1] = '\0'; + + while (start) + { + if (getmxrr(hostbuf, mxhosts, FALSE, &rcode) > 0) + { + strcpy(addr + 1, start + 1); + return TRUE; + } + c = *start; + *start = '\0'; + comma = strrchr(addr, ','); + if (comma && comma[1] == '@') + strcpy(hostbuf, comma + 2); + else + comma = 0; + *start = c; + start = comma; + } +#endif + return FALSE; +} diff --git a/usr.sbin/sendmail/src/sendmail.8 b/usr.sbin/sendmail/src/sendmail.8 new file mode 100644 index 000000000000..3397b8f947da --- /dev/null +++ b/usr.sbin/sendmail/src/sendmail.8 @@ -0,0 +1,514 @@ +.\" Copyright (c) 1988, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)sendmail.8 8.6 (Berkeley) 5/27/95 +.\" +.Dd May 27, 1995 +.Dt SENDMAIL 8 +.Os BSD 4 +.Sh NAME +.Nm sendmail +.Nd send mail over the internet +.Sh SYNOPSIS +.Nm sendmail +.Op Ar flags +.Op Ar address ... +.Nm newaliases +.Nm mailq +.Op Fl v +.Sh DESCRIPTION +.Nm Sendmail +sends a message to one or more +.Em recipients , +routing the message over whatever networks +are necessary. +.Nm Sendmail +does internetwork forwarding as necessary +to deliver the message to the correct place. +.Pp +.Nm Sendmail +is not intended as a user interface routine; +other programs provide user-friendly +front ends; +.Nm sendmail +is used only to deliver pre-formatted messages. +.Pp +With no flags, +.Nm sendmail +reads its standard input +up to an end-of-file +or a line consisting only of a single dot +and sends a copy of the message found there +to all of the addresses listed. +It determines the network(s) to use +based on the syntax and contents of the addresses. +.Pp +Local addresses are looked up in a file +and aliased appropriately. +Aliasing can be prevented by preceding the address +with a backslash. +Normally the sender is not included in any alias +expansions, e.g., +if `john' sends to `group', +and `group' includes `john' in the expansion, +then the letter will not be delivered to `john'. +.Ss Parameters +.Bl -tag -width Fl +.It Fl B Ns Ar type +Set the body type to +.Ar type . +Current legal values +.Li 7BIT +or +.Li 8BITMIME . +.It Fl ba +Go into +.Tn ARPANET +mode. +All input lines must end with a CR-LF, +and all messages will be generated with a CR-LF at the end. +Also, +the ``From:'' and ``Sender:'' +fields are examined for the name of the sender. +.It Fl bd +Run as a daemon. This requires Berkeley +.Tn IPC . +.Nm Sendmail +will fork and run in background +listening on socket 25 for incoming +.Tn SMTP +connections. +This is normally run from +.Pa /etc/rc . +.It Fl bi +Initialize the alias database. +.It Fl bm +Deliver mail in the usual way (default). +.It Fl bp +Print a listing of the queue. +.It Fl bs +Use the +.Tn SMTP +protocol as described in +.Tn RFC821 +on standard input and output. +This flag implies all the operations of the +.Fl ba +flag that are compatible with +.Tn SMTP . +.It Fl bt +Run in address test mode. +This mode reads addresses and shows the steps in parsing; +it is used for debugging configuration tables. +.It Fl bv +Verify names only \- do not try to collect or deliver a message. +Verify mode is normally used for validating +users or mailing lists. +.It Fl C Ns Ar file +Use alternate configuration file. +.Nm Sendmail +refuses to run as root if an alternate configuration file is specified. +.It Fl d Ns Ar X +Set debugging value to +.Ar X . +.ne 1i +.It Fl F Ns Ar fullname +Set the full name of the sender. +.It Fl f Ns Ar name +Sets the name of the ``from'' person +(i.e., the sender of the mail). +.Fl f +can only be used +by ``trusted'' users +(normally +.Em root , +.Em daemon , +and +.Em network ) +or if the person you are trying to become +is the same as the person you are. +.It Fl h Ns Ar N +Set the hop count to +.Ar N . +The hop count is incremented every time the mail is +processed. +When it reaches a limit, +the mail is returned with an error message, +the victim of an aliasing loop. +If not specified, +``Received:'' lines in the message are counted. +.It Fl n +Don't do aliasing. +.It Fl o Ns Ar x Em value +Set option +.Ar x +to the specified +.Em value . +Options are described below. +.It Fl p Ns Ar protocol +Set the name of the protocol used to receive the message. +This can be a simple protocol name such as ``UUCP'' +or a protocol and hostname, such as ``UUCP:ucbvax''. +.It Fl q Ns Bq Ar time +Processed saved messages in the queue at given intervals. +If +.Ar time +is omitted, +process the queue once. +.Xr Time +is given as a tagged number, +with +.Ql s +being seconds, +.Ql m +being minutes, +.Ql h +being hours, +.Ql d +being days, +and +.Ql w +being weeks. +For example, +.Ql \-q1h30m +or +.Ql \-q90m +would both set the timeout to one hour thirty minutes. +If +.Ar time +is specified, +.Nm sendmail +will run in background. +This option can be used safely with +.Fl bd . +.It Fl qI Ns Ar substr +Limit processed jobs to those containing +.Ar substr +as a substring of the queue id. +.It Fl qR Ns Ar substr +Limit processed jobs to those containing +.Ar substr +as a substring of one of the recipients. +.It Fl qS Ns Ar substr +Limit processed jobs to those containing +.Ar substr +as a substring of the sender. +.It Fl r Ns Ar name +An alternate and obsolete form of the +.Fl f +flag. +.It Fl t +Read message for recipients. +To:, Cc:, and Bcc: lines will be scanned for recipient addresses. +The Bcc: line will be deleted before transmission. +Any addresses in the argument list will be suppressed, +that is, +they will +.Em not +receive copies even if listed in the message header. +.It Fl v +Go into verbose mode. +Alias expansions will be announced, etc. +.It Fl X Ar logfile +Log all traffic in and out of mailers in the indicated log file. +This should only be used as a last resort +for debugging mailer bugs. +It will log a lot of data very quickly. +.El +.Ss Options +There are also a number of processing options that may be set. +Normally these will only be used by a system administrator. +Options may be set either on the command line +using the +.Fl o +flag +or in the configuration file. +This is a partial list; +for a complete list (and details), consult the +.%T "Sendmail Installation and Operation Guide" . +The options are: +.Bl -tag -width Fl +.It Li A Ns Ar file +Use alternate alias file. +.It Li b Ns Ar nblocks +The minimum number of free blocks needed on the spool filesystem. +.It Li c +On mailers that are considered ``expensive'' to connect to, +don't initiate immediate connection. +This requires queueing. +.It Li C Ar N +Checkpoint the queue file after every +.Ar N +successful deliveries (default 10). +This avoids excessive duplicate deliveries +when sending to long mailing lists +interrupted by system crashes. +.ne 1i +.It Li d Ns Ar x +Set the delivery mode to +.Ar x . +Delivery modes are +.Ql i +for interactive (synchronous) delivery, +.Ql b +for background (asynchronous) delivery, +and +.Ql q +for queue only \- i.e., +actual delivery is done the next time the queue is run. +.It Li D +Try to automatically rebuild the alias database +if necessary. +.It Li e Ns Ar x +Set error processing to mode +.Ar x . +Valid modes are +.Ql m +to mail back the error message, +.Ql w +to ``write'' back the error message +(or mail it back if the sender is not logged in), +.Ql p +to print the errors on the terminal +(default), +.Ql q +to throw away error messages +(only exit status is returned), +and +.Ql e +to do special processing for the BerkNet. +If the text of the message is not mailed back +by +modes +.Ql m +or +.Ql w +and if the sender is local to this machine, +a copy of the message is appended to the file +.Pa dead.letter +in the sender's home directory. +.It Li f +Save +.Tn UNIX Ns \-style +From lines at the front of messages. +.It Li G +Match local mail names against the GECOS portion of the password file. +.It Li g Ar N +The default group id to use when calling mailers. +.It Li H Ns Ar file +The +.Tn SMTP +help file. +.It Li h Ar N +The maximum number of times a message is allowed to ``hop'' +before we decide it is in a loop. +.It Li i +Do not take dots on a line by themselves +as a message terminator. +.It Li j +Send error messages in MIME format. +.It Li K Ns Ar timeout +Set connection cache timeout. +.It Li k Ns Ar N +Set connection cache size. +.It Li L Ns Ar n +The log level. +.It Li l +Pay attention to the Errors-To: header. +.It Li m +Send to ``me'' (the sender) also if I am in an alias expansion. +.It Li n +Validate the right hand side of aliases during a +.Xr newaliases 1 +command. +.It Li o +If set, this message may have +old style headers. +If not set, +this message is guaranteed to have new style headers +(i.e., commas instead of spaces between addresses). +If set, an adaptive algorithm is used that will correctly +determine the header format in most cases. +.It Li Q Ns Ar queuedir +Select the directory in which to queue messages. +.It Li S Ns Ar file +Save statistics in the named file. +.It Li s +Always instantiate the queue file, +even under circumstances where it is not strictly necessary. +This provides safety against system crashes during delivery. +.It Li T Ns Ar time +Set the timeout on undelivered messages in the queue to the specified time. +After delivery has failed +(e.g., because of a host being down) +for this amount of time, +failed messages will be returned to the sender. +The default is three days. +.It Li t Ns Ar stz , Ar dtz +Set the name of the time zone. +.It Li U Ns Ar userdatabase +If set, a user database is consulted to get forwarding information. +You can consider this an adjunct to the aliasing mechanism, +except that the database is intended to be distributed; +aliases are local to a particular host. +This may not be available if your sendmail does not have the +.Dv USERDB +option compiled in. +.It Li u Ns Ar N +Set the default user id for mailers. +.It Li Y +Fork each job during queue runs. +May be convenient on memory-poor machines. +.It Li 7 +Strip incoming messages to seven bits. +.El +.Pp +In aliases, +the first character of a name may be +a vertical bar to cause interpretation of +the rest of the name as a command +to pipe the mail to. +It may be necessary to quote the name +to keep +.Nm sendmail +from suppressing the blanks from between arguments. +For example, a common alias is: +.Pp +.Bd -literal -offset indent -compact +msgs: "|/usr/bin/msgs -s" +.Ed +.Pp +Aliases may also have the syntax +.Dq :include: Ns Ar filename +to ask +.Xr sendmail +to read the named file for a list of recipients. +For example, an alias such as: +.Pp +.Bd -literal -offset indent -compact +poets: ":include:/usr/local/lib/poets.list" +.Ed +.Pp +would read +.Pa /usr/local/lib/poets.list +for the list of addresses making up the group. +.Pp +.Nm Sendmail +returns an exit status +describing what it did. +The codes are defined in +.Aq Pa sysexits.h : +.Bl -tag -width EX_UNAVAILABLE -compact -offset indent +.It Dv EX_OK +Successful completion on all addresses. +.It Dv EX_NOUSER +User name not recognized. +.It Dv EX_UNAVAILABLE +Catchall meaning necessary resources +were not available. +.It Dv EX_SYNTAX +Syntax error in address. +.It Dv EX_SOFTWARE +Internal software error, +including bad arguments. +.It Dv EX_OSERR +Temporary operating system error, +such as +.Dq cannot fork . +.It Dv EX_NOHOST +Host name not recognized. +.It Dv EX_TEMPFAIL +Message could not be sent immediately, +but was queued. +.El +.Pp +If invoked as +.Nm newaliases , +.Nm sendmail +will rebuild the alias database. +If invoked as +.Nm mailq , +.Nm sendmail +will print the contents of the mail queue. +.Sh FILES +Except for the file +.Pa /etc/sendmail.cf +itself, +the following pathnames are all specified in +.Pa /etc/sendmail.cf. +Thus, +these values are only approximations. +.Pp +.Bl -tag -width /usr/lib/sendmail.fc -compact +.It Pa /etc/aliases +raw data for alias names +.It Pa /etc/aliases.db +data base of alias names +.It Pa /etc/sendmail.cf +configuration file +.It Pa /etc/sendmail.hf +help file +.It Pa /var/log/sendmail.st +collected statistics +.It Pa /var/spool/mqueue/* +temp files +.It Pa /var/run/sendmail.pid +The process id of the daemon +.El +.Sh SEE ALSO +.Xr binmail 1 , +.Xr mail 1 , +.Xr rmail 1 , +.Xr syslog 3 , +.Xr aliases 5 , +.Xr mailaddr 7 , +.Xr rc 8 ; +.Pp +DARPA +Internet Request For Comments +.%T RFC819 , +.%T RFC821 , +.%T RFC822 . +.Rs +.%T "Sendmail \- An Internetwork Mail Router" +.%V SMM +.%N \&No. 9 +.Re +.Rs +.%T "Sendmail Installation and Operation Guide" +.%V SMM +.%N \&No. 8 +.Re +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/sendmail/src/sendmail.h b/usr.sbin/sendmail/src/sendmail.h new file mode 100644 index 000000000000..9de20ca4b23d --- /dev/null +++ b/usr.sbin/sendmail/src/sendmail.h @@ -0,0 +1,1237 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)sendmail.h 8.159 (Berkeley) 11/18/95 + */ + +/* +** SENDMAIL.H -- Global definitions for sendmail. +*/ + +# ifdef _DEFINE +# define EXTERN +# ifndef lint +static char SmailSccsId[] = "@(#)sendmail.h 8.159 11/18/95"; +# endif +# else /* _DEFINE */ +# define EXTERN extern +# endif /* _DEFINE */ + +# include <unistd.h> +# include <stddef.h> +# include <stdlib.h> +# include <stdio.h> +# include <ctype.h> +# include <setjmp.h> +# include <string.h> +# include <time.h> +# include <errno.h> +# ifdef EX_OK +# undef EX_OK /* for SVr4.2 SMP */ +# endif +# include <sysexits.h> + +# include "conf.h" +# include "useful.h" + +# ifdef LOG +# include <syslog.h> +# endif /* LOG */ + +# ifdef DAEMON +# include <sys/socket.h> +# endif +# if NETUNIX +# include <sys/un.h> +# endif +# if NETINET +# include <netinet/in.h> +# endif +# if NETISO +# include <netiso/iso.h> +# endif +# if NETNS +# include <netns/ns.h> +# endif +# if NETX25 +# include <netccitt/x25.h> +# endif + + + +/* forward references for prototypes */ +typedef struct envelope ENVELOPE; +typedef struct mailer MAILER; + + +/* +** Data structure for bit maps. +** +** Each bit in this map can be referenced by an ascii character. +** This is 256 possible bits, or 32 8-bit bytes. +*/ + +#define BITMAPBYTES 32 /* number of bytes in a bit map */ +#define BYTEBITS 8 /* number of bits in a byte */ + +/* internal macros */ +#define _BITWORD(bit) ((bit) / (BYTEBITS * sizeof (int))) +#define _BITBIT(bit) (1 << ((bit) % (BYTEBITS * sizeof (int)))) + +typedef int BITMAP[BITMAPBYTES / sizeof (int)]; + +/* test bit number N */ +#define bitnset(bit, map) ((map)[_BITWORD(bit)] & _BITBIT(bit)) + +/* set bit number N */ +#define setbitn(bit, map) (map)[_BITWORD(bit)] |= _BITBIT(bit) + +/* clear bit number N */ +#define clrbitn(bit, map) (map)[_BITWORD(bit)] &= ~_BITBIT(bit) + +/* clear an entire bit map */ +#define clrbitmap(map) bzero((char *) map, BITMAPBYTES) +/* +** Address structure. +** Addresses are stored internally in this structure. +*/ + +struct address +{ + char *q_paddr; /* the printname for the address */ + char *q_user; /* user name */ + char *q_ruser; /* real user name, or NULL if q_user */ + char *q_host; /* host name */ + struct mailer *q_mailer; /* mailer to use */ + u_long q_flags; /* status flags, see below */ + uid_t q_uid; /* user-id of receiver (if known) */ + gid_t q_gid; /* group-id of receiver (if known) */ + char *q_home; /* home dir (local mailer only) */ + char *q_fullname; /* full name if known */ + struct address *q_next; /* chain */ + struct address *q_alias; /* address this results from */ + char *q_owner; /* owner of q_alias */ + struct address *q_tchain; /* temporary use chain */ + char *q_orcpt; /* ORCPT parameter from RCPT TO: line */ + char *q_status; /* status code for DSNs */ + char *q_rstatus; /* remote status message for DSNs */ + time_t q_statdate; /* date of status messages */ + char *q_statmta; /* MTA generating q_rstatus */ + short q_specificity; /* how "specific" this address is */ +}; + +typedef struct address ADDRESS; + +# define QDONTSEND 0x00000001 /* don't send to this address */ +# define QBADADDR 0x00000002 /* this address is verified bad */ +# define QGOODUID 0x00000004 /* the q_uid q_gid fields are good */ +# define QPRIMARY 0x00000008 /* set from RCPT or argv */ +# define QQUEUEUP 0x00000010 /* queue for later transmission */ +# define QSENT 0x00000020 /* has been successfully delivered */ +# define QNOTREMOTE 0x00000040 /* address not for remote forwarding */ +# define QSELFREF 0x00000080 /* this address references itself */ +# define QVERIFIED 0x00000100 /* verified, but not expanded */ +# define QBOGUSSHELL 0x00000400 /* user has no valid shell listed */ +# define QUNSAFEADDR 0x00000800 /* address aquired via unsafe path */ +# define QPINGONSUCCESS 0x00001000 /* give return on successful delivery */ +# define QPINGONFAILURE 0x00002000 /* give return on failure */ +# define QPINGONDELAY 0x00004000 /* give return on message delay */ +# define QHASNOTIFY 0x00008000 /* propogate notify parameter */ +# define QRELAYED 0x00010000 /* DSN: relayed to non-DSN aware sys */ +# define QEXPANDED 0x00020000 /* DSN: undergone list expansion */ +# define QDELIVERED 0x00040000 /* DSN: successful final delivery */ +# define QDELAYED 0x00080000 /* DSN: message delayed */ +# define QTHISPASS 0x80000000 /* temp: address set this pass */ + +# define NULLADDR ((ADDRESS *) NULL) + +/* functions */ +extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *)); +extern ADDRESS *recipient __P((ADDRESS *, ADDRESS **, int, ENVELOPE *)); +extern char **prescan __P((char *, int, char[], int, char **, u_char *)); +extern int rewrite __P((char **, int, int, ENVELOPE *)); +extern char *remotename __P((char *, MAILER *, int, int *, ENVELOPE *)); +extern ADDRESS *getctladdr __P((ADDRESS *)); +extern bool sameaddr __P((ADDRESS *, ADDRESS *)); +extern bool emptyaddr __P((ADDRESS *)); +extern void printaddr __P((ADDRESS *, bool)); +extern void cataddr __P((char **, char **, char *, int, int)); +extern int sendtolist __P((char *, ADDRESS *, ADDRESS **, int, ENVELOPE *)); +/* +** Mailer definition structure. +** Every mailer known to the system is declared in this +** structure. It defines the pathname of the mailer, some +** flags associated with it, and the argument vector to +** pass to it. The flags are defined in conf.c +** +** The argument vector is expanded before actual use. All +** words except the first are passed through the macro +** processor. +*/ + +struct mailer +{ + char *m_name; /* symbolic name of this mailer */ + char *m_mailer; /* pathname of the mailer to use */ + char *m_mtatype; /* type of this MTA */ + char *m_addrtype; /* type for addresses */ + char *m_diagtype; /* type for diagnostics */ + BITMAP m_flags; /* status flags, see below */ + short m_mno; /* mailer number internally */ + short m_nice; /* niceness to run at (mostly for prog) */ + char **m_argv; /* template argument vector */ + short m_sh_rwset; /* rewrite set: sender header addresses */ + short m_se_rwset; /* rewrite set: sender envelope addresses */ + short m_rh_rwset; /* rewrite set: recipient header addresses */ + short m_re_rwset; /* rewrite set: recipient envelope addresses */ + char *m_eol; /* end of line string */ + long m_maxsize; /* size limit on message to this mailer */ + int m_linelimit; /* max # characters per line */ + char *m_execdir; /* directory to chdir to before execv */ + uid_t m_uid; /* UID to run as */ + gid_t m_gid; /* GID to run as */ + char *m_defcharset; /* default character set */ +}; + +/* bits for m_flags */ +# define M_ESMTP 'a' /* run Extended SMTP protocol */ +# define M_ALIASABLE 'A' /* user can be LHS of an alias */ +# define M_BLANKEND 'b' /* ensure blank line at end of message */ +# define M_NOCOMMENT 'c' /* don't include comment part of address */ +# define M_CANONICAL 'C' /* make addresses canonical "u@dom" */ +# define M_NOBRACKET 'd' /* never angle bracket envelope route-addrs */ + /* 'D' /* CF: include Date: */ +# define M_EXPENSIVE 'e' /* it costs to use this mailer.... */ +# define M_ESCFROM 'E' /* escape From lines to >From */ +# define M_FOPT 'f' /* mailer takes picky -f flag */ + /* 'F' /* CF: include From: or Resent-From: */ +# define M_NO_NULL_FROM 'g' /* sender of errors should be $g */ +# define M_HST_UPPER 'h' /* preserve host case distinction */ +# define M_PREHEAD 'H' /* MAIL11V3: preview headers */ +# define M_UDBENVELOPE 'i' /* do udbsender rewriting on envelope */ +# define M_INTERNAL 'I' /* SMTP to another sendmail site */ +# define M_UDBRECIPIENT 'j' /* do udbsender rewriting on recipient lines */ +# define M_NOLOOPCHECK 'k' /* don't check for loops in HELO command */ +# define M_LOCALMAILER 'l' /* delivery is to this host */ +# define M_LIMITS 'L' /* must enforce SMTP line limits */ +# define M_MUSER 'm' /* can handle multiple users at once */ + /* 'M' /* CF: include Message-Id: */ +# define M_NHDR 'n' /* don't insert From line */ +# define M_MANYSTATUS 'N' /* MAIL11V3: DATA returns multi-status */ +# define M_RUNASRCPT 'o' /* always run mailer as recipient */ +# define M_FROMPATH 'p' /* use reverse-path in MAIL FROM: */ + /* 'P' /* CF: include Return-Path: */ +# define M_ROPT 'r' /* mailer takes picky -r flag */ +# define M_SECURE_PORT 'R' /* try to send on a reserved TCP port */ +# define M_STRIPQ 's' /* strip quote chars from user/host */ +# define M_SPECIFIC_UID 'S' /* run as specific uid/gid */ +# define M_USR_UPPER 'u' /* preserve user case distinction */ +# define M_UGLYUUCP 'U' /* this wants an ugly UUCP from line */ +# define M_CONTENT_LEN 'v' /* add Content-Length: header (SVr4) */ + /* 'V' /* UIUC: !-relativize all addresses */ +# define M_HASPWENT 'w' /* check for /etc/passwd entry */ + /* 'x' /* CF: include Full-Name: */ +# define M_XDOT 'X' /* use hidden-dot algorithm */ +# define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */ +# define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */ +# define M_7BITS '7' /* use 7-bit path */ +# define M_8BITS '8' /* force "just send 8" behaviour */ +# define M_MAKE8BIT '9' /* convert 7 -> 8 bit if appropriate */ +# define M_CHECKINCLUDE ':' /* check for :include: files */ +# define M_CHECKPROG '|' /* check for |program addresses */ +# define M_CHECKFILE '/' /* check for /file addresses */ +# define M_CHECKUDB '@' /* user can be user database key */ + +EXTERN MAILER *Mailer[MAXMAILERS+1]; + +EXTERN MAILER *LocalMailer; /* ptr to local mailer */ +EXTERN MAILER *ProgMailer; /* ptr to program mailer */ +EXTERN MAILER *FileMailer; /* ptr to *file* mailer */ +EXTERN MAILER *InclMailer; /* ptr to *include* mailer */ +/* +** Header structure. +** This structure is used internally to store header items. +*/ + +struct header +{ + char *h_field; /* the name of the field */ + char *h_value; /* the value of that field */ + struct header *h_link; /* the next header */ + u_short h_flags; /* status bits, see below */ + BITMAP h_mflags; /* m_flags bits needed */ +}; + +typedef struct header HDR; + +/* +** Header information structure. +** Defined in conf.c, this struct declares the header fields +** that have some magic meaning. +*/ + +struct hdrinfo +{ + char *hi_field; /* the name of the field */ + u_short hi_flags; /* status bits, see below */ +}; + +extern struct hdrinfo HdrInfo[]; + +/* bits for h_flags and hi_flags */ +# define H_EOH 0x0001 /* this field terminates header */ +# define H_RCPT 0x0002 /* contains recipient addresses */ +# define H_DEFAULT 0x0004 /* if another value is found, drop this */ +# define H_RESENT 0x0008 /* this address is a "Resent-..." address */ +# define H_CHECK 0x0010 /* check h_mflags against m_flags */ +# define H_ACHECK 0x0020 /* ditto, but always (not just default) */ +# define H_FORCE 0x0040 /* force this field, even if default */ +# define H_TRACE 0x0080 /* this field contains trace information */ +# define H_FROM 0x0100 /* this is a from-type field */ +# define H_VALID 0x0200 /* this field has a validated value */ +# define H_RECEIPTTO 0x0400 /* this field has return receipt info */ +# define H_ERRORSTO 0x0800 /* this field has error address info */ +# define H_CTE 0x1000 /* this field is a content-transfer-encoding */ +# define H_CTYPE 0x2000 /* this is a content-type field */ +# define H_BCC 0x4000 /* Bcc: header: strip value or delete */ +/* +** Information about currently open connections to mailers, or to +** hosts that we have looked up recently. +*/ + +# define MCI struct mailer_con_info + +MCI +{ + short mci_flags; /* flag bits, see below */ + short mci_errno; /* error number on last connection */ + short mci_herrno; /* h_errno from last DNS lookup */ + short mci_exitstat; /* exit status from last connection */ + short mci_state; /* SMTP state */ + long mci_maxsize; /* max size this server will accept */ + FILE *mci_in; /* input side of connection */ + FILE *mci_out; /* output side of connection */ + int mci_pid; /* process id of subordinate proc */ + char *mci_phase; /* SMTP phase string */ + struct mailer *mci_mailer; /* ptr to the mailer for this conn */ + char *mci_host; /* host name */ + char *mci_status; /* DSN status to be copied to addrs */ + time_t mci_lastuse; /* last usage time */ +}; + + +/* flag bits */ +#define MCIF_VALID 0x0001 /* this entry is valid */ +#define MCIF_TEMP 0x0002 /* don't cache this connection */ +#define MCIF_CACHED 0x0004 /* currently in open cache */ +#define MCIF_ESMTP 0x0008 /* this host speaks ESMTP */ +#define MCIF_EXPN 0x0010 /* EXPN command supported */ +#define MCIF_SIZE 0x0020 /* SIZE option supported */ +#define MCIF_8BITMIME 0x0040 /* BODY=8BITMIME supported */ +#define MCIF_7BIT 0x0080 /* strip this message to 7 bits */ +#define MCIF_MULTSTAT 0x0100 /* MAIL11V3: handles MULT status */ +#define MCIF_INHEADER 0x0200 /* currently outputing header */ +#define MCIF_CVT8TO7 0x0400 /* convert from 8 to 7 bits */ +#define MCIF_DSN 0x0800 /* DSN extension supported */ +#define MCIF_8BITOK 0x1000 /* OK to send 8 bit characters */ +#define MCIF_CVT7TO8 0x2000 /* convert from 7 to 8 bits */ +#define MCIF_INMIME 0x4000 /* currently reading MIME header */ + +/* states */ +#define MCIS_CLOSED 0 /* no traffic on this connection */ +#define MCIS_OPENING 1 /* sending initial protocol */ +#define MCIS_OPEN 2 /* open, initial protocol sent */ +#define MCIS_ACTIVE 3 /* message being sent */ +#define MCIS_QUITING 4 /* running quit protocol */ +#define MCIS_SSD 5 /* service shutting down */ +#define MCIS_ERROR 6 /* I/O error on connection */ + +/* functions */ +extern MCI *mci_get __P((char *, MAILER *)); +extern void mci_cache __P((MCI *)); +extern void mci_flush __P((bool, MCI *)); +/* +** Envelope structure. +** This structure defines the message itself. There is usually +** only one of these -- for the message that we originally read +** and which is our primary interest -- but other envelopes can +** be generated during processing. For example, error messages +** will have their own envelope. +*/ + +struct envelope +{ + HDR *e_header; /* head of header list */ + long e_msgpriority; /* adjusted priority of this message */ + time_t e_ctime; /* time message appeared in the queue */ + char *e_to; /* the target person */ + char *e_receiptto; /* return receipt address */ + ADDRESS e_from; /* the person it is from */ + char *e_sender; /* e_from.q_paddr w comments stripped */ + char **e_fromdomain; /* the domain part of the sender */ + ADDRESS *e_sendqueue; /* list of message recipients */ + ADDRESS *e_errorqueue; /* the queue for error responses */ + long e_msgsize; /* size of the message in bytes */ + long e_flags; /* flags, see below */ + int e_nrcpts; /* number of recipients */ + short e_class; /* msg class (priority, junk, etc.) */ + short e_hopcount; /* number of times processed */ + short e_nsent; /* number of sends since checkpoint */ + short e_sendmode; /* message send mode */ + short e_errormode; /* error return mode */ + short e_timeoutclass; /* message timeout class */ + void (*e_puthdr)__P((MCI *, HDR *, ENVELOPE *)); + /* function to put header of message */ + void (*e_putbody)__P((MCI *, ENVELOPE *, char *)); + /* function to put body of message */ + struct envelope *e_parent; /* the message this one encloses */ + struct envelope *e_sibling; /* the next envelope of interest */ + char *e_bodytype; /* type of message body */ + FILE *e_dfp; /* temporary file */ + char *e_id; /* code for this entry in queue */ + FILE *e_xfp; /* transcript file */ + FILE *e_lockfp; /* the lock file for this message */ + char *e_message; /* error message */ + char *e_statmsg; /* stat msg (changes per delivery) */ + char *e_msgboundary; /* MIME-style message part boundary */ + char *e_origrcpt; /* original recipient (one only) */ + char *e_envid; /* envelope id from MAIL FROM: line */ + char *e_status; /* DSN status for this message */ + time_t e_dtime; /* time of last delivery attempt */ + int e_ntries; /* number of delivery attempts */ + dev_t e_dfdev; /* df file's device, for crash recov */ + ino_t e_dfino; /* df file's ino, for crash recovery */ + char *e_macro[256]; /* macro definitions */ +}; + +/* values for e_flags */ +#define EF_OLDSTYLE 0x0000001 /* use spaces (not commas) in hdrs */ +#define EF_INQUEUE 0x0000002 /* this message is fully queued */ +#define EF_NO_BODY_RETN 0x0000004 /* omit message body on error */ +#define EF_CLRQUEUE 0x0000008 /* disk copy is no longer needed */ +#define EF_SENDRECEIPT 0x0000010 /* send a return receipt */ +#define EF_FATALERRS 0x0000020 /* fatal errors occured */ +#define EF_DELETE_BCC 0x0000040 /* delete Bcc: headers entirely */ +#define EF_RESPONSE 0x0000080 /* this is an error or return receipt */ +#define EF_RESENT 0x0000100 /* this message is being forwarded */ +#define EF_VRFYONLY 0x0000200 /* verify only (don't expand aliases) */ +#define EF_WARNING 0x0000400 /* warning message has been sent */ +#define EF_QUEUERUN 0x0000800 /* this envelope is from queue */ +#define EF_GLOBALERRS 0x0001000 /* treat errors as global */ +#define EF_PM_NOTIFY 0x0002000 /* send return mail to postmaster */ +#define EF_METOO 0x0004000 /* send to me too */ +#define EF_LOGSENDER 0x0008000 /* need to log the sender */ +#define EF_NORECEIPT 0x0010000 /* suppress all return-receipts */ +#define EF_HAS8BIT 0x0020000 /* at least one 8-bit char in body */ +#define EF_NL_NOT_EOL 0x0040000 /* don't accept raw NL as EOLine */ +#define EF_CRLF_NOT_EOL 0x0080000 /* don't accept CR-LF as EOLine */ +#define EF_RET_PARAM 0x0100000 /* RCPT command had RET argument */ +#define EF_HAS_DF 0x0200000 /* set when df file is instantiated */ +#define EF_IS_MIME 0x0400000 /* really is a MIME message */ +#define EF_DONT_MIME 0x0800000 /* never MIME this message */ + +EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */ + +/* functions */ +extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *)); +extern void dropenvelope __P((ENVELOPE *)); +extern void clearenvelope __P((ENVELOPE *, bool)); + +extern void putheader __P((MCI *, HDR *, ENVELOPE *)); +extern void putbody __P((MCI *, ENVELOPE *, char *)); +/* +** Message priority classes. +** +** The message class is read directly from the Priority: header +** field in the message. +** +** CurEnv->e_msgpriority is the number of bytes in the message plus +** the creation time (so that jobs ``tend'' to be ordered correctly), +** adjusted by the message class, the number of recipients, and the +** amount of time the message has been sitting around. This number +** is used to order the queue. Higher values mean LOWER priority. +** +** Each priority class point is worth WkClassFact priority points; +** each recipient is worth WkRecipFact priority points. Each time +** we reprocess a message the priority is adjusted by WkTimeFact. +** WkTimeFact should normally decrease the priority so that jobs +** that have historically failed will be run later; thanks go to +** Jay Lepreau at Utah for pointing out the error in my thinking. +** +** The "class" is this number, unadjusted by the age or size of +** this message. Classes with negative representations will have +** error messages thrown away if they are not local. +*/ + +struct priority +{ + char *pri_name; /* external name of priority */ + int pri_val; /* internal value for same */ +}; + +EXTERN struct priority Priorities[MAXPRIORITIES]; +EXTERN int NumPriorities; /* pointer into Priorities */ +/* +** Rewrite rules. +*/ + +struct rewrite +{ + char **r_lhs; /* pattern match */ + char **r_rhs; /* substitution value */ + struct rewrite *r_next;/* next in chain */ +}; + +EXTERN struct rewrite *RewriteRules[MAXRWSETS]; + +/* +** Special characters in rewriting rules. +** These are used internally only. +** The COND* rules are actually used in macros rather than in +** rewriting rules, but are given here because they +** cannot conflict. +*/ + +/* left hand side items */ +# define MATCHZANY ((u_char)0220) /* match zero or more tokens */ +# define MATCHANY ((u_char)0221) /* match one or more tokens */ +# define MATCHONE ((u_char)0222) /* match exactly one token */ +# define MATCHCLASS ((u_char)0223) /* match one token in a class */ +# define MATCHNCLASS ((u_char)0224) /* match anything not in class */ +# define MATCHREPL ((u_char)0225) /* replacement on RHS for above */ + +/* right hand side items */ +# define CANONNET ((u_char)0226) /* canonical net, next token */ +# define CANONHOST ((u_char)0227) /* canonical host, next token */ +# define CANONUSER ((u_char)0230) /* canonical user, next N tokens */ +# define CALLSUBR ((u_char)0231) /* call another rewriting set */ + +/* conditionals in macros */ +# define CONDIF ((u_char)0232) /* conditional if-then */ +# define CONDELSE ((u_char)0233) /* conditional else */ +# define CONDFI ((u_char)0234) /* conditional fi */ + +/* bracket characters for host name lookup */ +# define HOSTBEGIN ((u_char)0235) /* hostname lookup begin */ +# define HOSTEND ((u_char)0236) /* hostname lookup end */ + +/* bracket characters for generalized lookup */ +# define LOOKUPBEGIN ((u_char)0205) /* generalized lookup begin */ +# define LOOKUPEND ((u_char)0206) /* generalized lookup end */ + +/* macro substitution character */ +# define MACROEXPAND ((u_char)0201) /* macro expansion */ +# define MACRODEXPAND ((u_char)0202) /* deferred macro expansion */ + +/* to make the code clearer */ +# define MATCHZERO CANONHOST + +/* external <==> internal mapping table */ +struct metamac +{ + char metaname; /* external code (after $) */ + u_char metaval; /* internal code (as above) */ +}; + +/* values for macros with external names only */ +# define MID_OPMODE 0202 /* operation mode */ + +/* functions */ +extern void expand __P((char *, char *, size_t, ENVELOPE *)); +extern void define __P((int, char *, ENVELOPE *)); +extern char *macvalue __P((int, ENVELOPE *)); +extern char *macname __P((int)); +extern int macid __P((char *, char **)); +/* +** Name canonification short circuit. +** +** If the name server for a host is down, the process of trying to +** canonify the name can hang. This is similar to (but alas, not +** identical to) looking up the name for delivery. This stab type +** caches the result of the name server lookup so we don't hang +** multiple times. +*/ + +#define NAMECANON struct _namecanon + +NAMECANON +{ + short nc_errno; /* cached errno */ + short nc_herrno; /* cached h_errno */ + short nc_stat; /* cached exit status code */ + short nc_flags; /* flag bits */ + char *nc_cname; /* the canonical name */ +}; + +/* values for nc_flags */ +#define NCF_VALID 0x0001 /* entry valid */ +/* +** Mapping functions +** +** These allow arbitrary mappings in the config file. The idea +** (albeit not the implementation) comes from IDA sendmail. +*/ + +# define MAPCLASS struct _mapclass +# define MAP struct _map +# define MAXMAPACTIONS 3 /* size of map_actions array */ + + +/* +** An actual map. +*/ + +MAP +{ + MAPCLASS *map_class; /* the class of this map */ + char *map_mname; /* name of this map */ + long map_mflags; /* flags, see below */ + char *map_file; /* the (nominal) filename */ + ARBPTR_T map_db1; /* the open database ptr */ + ARBPTR_T map_db2; /* an "extra" database pointer */ + char *map_keycolnm; /* key column name */ + char *map_valcolnm; /* value column name */ + u_char map_keycolno; /* key column number */ + u_char map_valcolno; /* value column number */ + char map_coldelim; /* column delimiter */ + char *map_app; /* to append to successful matches */ + char *map_domain; /* the (nominal) NIS domain */ + char *map_rebuild; /* program to run to do auto-rebuild */ + time_t map_mtime; /* last database modification time */ + short map_specificity; /* specificity of alaases */ + MAP *map_stack[MAXMAPSTACK]; /* list for stacked maps */ + short map_return[MAXMAPACTIONS]; /* return bitmaps for stacked maps */ +}; + +/* bit values for map_mflags */ +# define MF_VALID 0x00000001 /* this entry is valid */ +# define MF_INCLNULL 0x00000002 /* include null byte in key */ +# define MF_OPTIONAL 0x00000004 /* don't complain if map not found */ +# define MF_NOFOLDCASE 0x00000008 /* don't fold case in keys */ +# define MF_MATCHONLY 0x00000010 /* don't use the map value */ +# define MF_OPEN 0x00000020 /* this entry is open */ +# define MF_WRITABLE 0x00000040 /* open for writing */ +# define MF_ALIAS 0x00000080 /* this is an alias file */ +# define MF_TRY0NULL 0x00000100 /* try with no null byte */ +# define MF_TRY1NULL 0x00000200 /* try with the null byte */ +# define MF_LOCKED 0x00000400 /* this map is currently locked */ +# define MF_ALIASWAIT 0x00000800 /* alias map in aliaswait state */ +# define MF_IMPL_HASH 0x00001000 /* implicit: underlying hash database */ +# define MF_IMPL_NDBM 0x00002000 /* implicit: underlying NDBM database */ +# define MF_UNSAFEDB 0x00004000 /* this map is world writable */ +# define MF_APPEND 0x00008000 /* append new entry on rebuiled */ +# define MF_KEEPQUOTES 0x00010000 /* don't dequote key before lookup */ + +/* indices for map_actions */ +# define MA_NOTFOUND 0 /* member map returned "not found" */ +# define MA_UNAVAIL 1 /* member map is not available */ +# define MA_TRYAGAIN 2 /* member map returns temp failure */ + +/* +** The class of a map -- essentially the functions to call +*/ + +MAPCLASS +{ + char *map_cname; /* name of this map class */ + char *map_ext; /* extension for database file */ + short map_cflags; /* flag bits, see below */ + bool (*map_parse)__P((MAP *, char *)); + /* argument parsing function */ + char *(*map_lookup)__P((MAP *, char *, char **, int *)); + /* lookup function */ + void (*map_store)__P((MAP *, char *, char *)); + /* store function */ + bool (*map_open)__P((MAP *, int)); + /* open function */ + void (*map_close)__P((MAP *)); + /* close function */ +}; + +/* bit values for map_cflags */ +#define MCF_ALIASOK 0x0001 /* can be used for aliases */ +#define MCF_ALIASONLY 0x0002 /* usable only for aliases */ +#define MCF_REBUILDABLE 0x0004 /* can rebuild alias files */ +#define MCF_OPTFILE 0x0008 /* file name is optional */ + +/* functions */ +extern char *map_rewrite __P((MAP *, char *, int, char **)); +extern MAP *makemapentry __P((char *)); +/* +** Symbol table definitions +*/ + +struct symtab +{ + char *s_name; /* name to be entered */ + char s_type; /* general type (see below) */ + struct symtab *s_next; /* pointer to next in chain */ + union + { + BITMAP sv_class; /* bit-map of word classes */ + ADDRESS *sv_addr; /* pointer to address header */ + MAILER *sv_mailer; /* pointer to mailer */ + char *sv_alias; /* alias */ + MAPCLASS sv_mapclass; /* mapping function class */ + MAP sv_map; /* mapping function */ + char *sv_hostsig; /* host signature */ + MCI sv_mci; /* mailer connection info */ + NAMECANON sv_namecanon; /* canonical name cache */ + int sv_macro; /* macro name => id mapping */ + int sv_ruleset; /* ruleset index */ + } s_value; +}; + +typedef struct symtab STAB; + +/* symbol types */ +# define ST_UNDEF 0 /* undefined type */ +# define ST_CLASS 1 /* class map */ +# define ST_ADDRESS 2 /* an address in parsed format */ +# define ST_MAILER 3 /* a mailer header */ +# define ST_ALIAS 4 /* an alias */ +# define ST_MAPCLASS 5 /* mapping function class */ +# define ST_MAP 6 /* mapping function */ +# define ST_HOSTSIG 7 /* host signature */ +# define ST_NAMECANON 8 /* cached canonical name */ +# define ST_MACRO 9 /* macro name to id mapping */ +# define ST_RULESET 10 /* ruleset index */ +# define ST_MCI 16 /* mailer connection info (offset) */ + +# define s_class s_value.sv_class +# define s_address s_value.sv_addr +# define s_mailer s_value.sv_mailer +# define s_alias s_value.sv_alias +# define s_mci s_value.sv_mci +# define s_mapclass s_value.sv_mapclass +# define s_hostsig s_value.sv_hostsig +# define s_map s_value.sv_map +# define s_namecanon s_value.sv_namecanon +# define s_macro s_value.sv_macro +# define s_ruleset s_value.sv_ruleset + +extern STAB *stab __P((char *, int, int)); +extern void stabapply __P((void (*)(STAB *, int), int)); + +/* opcodes to stab */ +# define ST_FIND 0 /* find entry */ +# define ST_ENTER 1 /* enter if not there */ +/* +** STRUCT EVENT -- event queue. +** +** Maintained in sorted order. +** +** We store the pid of the process that set this event to insure +** that when we fork we will not take events intended for the parent. +*/ + +struct event +{ + time_t ev_time; /* time of the function call */ + void (*ev_func)__P((int)); + /* function to call */ + int ev_arg; /* argument to ev_func */ + int ev_pid; /* pid that set this event */ + struct event *ev_link; /* link to next item */ +}; + +typedef struct event EVENT; + +EXTERN EVENT *EventQueue; /* head of event queue */ + +/* functions */ +extern EVENT *setevent __P((time_t, void(*)(), int)); +extern void clrevent __P((EVENT *)); +/* +** Operation, send, error, and MIME modes +** +** The operation mode describes the basic operation of sendmail. +** This can be set from the command line, and is "send mail" by +** default. +** +** The send mode tells how to send mail. It can be set in the +** configuration file. It's setting determines how quickly the +** mail will be delivered versus the load on your system. If the +** -v (verbose) flag is given, it will be forced to SM_DELIVER +** mode. +** +** The error mode tells how to return errors. +*/ + +EXTERN char OpMode; /* operation mode, see below */ + +#define MD_DELIVER 'm' /* be a mail sender */ +#define MD_SMTP 's' /* run SMTP on standard input */ +#define MD_ARPAFTP 'a' /* obsolete ARPANET mode (Grey Book) */ +#define MD_DAEMON 'd' /* run as a daemon */ +#define MD_VERIFY 'v' /* verify: don't collect or deliver */ +#define MD_TEST 't' /* test mode: resolve addrs only */ +#define MD_INITALIAS 'i' /* initialize alias database */ +#define MD_PRINT 'p' /* print the queue */ +#define MD_FREEZE 'z' /* freeze the configuration file */ + + +/* values for e_sendmode -- send modes */ +#define SM_DELIVER 'i' /* interactive delivery */ +#define SM_FORK 'b' /* deliver in background */ +#define SM_QUEUE 'q' /* queue, don't deliver */ +#define SM_DEFER 'd' /* defer map lookups as well as queue */ +#define SM_VERIFY 'v' /* verify only (used internally) */ + +/* used only as a parameter to sendall */ +#define SM_DEFAULT '\0' /* unspecified, use SendMode */ + + +/* values for e_errormode -- error handling modes */ +#define EM_PRINT 'p' /* print errors */ +#define EM_MAIL 'm' /* mail back errors */ +#define EM_WRITE 'w' /* write back errors */ +#define EM_BERKNET 'e' /* special berknet processing */ +#define EM_QUIET 'q' /* don't print messages (stat only) */ + + +/* MIME processing mode */ +EXTERN int MimeMode; + +/* bit values for MimeMode */ +#define MM_CVTMIME 0x0001 /* convert 8 to 7 bit MIME */ +#define MM_PASS8BIT 0x0002 /* just send 8 bit data blind */ +#define MM_MIME8BIT 0x0004 /* convert 8-bit data to MIME */ + +/* queue sorting order algorithm */ +EXTERN int QueueSortOrder; + +#define QS_BYPRIORITY 0 /* sort by message priority */ +#define QS_BYHOST 1 /* sort by first host name */ + + +/* how to handle messages without any recipient addresses */ +EXTERN int NoRecipientAction; + +#define NRA_NO_ACTION 0 /* just leave it as is */ +#define NRA_ADD_TO 1 /* add To: header */ +#define NRA_ADD_APPARENTLY_TO 2 /* add Apparently-To: header */ +#define NRA_ADD_BCC 3 /* add empty Bcc: header */ +#define NRA_ADD_TO_UNDISCLOSED 4 /* add To: undisclosed:; header */ + + +/* flags to putxline */ +#define PXLF_NOTHINGSPECIAL 0 /* no special mapping */ +#define PXLF_MAPFROM 0x0001 /* map From_ to >From_ */ +#define PXLF_STRIP8BIT 0x0002 /* strip 8th bit *e +/* +** Additional definitions +*/ + + +/* +** Privacy flags +** These are bit values for the PrivacyFlags word. +*/ + +#define PRIV_PUBLIC 0 /* what have I got to hide? */ +#define PRIV_NEEDMAILHELO 0x0001 /* insist on HELO for MAIL, at least */ +#define PRIV_NEEDEXPNHELO 0x0002 /* insist on HELO for EXPN */ +#define PRIV_NEEDVRFYHELO 0x0004 /* insist on HELO for VRFY */ +#define PRIV_NOEXPN 0x0008 /* disallow EXPN command entirely */ +#define PRIV_NOVRFY 0x0010 /* disallow VRFY command entirely */ +#define PRIV_AUTHWARNINGS 0x0020 /* flag possible authorization probs */ +#define PRIV_NORECEIPTS 0x0040 /* disallow return receipts */ +#define PRIV_RESTRICTMAILQ 0x1000 /* restrict mailq command */ +#define PRIV_RESTRICTQRUN 0x2000 /* restrict queue run */ +#define PRIV_GOAWAY 0x0fff /* don't give no info, anyway, anyhow */ + +/* struct defining such things */ +struct prival +{ + char *pv_name; /* name of privacy flag */ + int pv_flag; /* numeric level */ +}; + + +/* +** Flags passed to remotename, parseaddr, allocaddr, and buildaddr. +*/ + +#define RF_SENDERADDR 0x001 /* this is a sender address */ +#define RF_HEADERADDR 0x002 /* this is a header address */ +#define RF_CANONICAL 0x004 /* strip comment information */ +#define RF_ADDDOMAIN 0x008 /* OK to do domain extension */ +#define RF_COPYPARSE 0x010 /* copy parsed user & host */ +#define RF_COPYPADDR 0x020 /* copy print address */ +#define RF_COPYALL (RF_COPYPARSE|RF_COPYPADDR) +#define RF_COPYNONE 0 + + +/* +** Flags passed to safefile. +*/ + +#define SFF_ANYFILE 0 /* no special restrictions */ +#define SFF_MUSTOWN 0x0001 /* user must own this file */ +#define SFF_NOSLINK 0x0002 /* file cannot be a symbolic link */ +#define SFF_ROOTOK 0x0004 /* ok for root to own this file */ +#define SFF_RUNASREALUID 0x0008 /* if no ctladdr, run as real uid */ +#define SFF_NOPATHCHECK 0x0010 /* don't bother checking dir path */ +#define SFF_SETUIDOK 0x0020 /* setuid files are ok */ +#define SFF_CREAT 0x0040 /* ok to create file if necessary */ +#define SFF_REGONLY 0x0080 /* regular files only */ + +/* flags that are actually specific to safefopen */ +#define SFF_OPENASROOT 0x1000 /* open as root instead of real user */ + + +/* +** Flags passed to mime8to7. +*/ + +#define M87F_OUTER 0 /* outer context */ +#define M87F_NO8BIT 0x0001 /* can't have 8-bit in this section */ +#define M87F_DIGEST 0x0002 /* processing multipart/digest */ + + +/* +** Regular UNIX sockaddrs are too small to handle ISO addresses, so +** we are forced to declare a supertype here. +*/ + +#ifdef DAEMON +union bigsockaddr +{ + struct sockaddr sa; /* general version */ +#if NETUNIX + struct sockaddr_un sunix; /* UNIX family */ +#endif +#if NETINET + struct sockaddr_in sin; /* INET family */ +#endif +#if NETISO + struct sockaddr_iso siso; /* ISO family */ +#endif +#if NETNS + struct sockaddr_ns sns; /* XNS family */ +#endif +#if NETX25 + struct sockaddr_x25 sx25; /* X.25 family */ +#endif +}; + +#define SOCKADDR union bigsockaddr + +EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */ +extern char *anynet_ntoa __P((SOCKADDR *)); + +#endif + + +/* +** Vendor codes +** +** Vendors can customize sendmail to add special behaviour, +** generally for back compatibility. Ideally, this should +** be set up in the .cf file using the "V" command. However, +** it's quite reasonable for some vendors to want the default +** be their old version; this can be set using +** -DVENDOR_DEFAULT=VENDOR_xxx +** in the Makefile. +** +** Vendors should apply to sendmail@CS.Berkeley.EDU for +** unique vendor codes. +*/ + +#define VENDOR_BERKELEY 1 /* Berkeley-native configuration file */ +#define VENDOR_SUN 2 /* Sun-native configuration file */ +#define VENDOR_HP 3 /* Hewlett-Packard specific config syntax */ +#define VENDOR_IBM 4 /* IBM specific config syntax */ + +EXTERN int VendorCode; /* vendor-specific operation enhancements */ +/* +** Global variables. +*/ + +EXTERN bool FromFlag; /* if set, "From" person is explicit */ +EXTERN bool MeToo; /* send to the sender also */ +EXTERN bool IgnrDot; /* don't let dot end messages */ +EXTERN bool SaveFrom; /* save leading "From" lines */ +EXTERN bool Verbose; /* set if blow-by-blow desired */ +EXTERN bool GrabTo; /* if set, get recipients from msg */ +EXTERN bool SuprErrs; /* set if we are suppressing errors */ +EXTERN bool HoldErrs; /* only output errors to transcript */ +EXTERN bool NoConnect; /* don't connect to non-local mailers */ +EXTERN bool SuperSafe; /* be extra careful, even if expensive */ +EXTERN bool ForkQueueRuns; /* fork for each job when running the queue */ +EXTERN bool AutoRebuild; /* auto-rebuild the alias database as needed */ +EXTERN bool CheckAliases; /* parse addresses during newaliases */ +EXTERN bool NoAlias; /* suppress aliasing */ +EXTERN bool UseNameServer; /* using DNS -- interpret h_errno & MX RRs */ +EXTERN bool UseHesiod; /* using Hesiod -- interpret Hesiod errors */ +EXTERN bool SevenBitInput; /* force 7-bit data on input */ +EXTERN bool HasEightBits; /* has at least one eight bit input byte */ +EXTERN time_t SafeAlias; /* interval to wait until @:@ in alias file */ +EXTERN FILE *InChannel; /* input connection */ +EXTERN FILE *OutChannel; /* output connection */ +EXTERN char *RealUserName; /* real user name of caller */ +EXTERN uid_t RealUid; /* real uid of caller */ +EXTERN gid_t RealGid; /* real gid of caller */ +EXTERN uid_t DefUid; /* default uid to run as */ +EXTERN gid_t DefGid; /* default gid to run as */ +EXTERN char *DefUser; /* default user to run as (from DefUid) */ +EXTERN int OldUmask; /* umask when sendmail starts up */ +EXTERN int Errors; /* set if errors (local to single pass) */ +EXTERN int ExitStat; /* exit status code */ +EXTERN int LineNumber; /* line number in current input */ +EXTERN int LogLevel; /* level of logging to perform */ +EXTERN int FileMode; /* mode on files */ +EXTERN int QueueLA; /* load average starting forced queueing */ +EXTERN int RefuseLA; /* load average refusing connections are */ +EXTERN int CurrentLA; /* current load average */ +EXTERN long QueueFactor; /* slope of queue function */ +EXTERN time_t QueueIntvl; /* intervals between running the queue */ +EXTERN char *HelpFile; /* location of SMTP help file */ +EXTERN char *ErrMsgFile; /* file to prepend to all error messages */ +EXTERN char *StatFile; /* location of statistics summary */ +EXTERN char *QueueDir; /* location of queue directory */ +EXTERN char *FileName; /* name to print on error messages */ +EXTERN char *SmtpPhase; /* current phase in SMTP processing */ +EXTERN char *MyHostName; /* name of this host for SMTP messages */ +EXTERN char *RealHostName; /* name of host we are talking to */ +EXTERN char *CurHostName; /* current host we are dealing with */ +EXTERN jmp_buf TopFrame; /* branch-to-top-of-loop-on-error frame */ +EXTERN bool QuickAbort; /* .... but only if we want a quick abort */ +EXTERN bool LogUsrErrs; /* syslog user errors (e.g., SMTP RCPT cmd) */ +EXTERN bool SendMIMEErrors; /* send error messages in MIME format */ +EXTERN bool MatchGecos; /* look for user names in gecos field */ +EXTERN bool UseErrorsTo; /* use Errors-To: header (back compat) */ +EXTERN bool TryNullMXList; /* if we are the best MX, try host directly */ +EXTERN bool InChild; /* true if running in an SMTP subprocess */ +EXTERN bool DisConnected; /* running with OutChannel redirected to xf */ +EXTERN bool ColonOkInAddr; /* single colon legal in address */ +EXTERN bool HasWildcardMX; /* don't use MX records when canonifying */ +EXTERN char SpaceSub; /* substitution for <lwsp> */ +EXTERN int PrivacyFlags; /* privacy flags */ +EXTERN char *ConfFile; /* location of configuration file [conf.c] */ +extern char *PidFile; /* location of proc id file [conf.c] */ +extern ADDRESS NullAddress; /* a null (template) address [main.c] */ +EXTERN long WkClassFact; /* multiplier for message class -> priority */ +EXTERN long WkRecipFact; /* multiplier for # of recipients -> priority */ +EXTERN long WkTimeFact; /* priority offset each time this job is run */ +EXTERN char *UdbSpec; /* user database source spec */ +EXTERN int MaxHopCount; /* max # of hops until bounce */ +EXTERN int ConfigLevel; /* config file level */ +EXTERN char *TimeZoneSpec; /* override time zone specification */ +EXTERN char *ForwardPath; /* path to search for .forward files */ +EXTERN long MinBlocksFree; /* min # of blocks free on queue fs */ +EXTERN char *FallBackMX; /* fall back MX host */ +EXTERN long MaxMessageSize; /* advertised max size we will accept */ +EXTERN time_t MaxHostStatAge; /* max age of cached host status info */ +EXTERN time_t MinQueueAge; /* min delivery interval */ +EXTERN time_t DialDelay; /* delay between dial-on-demand tries */ +EXTERN char *SafeFileEnv; /* chroot location for file delivery */ +EXTERN char *HostsFile; /* path to /etc/hosts file */ +EXTERN int MaxQueueRun; /* maximum number of jobs in one queue run */ +EXTERN int MaxChildren; /* maximum number of daemonic children */ +EXTERN int CurChildren; /* current number of daemonic children */ +EXTERN char *SmtpGreeting; /* SMTP greeting message (old $e macro) */ +EXTERN char *UnixFromLine; /* UNIX From_ line (old $l macro) */ +EXTERN char *OperatorChars; /* operators (old $o macro) */ +EXTERN bool DontInitGroups; /* avoid initgroups() because of NIS cost */ +EXTERN bool SingleLineFromHeader; /* force From: header to be one line */ +EXTERN int MaxAliasRecursion; /* maximum depth of alias recursion */ +EXTERN int MaxRuleRecursion; /* maximum depth of ruleset recursion */ +EXTERN char *MustQuoteChars; /* quote these characters in phrases */ +EXTERN char *ServiceSwitchFile; /* backup service switch */ +EXTERN char *DefaultCharSet; /* default character set for MIME */ +EXTERN int DeliveryNiceness; /* how nice to be during delivery */ +EXTERN char *PostMasterCopy; /* address to get errs cc's */ +EXTERN int CheckpointInterval; /* queue file checkpoint interval */ +EXTERN bool DontPruneRoutes; /* don't prune source routes */ +EXTERN bool DontExpandCnames; /* do not $[...$] expand CNAMEs */ +EXTERN int MaxMciCache; /* maximum entries in MCI cache */ +EXTERN time_t MciCacheTimeout; /* maximum idle time on connections */ +EXTERN time_t MciInfoTimeout; /* how long 'til we retry down hosts */ +EXTERN char *QueueLimitRecipient; /* limit queue runs to this recipient */ +EXTERN char *QueueLimitSender; /* limit queue runs to this sender */ +EXTERN char *QueueLimitId; /* limit queue runs to this id */ +EXTERN FILE *TrafficLogFile; /* file in which to log all traffic */ +EXTERN char *UserEnviron[MAXUSERENVIRON + 1]; + /* saved user environment */ +extern int errno; + + +/* +** Timeouts +** +** Indicated values are the MINIMUM per RFC 1123 section 5.3.2. +*/ + +EXTERN struct +{ + /* RFC 1123-specified timeouts [minimum value] */ + time_t to_initial; /* initial greeting timeout [5m] */ + time_t to_mail; /* MAIL command [5m] */ + time_t to_rcpt; /* RCPT command [5m] */ + time_t to_datainit; /* DATA initiation [2m] */ + time_t to_datablock; /* DATA block [3m] */ + time_t to_datafinal; /* DATA completion [10m] */ + time_t to_nextcommand; /* next command [5m] */ + /* following timeouts are not mentioned in RFC 1123 */ + time_t to_connect; /* initial connection timeout */ + time_t to_rset; /* RSET command */ + time_t to_helo; /* HELO command */ + time_t to_quit; /* QUIT command */ + time_t to_miscshort; /* misc short commands (NOOP, VERB, etc) */ + time_t to_ident; /* IDENT protocol requests */ + time_t to_fileopen; /* opening :include: and .forward files */ + /* following are per message */ + time_t to_q_return[MAXTOCLASS]; /* queue return timeouts */ + time_t to_q_warning[MAXTOCLASS]; /* queue warning timeouts */ +} TimeOuts; + +/* timeout classes for return and warning timeouts */ +# define TOC_NORMAL 0 /* normal delivery */ +# define TOC_URGENT 1 /* urgent delivery */ +# define TOC_NONURGENT 2 /* non-urgent delivery */ + + +/* +** Trace information +*/ + +/* trace vector and macros for debugging flags */ +EXTERN u_char tTdvect[100]; +# define tTd(flag, level) (tTdvect[flag] >= level) +# define tTdlevel(flag) (tTdvect[flag]) +/* +** Miscellaneous information. +*/ + + + +/* +** Some in-line functions +*/ + +/* set exit status */ +#define setstat(s) { \ + if (ExitStat == EX_OK || ExitStat == EX_TEMPFAIL) \ + ExitStat = s; \ + } + +/* make a copy of a string */ +#define newstr(s) strcpy(xalloc(strlen(s) + 1), s) + +#define STRUCTCOPY(s, d) d = s + + +/* +** Declarations of useful functions +*/ + +extern char *xalloc __P((int)); +extern FILE *dfopen __P((char *, int, int)); +extern char *sfgets __P((char *, int, FILE *, time_t, char *)); +extern char *queuename __P((ENVELOPE *, int)); +extern time_t curtime __P(()); +extern bool transienterror __P((int)); +extern char *fgetfolded __P((char *, int, FILE *)); +extern char *username __P(()); +extern char *pintvl __P((time_t, bool)); +extern bool shouldqueue __P((long, time_t)); +extern bool lockfile __P((int, char *, char *, int)); +extern char *hostsignature __P((MAILER *, char *, ENVELOPE *)); +extern void openxscript __P((ENVELOPE *)); +extern void closexscript __P((ENVELOPE *)); +extern char *shortenstring __P((const char *, int)); +extern bool usershellok __P((char *, char *)); +extern void commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *)); +extern char *hvalue __P((char *, HDR *)); +extern char *defcharset __P((ENVELOPE *)); +extern bool wordinclass __P((char *, int)); +extern char *denlstring __P((char *, bool, bool)); +extern void makelower __P((char *)); +extern void rebuildaliases __P((MAP *, bool)); +extern void readaliases __P((MAP *, FILE *, bool, bool)); +extern void finis __P(()); +extern void setsender __P((char *, ENVELOPE *, char **, bool)); +extern FILE *safefopen __P((char *, int, int, int)); +extern void xputs __P((const char *)); +extern void logsender __P((ENVELOPE *, char *)); +extern void smtprset __P((MAILER *, MCI *, ENVELOPE *)); +extern void smtpquit __P((MAILER *, MCI *, ENVELOPE *)); +extern void setuserenv __P((const char *, const char *)); +extern void disconnect __P((int, ENVELOPE *)); +extern void putxline __P((char *, MCI *, int)); +extern void dumpfd __P((int, bool, bool)); +extern void makemailer __P((char *)); +extern void putfromline __P((MCI *, ENVELOPE *)); +extern void setoption __P((int, char *, bool, bool, ENVELOPE *)); +extern void setclass __P((int, char *)); +extern void inittimeouts __P((char *)); +extern void logdelivery __P((MAILER *, MCI *, const char *, ADDRESS *, time_t, ENVELOPE *)); +extern void giveresponse __P((int, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *)); + +extern const char *errstring __P((int)); +extern sigfunc_t setsignal __P((int, sigfunc_t)); +extern struct hostent *sm_gethostbyname __P((char *)); +extern struct hostent *sm_gethostbyaddr __P((char *, int, int)); +extern struct passwd *sm_getpwnam __P((char *)); +extern struct passwd *sm_getpwuid __P((UID_T)); + +#ifdef XDEBUG +extern void checkfd012 __P((char *)); +#endif + +/* ellipsis is a different case though */ +#ifdef __STDC__ +extern void auth_warning(ENVELOPE *, const char *, ...); +extern void syserr(const char *, ...); +extern void usrerr(const char *, ...); +extern void message(const char *, ...); +extern void nmessage(const char *, ...); +#else +extern void auth_warning(); +extern void syserr(); +extern void usrerr(); +extern void message(); +extern void nmessage(); +#endif + +#if !HASSNPRINTF +# ifdef __STDC__ +extern void snprintf(char *, size_t, const char *, ...); +extern void vsnprintf(char *, size_t, const char *, va_list); +# else +extern void snprintf(); +extern void vsnprintf(); +# endif +#endif diff --git a/usr.sbin/sendmail/src/sendmail.hf b/usr.sbin/sendmail/src/sendmail.hf new file mode 100644 index 000000000000..14db22c68ee5 --- /dev/null +++ b/usr.sbin/sendmail/src/sendmail.hf @@ -0,0 +1,78 @@ +cpyr +cpyr Copyright (c) 1983, 1995 Eric P. Allman +cpyr Copyright (c) 1988, 1993 +cpyr The Regents of the University of California. All rights reserved. +cpyr +cpyr @(#)sendmail.hf 8.7 (Berkeley) 10/1/95 +cpyr +smtp Commands: +smtp HELO EHLO MAIL RCPT DATA +smtp RSET NOOP QUIT HELP VRFY +smtp EXPN VERB +smtp For more info use "HELP <topic>". +smtp To report bugs in the implementation send email to +smtp sendmail-bugs@sendmail.org. +smtp For local information send email to Postmaster at your site. +help HELP [ <topic> ] +help The HELP command gives help info. +helo HELO <hostname> +helo Introduce yourself. +ehlo EHLO <hostname> +ehlo Introduce yourself, and request extended SMTP mode. +mail MAIL FROM: <sender> +mail Specifies the sender. +rcpt RCPT TO: <recipient> +rcpt Specifies the recipient. Can be used any number of times. +data DATA +data Following text is collected as the message. +data End with a single dot. +rset RSET +rset Resets the system. +quit QUIT +quit Exit sendmail (SMTP). +verb VERB +verb Go into verbose mode. This sends 0xy responses that are +verb not RFC821 standard (but should be) They are recognized +verb by humans and other sendmail implementations. +vrfy VRFY <recipient> +vrfy Verify an address. If you want to see what it aliases +vrfy to, use EXPN instead. +expn EXPN <recipient> +expn Expand an address. If the address indicates a mailing +expn list, return the contents of that list. +noop NOOP +noop Do nothing. +send SEND FROM: <sender> +send replaces the MAIL command, and can be used to send +send directly to a users terminal. Not supported in this +send implementation. +soml SOML FROM: <sender> +soml Send or mail. If the user is logged in, send directly, +soml otherwise mail. Not supported in this implementation. +saml SAML FROM: <sender> +saml Send and mail. Send directly to the user's terminal, +saml and also mail a letter. Not supported in this +saml implementation. +turn TURN +turn Reverses the direction of the connection. Not currently +turn implemented. +-bt Help for test mode: +-bt ? :this help message. +-bt .Dmvalue :define macro `m' to `value'. +-bt .Ccvalue :add `value' to class `c'. +-bt =Sruleset :dump the contents of the indicated ruleset. +-bt =M :display the known mailers. +-bt -ddebug-spec :equivalent to the command-line -d debug flag. +-bt $m :print the value of macro $m. +-bt $=c :print the contents of class $=c. +-bt /mx host :returns the MX records for `host'. +-bt /parse address :parse address, returning the value of crackaddr, and +-bt the parsed address (same as -bv). +-bt /try mailer addr :rewrite address into the form it will have when +-bt presented to the indicated mailer. +-bt /tryflags flags :set flags used by parsing. The flags can be `H' for +-bt Header or `E' for Envelope, and `S' for Sender or `R' +-bt for Recipient. These can be combined, `HR' sets +-bt flags for header recipients. +-bt /canon hostname :try to canonify hostname. +-bt /map mapname key :look up `key' in the indicated `mapname'. diff --git a/usr.sbin/sendmail/src/srvrsmtp.c b/usr.sbin/sendmail/src/srvrsmtp.c new file mode 100644 index 000000000000..5e7ab64b1045 --- /dev/null +++ b/usr.sbin/sendmail/src/srvrsmtp.c @@ -0,0 +1,1285 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +# include "sendmail.h" + +#ifndef lint +#ifdef SMTP +static char sccsid[] = "@(#)srvrsmtp.c 8.97 (Berkeley) 11/18/95 (with SMTP)"; +#else +static char sccsid[] = "@(#)srvrsmtp.c 8.97 (Berkeley) 11/18/95 (without SMTP)"; +#endif +#endif /* not lint */ + +# include <errno.h> + +# ifdef SMTP + +/* +** SMTP -- run the SMTP protocol. +** +** Parameters: +** none. +** +** Returns: +** never. +** +** Side Effects: +** Reads commands from the input channel and processes +** them. +*/ + +struct cmd +{ + char *cmdname; /* command name */ + int cmdcode; /* internal code, see below */ +}; + +/* values for cmdcode */ +# define CMDERROR 0 /* bad command */ +# define CMDMAIL 1 /* mail -- designate sender */ +# define CMDRCPT 2 /* rcpt -- designate recipient */ +# define CMDDATA 3 /* data -- send message text */ +# define CMDRSET 4 /* rset -- reset state */ +# define CMDVRFY 5 /* vrfy -- verify address */ +# define CMDEXPN 6 /* expn -- expand address */ +# define CMDNOOP 7 /* noop -- do nothing */ +# define CMDQUIT 8 /* quit -- close connection and die */ +# define CMDHELO 9 /* helo -- be polite */ +# define CMDHELP 10 /* help -- give usage info */ +# define CMDEHLO 11 /* ehlo -- extended helo (RFC 1425) */ +/* non-standard commands */ +# define CMDONEX 16 /* onex -- sending one transaction only */ +# define CMDVERB 17 /* verb -- go into verbose mode */ +/* use this to catch and log "door handle" attempts on your system */ +# define CMDLOGBOGUS 23 /* bogus command that should be logged */ +/* debugging-only commands, only enabled if SMTPDEBUG is defined */ +# define CMDDBGQSHOW 24 /* showq -- show send queue */ +# define CMDDBGDEBUG 25 /* debug -- set debug mode */ + +static struct cmd CmdTab[] = +{ + "mail", CMDMAIL, + "rcpt", CMDRCPT, + "data", CMDDATA, + "rset", CMDRSET, + "vrfy", CMDVRFY, + "expn", CMDEXPN, + "help", CMDHELP, + "noop", CMDNOOP, + "quit", CMDQUIT, + "helo", CMDHELO, + "ehlo", CMDEHLO, + "verb", CMDVERB, + "onex", CMDONEX, + /* + * remaining commands are here only + * to trap and log attempts to use them + */ + "showq", CMDDBGQSHOW, + "debug", CMDDBGDEBUG, + "wiz", CMDLOGBOGUS, + NULL, CMDERROR, +}; + +bool OneXact = FALSE; /* one xaction only this run */ +char *CurSmtpClient; /* who's at the other end of channel */ + +static char *skipword(); + + +#define MAXBADCOMMANDS 25 /* maximum number of bad commands */ + +void +smtp(e) + register ENVELOPE *volatile e; +{ + register char *p; + register struct cmd *c; + char *cmd; + auto ADDRESS *vrfyqueue; + ADDRESS *a; + volatile bool gotmail; /* mail command received */ + volatile bool gothello; /* helo command received */ + bool vrfy; /* set if this is a vrfy command */ + char *volatile protocol; /* sending protocol */ + char *volatile sendinghost; /* sending hostname */ + char *volatile peerhostname; /* name of SMTP peer or "localhost" */ + auto char *delimptr; + char *id; + volatile int nrcpts = 0; /* number of RCPT commands */ + bool doublequeue; + volatile int badcommands = 0; /* count of bad commands */ + char inp[MAXLINE]; + char cmdbuf[MAXLINE]; + extern ENVELOPE BlankEnvelope; + extern void help __P((char *)); + + if (fileno(OutChannel) != fileno(stdout)) + { + /* arrange for debugging output to go to remote host */ + (void) dup2(fileno(OutChannel), fileno(stdout)); + } + settime(e); + peerhostname = RealHostName; + if (peerhostname == NULL) + peerhostname = "localhost"; + CurHostName = peerhostname; + CurSmtpClient = macvalue('_', e); + if (CurSmtpClient == NULL) + CurSmtpClient = CurHostName; + + setproctitle("server %s startup", CurSmtpClient); +#ifdef LOG + if (LogLevel > 11) + { + /* log connection information */ + syslog(LOG_INFO, "SMTP connect from %.100s (%.100s)", + CurSmtpClient, anynet_ntoa(&RealHostAddr)); + } +#endif + + /* output the first line, inserting "ESMTP" as second word */ + expand(SmtpGreeting, inp, sizeof inp, e); + p = strchr(inp, '\n'); + if (p != NULL) + *p++ = '\0'; + id = strchr(inp, ' '); + if (id == NULL) + id = &inp[strlen(inp)]; + cmd = p == NULL ? "220 %.*s ESMTP%s" : "220-%.*s ESMTP%s"; + message(cmd, id - inp, inp, id); + + /* output remaining lines */ + while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL) + { + *p++ = '\0'; + if (isascii(*id) && isspace(*id)) + id++; + message("220-%s", id); + } + if (id != NULL) + { + if (isascii(*id) && isspace(*id)) + id++; + message("220 %s", id); + } + + protocol = NULL; + sendinghost = macvalue('s', e); + gothello = FALSE; + gotmail = FALSE; + for (;;) + { + /* arrange for backout */ + if (setjmp(TopFrame) > 0) + { + /* if() nesting is necessary for Cray UNICOS */ + if (InChild) + { + QuickAbort = FALSE; + SuprErrs = TRUE; + finis(); + } + } + QuickAbort = FALSE; + HoldErrs = FALSE; + LogUsrErrs = FALSE; + e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS); + + /* setup for the read */ + e->e_to = NULL; + Errors = 0; + (void) fflush(stdout); + + /* read the input line */ + SmtpPhase = "server cmd read"; + setproctitle("server %s cmd read", CurSmtpClient); + p = sfgets(inp, sizeof inp, InChannel, TimeOuts.to_nextcommand, + SmtpPhase); + + /* handle errors */ + if (p == NULL) + { + /* end of file, just die */ + disconnect(1, e); + message("421 %s Lost input channel from %s", + MyHostName, CurSmtpClient); +#ifdef LOG + if (LogLevel > (gotmail ? 1 : 19)) + syslog(LOG_NOTICE, "lost input channel from %.100s", + CurSmtpClient); +#endif + if (InChild) + ExitStat = EX_QUIT; + finis(); + } + + /* clean up end of line */ + fixcrlf(inp, TRUE); + + /* echo command to transcript */ + if (e->e_xfp != NULL) + fprintf(e->e_xfp, "<<< %s\n", inp); + + if (e->e_id == NULL) + setproctitle("%s: %.80s", CurSmtpClient, inp); + else + setproctitle("%s %s: %.80s", e->e_id, CurSmtpClient, inp); + + /* break off command */ + for (p = inp; isascii(*p) && isspace(*p); p++) + continue; + cmd = cmdbuf; + while (*p != '\0' && + !(isascii(*p) && isspace(*p)) && + cmd < &cmdbuf[sizeof cmdbuf - 2]) + *cmd++ = *p++; + *cmd = '\0'; + + /* throw away leading whitespace */ + while (isascii(*p) && isspace(*p)) + p++; + + /* decode command */ + for (c = CmdTab; c->cmdname != NULL; c++) + { + if (!strcasecmp(c->cmdname, cmdbuf)) + break; + } + + /* reset errors */ + errno = 0; + + /* process command */ + switch (c->cmdcode) + { + case CMDHELO: /* hello -- introduce yourself */ + case CMDEHLO: /* extended hello */ + if (c->cmdcode == CMDEHLO) + { + protocol = "ESMTP"; + SmtpPhase = "server EHLO"; + } + else + { + protocol = "SMTP"; + SmtpPhase = "server HELO"; + } + + /* check for valid domain name (re 1123 5.2.5) */ + if (*p == '\0') + { + message("501 %s requires domain address", + cmdbuf); + break; + } + else + { + register char *q; + + for (q = p; *q != '\0'; q++) + { + if (!isascii(*q)) + break; + if (isalnum(*q)) + continue; + if (isspace(*q)) + { + *q = '\0'; + break; + } + if (strchr("[].-_#", *q) == NULL) + break; + } + if (*q != '\0') + { + message("501 Invalid domain name"); + break; + } + } + + sendinghost = newstr(p); + gothello = TRUE; + if (c->cmdcode != CMDEHLO) + { + /* print old message and be done with it */ + message("250 %s Hello %s, pleased to meet you", + MyHostName, CurSmtpClient); + break; + } + + /* print extended message and brag */ + message("250-%s Hello %s, pleased to meet you", + MyHostName, CurSmtpClient); + if (!bitset(PRIV_NOEXPN, PrivacyFlags)) + message("250-EXPN"); +#if MIME8TO7 + message("250-8BITMIME"); +#endif + if (MaxMessageSize > 0) + message("250-SIZE %ld", MaxMessageSize); + else + message("250-SIZE"); +#if DSN + if (SendMIMEErrors) + message("250-DSN"); +#endif + message("250-VERB"); + message("250-ONEX"); + message("250 HELP"); + break; + + case CMDMAIL: /* mail -- designate sender */ + SmtpPhase = "server MAIL"; + + /* check for validity of this command */ + if (!gothello) + { + /* set sending host to our known value */ + if (sendinghost == NULL) + sendinghost = peerhostname; + + if (bitset(PRIV_NEEDMAILHELO, PrivacyFlags)) + { + message("503 Polite people say HELO first"); + break; + } + } + if (gotmail) + { + message("503 Sender already specified"); + if (InChild) + finis(); + break; + } + if (InChild) + { + errno = 0; + syserr("503 Nested MAIL command: MAIL %s", p); + finis(); + } + + /* fork a subprocess to process this command */ + if (runinchild("SMTP-MAIL", e) > 0) + break; + if (!gothello) + { + auth_warning(e, + "Host %s didn't use HELO protocol", + CurSmtpClient); + } +#ifdef PICKY_HELO_CHECK + if (strcasecmp(sendinghost, peerhostname) != 0 && + (strcasecmp(peerhostname, "localhost") != 0 || + strcasecmp(sendinghost, MyHostName) != 0)) + { + auth_warning(e, "Host %s claimed to be %s", + CurSmtpClient, sendinghost); + } +#endif + + if (protocol == NULL) + protocol = "SMTP"; + define('r', protocol, e); + define('s', sendinghost, e); + initsys(e); + nrcpts = 0; + e->e_flags |= EF_LOGSENDER|EF_CLRQUEUE; + setproctitle("%s %s: %.80s", e->e_id, CurSmtpClient, inp); + + /* child -- go do the processing */ + p = skipword(p, "from"); + if (p == NULL) + break; + if (setjmp(TopFrame) > 0) + { + /* this failed -- undo work */ + if (InChild) + { + QuickAbort = FALSE; + SuprErrs = TRUE; + e->e_flags &= ~EF_FATALERRS; + finis(); + } + break; + } + QuickAbort = TRUE; + + /* must parse sender first */ + delimptr = NULL; + setsender(p, e, &delimptr, FALSE); + p = delimptr; + if (p != NULL && *p != '\0') + *p++ = '\0'; + + /* check for possible spoofing */ + if (RealUid != 0 && OpMode == MD_SMTP && + !wordinclass(RealUserName, 't') && + !bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags) && + strcmp(e->e_from.q_user, RealUserName) != 0) + { + auth_warning(e, "%s owned process doing -bs", + RealUserName); + } + + /* now parse ESMTP arguments */ + e->e_msgsize = 0; + while (p != NULL && *p != '\0') + { + char *kp; + char *vp = NULL; + extern void mail_esmtp_args __P((char *, char *, ENVELOPE *)); + + /* locate the beginning of the keyword */ + while (isascii(*p) && isspace(*p)) + p++; + if (*p == '\0') + break; + kp = p; + + /* skip to the value portion */ + while (isascii(*p) && isalnum(*p) || *p == '-') + p++; + if (*p == '=') + { + *p++ = '\0'; + vp = p; + + /* skip to the end of the value */ + while (*p != '\0' && *p != ' ' && + !(isascii(*p) && iscntrl(*p)) && + *p != '=') + p++; + } + + if (*p != '\0') + *p++ = '\0'; + + if (tTd(19, 1)) + printf("MAIL: got arg %s=\"%s\"\n", kp, + vp == NULL ? "<null>" : vp); + + mail_esmtp_args(kp, vp, e); + } + + if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize) + { + usrerr("552 Message size exceeds fixed maximum message size (%ld)", + MaxMessageSize); + /* NOTREACHED */ + } + + if (!enoughdiskspace(e->e_msgsize)) + { + message("452 Insufficient disk space; try again later"); + break; + } + message("250 Sender ok"); + gotmail = TRUE; + break; + + case CMDRCPT: /* rcpt -- designate recipient */ + if (!gotmail) + { + usrerr("503 Need MAIL before RCPT"); + break; + } + SmtpPhase = "server RCPT"; + if (setjmp(TopFrame) > 0) + { + e->e_flags &= ~EF_FATALERRS; + break; + } + QuickAbort = TRUE; + LogUsrErrs = TRUE; + + if (e->e_sendmode != SM_DELIVER) + e->e_flags |= EF_VRFYONLY; + + p = skipword(p, "to"); + if (p == NULL) + break; + a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr, e); + if (a == NULL) + break; + p = delimptr; + + /* now parse ESMTP arguments */ + while (p != NULL && *p != '\0') + { + char *kp; + char *vp = NULL; + extern void rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *)); + + /* locate the beginning of the keyword */ + while (isascii(*p) && isspace(*p)) + p++; + if (*p == '\0') + break; + kp = p; + + /* skip to the value portion */ + while (isascii(*p) && isalnum(*p) || *p == '-') + p++; + if (*p == '=') + { + *p++ = '\0'; + vp = p; + + /* skip to the end of the value */ + while (*p != '\0' && *p != ' ' && + !(isascii(*p) && iscntrl(*p)) && + *p != '=') + p++; + } + + if (*p != '\0') + *p++ = '\0'; + + if (tTd(19, 1)) + printf("RCPT: got arg %s=\"%s\"\n", kp, + vp == NULL ? "<null>" : vp); + + rcpt_esmtp_args(a, kp, vp, e); + } + + /* save in recipient list after ESMTP mods */ + a = recipient(a, &e->e_sendqueue, 0, e); + + if (Errors != 0) + break; + + /* no errors during parsing, but might be a duplicate */ + e->e_to = p; + if (!bitset(QBADADDR, a->q_flags)) + { + message("250 Recipient ok%s", + bitset(QQUEUEUP, a->q_flags) ? + " (will queue)" : ""); + nrcpts++; + } + else + { + /* punt -- should keep message in ADDRESS.... */ + message("550 Addressee unknown"); + } + e->e_to = NULL; + break; + + case CMDDATA: /* data -- text of mail */ + SmtpPhase = "server DATA"; + if (!gotmail) + { + message("503 Need MAIL command"); + break; + } + else if (nrcpts <= 0) + { + message("503 Need RCPT (recipient)"); + break; + } + + /* check to see if we need to re-expand aliases */ + /* also reset QBADADDR on already-diagnosted addrs */ + doublequeue = FALSE; + for (a = e->e_sendqueue; a != NULL; a = a->q_next) + { + if (bitset(QVERIFIED, a->q_flags)) + { + /* need to re-expand aliases */ + doublequeue = TRUE; + } + if (bitset(QBADADDR, a->q_flags)) + { + /* make this "go away" */ + a->q_flags |= QDONTSEND; + a->q_flags &= ~QBADADDR; + } + } + + /* collect the text of the message */ + SmtpPhase = "collect"; + buffer_errors(); + collect(InChannel, TRUE, doublequeue, NULL, e); + flush_errors(TRUE); + if (Errors != 0) + goto abortmessage; + + /* make sure we actually do delivery */ + e->e_flags &= ~EF_CLRQUEUE; + + /* from now on, we have to operate silently */ + buffer_errors(); + e->e_errormode = EM_MAIL; + + /* + ** Arrange to send to everyone. + ** If sending to multiple people, mail back + ** errors rather than reporting directly. + ** In any case, don't mail back errors for + ** anything that has happened up to + ** now (the other end will do this). + ** Truncate our transcript -- the mail has gotten + ** to us successfully, and if we have + ** to mail this back, it will be easier + ** on the reader. + ** Then send to everyone. + ** Finally give a reply code. If an error has + ** already been given, don't mail a + ** message back. + ** We goose error returns by clearing error bit. + */ + + SmtpPhase = "delivery"; + e->e_xfp = freopen(queuename(e, 'x'), "w", e->e_xfp); + id = e->e_id; + + if (doublequeue) + { + /* make sure it is in the queue */ + queueup(e, FALSE); + } + else + { + /* send to all recipients */ + sendall(e, SM_DEFAULT); + } + e->e_to = NULL; + + /* issue success message */ + message("250 %s Message accepted for delivery", id); + + /* if we just queued, poke it */ + if (doublequeue && e->e_sendmode != SM_QUEUE && + e->e_sendmode != SM_DEFER) + { + extern pid_t dowork(); + + unlockqueue(e); + (void) dowork(id, TRUE, TRUE, e); + } + + abortmessage: + /* if in a child, pop back to our parent */ + if (InChild) + finis(); + + /* clean up a bit */ + gotmail = FALSE; + dropenvelope(e); + CurEnv = e = newenvelope(e, CurEnv); + e->e_flags = BlankEnvelope.e_flags; + break; + + case CMDRSET: /* rset -- reset state */ + message("250 Reset state"); + + /* arrange to ignore any current send list */ + e->e_sendqueue = NULL; + e->e_flags |= EF_CLRQUEUE; + if (InChild) + finis(); + + /* clean up a bit */ + gotmail = FALSE; + dropenvelope(e); + CurEnv = e = newenvelope(e, CurEnv); + break; + + case CMDVRFY: /* vrfy -- verify address */ + case CMDEXPN: /* expn -- expand address */ + vrfy = c->cmdcode == CMDVRFY; + if (bitset(vrfy ? PRIV_NOVRFY : PRIV_NOEXPN, + PrivacyFlags)) + { + if (vrfy) + message("252 Cannot VRFY user; try RCPT to attempt delivery (or try finger)"); + else + message("502 Sorry, we do not allow this operation"); +#ifdef LOG + if (LogLevel > 5) + syslog(LOG_INFO, "%.100s: %s [rejected]", + CurSmtpClient, + shortenstring(inp, 203)); +#endif + break; + } + else if (!gothello && + bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO, + PrivacyFlags)) + { + message("503 I demand that you introduce yourself first"); + break; + } + if (runinchild(vrfy ? "SMTP-VRFY" : "SMTP-EXPN", e) > 0) + break; +#ifdef LOG + if (LogLevel > 5) + syslog(LOG_INFO, "%.100s: %s", + CurSmtpClient, + shortenstring(inp, 203)); +#endif + vrfyqueue = NULL; + QuickAbort = TRUE; + if (vrfy) + e->e_flags |= EF_VRFYONLY; + while (*p != '\0' && isascii(*p) && isspace(*p)) + p++; + if (*p == '\0') + { + message("501 Argument required"); + Errors++; + } + else + { + (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e); + } + if (Errors != 0) + { + if (InChild) + finis(); + break; + } + if (vrfyqueue == NULL) + { + message("554 Nothing to %s", vrfy ? "VRFY" : "EXPN"); + } + while (vrfyqueue != NULL) + { + extern void printvrfyaddr __P((ADDRESS *, bool)); + + a = vrfyqueue; + while ((a = a->q_next) != NULL && + bitset(QDONTSEND|QBADADDR, a->q_flags)) + continue; + if (!bitset(QDONTSEND|QBADADDR, vrfyqueue->q_flags)) + printvrfyaddr(vrfyqueue, a == NULL); + vrfyqueue = vrfyqueue->q_next; + } + if (InChild) + finis(); + break; + + case CMDHELP: /* help -- give user info */ + help(p); + break; + + case CMDNOOP: /* noop -- do nothing */ + message("250 OK"); + break; + + case CMDQUIT: /* quit -- leave mail */ + message("221 %s closing connection", MyHostName); + +doquit: + /* arrange to ignore any current send list */ + e->e_sendqueue = NULL; + + /* avoid future 050 messages */ + disconnect(1, e); + + if (InChild) + ExitStat = EX_QUIT; + finis(); + + case CMDVERB: /* set verbose mode */ + if (bitset(PRIV_NOEXPN, PrivacyFlags)) + { + /* this would give out the same info */ + message("502 Verbose unavailable"); + break; + } + Verbose = TRUE; + e->e_sendmode = SM_DELIVER; + message("250 Verbose mode"); + break; + + case CMDONEX: /* doing one transaction only */ + OneXact = TRUE; + message("250 Only one transaction"); + break; + +# ifdef SMTPDEBUG + case CMDDBGQSHOW: /* show queues */ + printf("Send Queue="); + printaddr(e->e_sendqueue, TRUE); + break; + + case CMDDBGDEBUG: /* set debug mode */ + tTsetup(tTdvect, sizeof tTdvect, "0-99.1"); + tTflag(p); + message("200 Debug set"); + break; + +# else /* not SMTPDEBUG */ + case CMDDBGQSHOW: /* show queues */ + case CMDDBGDEBUG: /* set debug mode */ +# endif /* SMTPDEBUG */ + case CMDLOGBOGUS: /* bogus command */ +# ifdef LOG + if (LogLevel > 0) + syslog(LOG_CRIT, + "\"%s\" command from %.100s (%.100s)", + c->cmdname, CurSmtpClient, + anynet_ntoa(&RealHostAddr)); +# endif + /* FALL THROUGH */ + + case CMDERROR: /* unknown command */ + if (++badcommands > MAXBADCOMMANDS) + { + message("421 %s Too many bad commands; closing connection", + MyHostName); + goto doquit; + } + + message("500 Command unrecognized"); + break; + + default: + errno = 0; + syserr("500 smtp: unknown code %d", c->cmdcode); + break; + } + } +} +/* +** SKIPWORD -- skip a fixed word. +** +** Parameters: +** p -- place to start looking. +** w -- word to skip. +** +** Returns: +** p following w. +** NULL on error. +** +** Side Effects: +** clobbers the p data area. +*/ + +static char * +skipword(p, w) + register char *p; + char *w; +{ + register char *q; + char *firstp = p; + + /* find beginning of word */ + while (isascii(*p) && isspace(*p)) + p++; + q = p; + + /* find end of word */ + while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p))) + p++; + while (isascii(*p) && isspace(*p)) + *p++ = '\0'; + if (*p != ':') + { + syntax: + message("501 Syntax error in parameters scanning \"%s\"", + shortenstring(firstp, 203)); + Errors++; + return (NULL); + } + *p++ = '\0'; + while (isascii(*p) && isspace(*p)) + p++; + + if (*p == '\0') + goto syntax; + + /* see if the input word matches desired word */ + if (strcasecmp(q, w)) + goto syntax; + + return (p); +} +/* +** MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line +** +** Parameters: +** kp -- the parameter key. +** vp -- the value of that parameter. +** e -- the envelope. +** +** Returns: +** none. +*/ + +void +mail_esmtp_args(kp, vp, e) + char *kp; + char *vp; + ENVELOPE *e; +{ + if (strcasecmp(kp, "size") == 0) + { + if (vp == NULL) + { + usrerr("501 SIZE requires a value"); + /* NOTREACHED */ + } +# if defined(__STDC__) && !defined(BROKEN_ANSI_LIBRARY) + e->e_msgsize = strtoul(vp, (char **) NULL, 10); +# else + e->e_msgsize = strtol(vp, (char **) NULL, 10); +# endif + } + else if (strcasecmp(kp, "body") == 0) + { + if (vp == NULL) + { + usrerr("501 BODY requires a value"); + /* NOTREACHED */ + } + else if (strcasecmp(vp, "8bitmime") == 0) + { + SevenBitInput = FALSE; + } + else if (strcasecmp(vp, "7bit") == 0) + { + SevenBitInput = TRUE; + } + else + { + usrerr("501 Unknown BODY type %s", + vp); + /* NOTREACHED */ + } + e->e_bodytype = newstr(vp); + } + else if (strcasecmp(kp, "envid") == 0) + { + if (vp == NULL) + { + usrerr("501 ENVID requires a value"); + /* NOTREACHED */ + } + if (!xtextok(vp)) + { + usrerr("501 Syntax error in ENVID parameter value"); + /* NOTREACHED */ + } + if (e->e_envid != NULL) + { + usrerr("501 Duplicate ENVID parameter"); + /* NOTREACHED */ + } + e->e_envid = newstr(vp); + } + else if (strcasecmp(kp, "ret") == 0) + { + if (vp == NULL) + { + usrerr("501 RET requires a value"); + /* NOTREACHED */ + } + if (bitset(EF_RET_PARAM, e->e_flags)) + { + usrerr("501 Duplicate RET parameter"); + /* NOTREACHED */ + } + e->e_flags |= EF_RET_PARAM; + if (strcasecmp(vp, "hdrs") == 0) + e->e_flags |= EF_NO_BODY_RETN; + else if (strcasecmp(vp, "full") != 0) + { + usrerr("501 Bad argument \"%s\" to RET", vp); + /* NOTREACHED */ + } + } + else + { + usrerr("501 %s parameter unrecognized", kp); + /* NOTREACHED */ + } +} +/* +** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line +** +** Parameters: +** a -- the address corresponding to the To: parameter. +** kp -- the parameter key. +** vp -- the value of that parameter. +** e -- the envelope. +** +** Returns: +** none. +*/ + +void +rcpt_esmtp_args(a, kp, vp, e) + ADDRESS *a; + char *kp; + char *vp; + ENVELOPE *e; +{ + if (strcasecmp(kp, "notify") == 0) + { + char *p; + + if (vp == NULL) + { + usrerr("501 NOTIFY requires a value"); + /* NOTREACHED */ + } + a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY); + a->q_flags |= QHASNOTIFY; + if (strcasecmp(vp, "never") == 0) + return; + for (p = vp; p != NULL; vp = p) + { + p = strchr(p, ','); + if (p != NULL) + *p++ = '\0'; + if (strcasecmp(vp, "success") == 0) + a->q_flags |= QPINGONSUCCESS; + else if (strcasecmp(vp, "failure") == 0) + a->q_flags |= QPINGONFAILURE; + else if (strcasecmp(vp, "delay") == 0) + a->q_flags |= QPINGONDELAY; + else + { + usrerr("501 Bad argument \"%s\" to NOTIFY", + vp); + /* NOTREACHED */ + } + } + } + else if (strcasecmp(kp, "orcpt") == 0) + { + if (vp == NULL) + { + usrerr("501 ORCPT requires a value"); + /* NOTREACHED */ + } + if (strchr(vp, ';') == NULL || !xtextok(vp)) + { + usrerr("501 Syntax error in ORCPT parameter value"); + /* NOTREACHED */ + } + if (a->q_orcpt != NULL) + { + usrerr("501 Duplicate ORCPT parameter"); + /* NOTREACHED */ + } + a->q_orcpt = newstr(vp); + } + else + { + usrerr("501 %s parameter unrecognized", kp); + /* NOTREACHED */ + } +} +/* +** PRINTVRFYADDR -- print an entry in the verify queue +** +** Parameters: +** a -- the address to print +** last -- set if this is the last one. +** +** Returns: +** none. +** +** Side Effects: +** Prints the appropriate 250 codes. +*/ + +void +printvrfyaddr(a, last) + register ADDRESS *a; + bool last; +{ + char fmtbuf[20]; + + strcpy(fmtbuf, "250"); + fmtbuf[3] = last ? ' ' : '-'; + + if (a->q_fullname == NULL) + { + if (strchr(a->q_user, '@') == NULL) + strcpy(&fmtbuf[4], "<%s@%s>"); + else + strcpy(&fmtbuf[4], "<%s>"); + message(fmtbuf, a->q_user, MyHostName); + } + else + { + if (strchr(a->q_user, '@') == NULL) + strcpy(&fmtbuf[4], "%s <%s@%s>"); + else + strcpy(&fmtbuf[4], "%s <%s>"); + message(fmtbuf, a->q_fullname, a->q_user, MyHostName); + } +} +/* +** RUNINCHILD -- return twice -- once in the child, then in the parent again +** +** Parameters: +** label -- a string used in error messages +** +** Returns: +** zero in the child +** one in the parent +** +** Side Effects: +** none. +*/ + +int +runinchild(label, e) + char *label; + register ENVELOPE *e; +{ + int childpid; + + if (!OneXact) + { + childpid = dofork(); + if (childpid < 0) + { + syserr("451 %s: cannot fork", label); + return (1); + } + if (childpid > 0) + { + auto int st; + + /* parent -- wait for child to complete */ + setproctitle("server %s child wait", CurSmtpClient); + st = waitfor(childpid); + if (st == -1) + syserr("451 %s: lost child", label); + else if (!WIFEXITED(st)) + syserr("451 %s: died on signal %d", + label, st & 0177); + + /* if we exited on a QUIT command, complete the process */ + if (WEXITSTATUS(st) == EX_QUIT) + { + disconnect(1, e); + finis(); + } + + return (1); + } + else + { + /* child */ + InChild = TRUE; + QuickAbort = FALSE; + clearenvelope(e, FALSE); + } + } + + /* open alias database */ + initmaps(FALSE, e); + + return (0); +} + +# endif /* SMTP */ +/* +** HELP -- implement the HELP command. +** +** Parameters: +** topic -- the topic we want help for. +** +** Returns: +** none. +** +** Side Effects: +** outputs the help file to message output. +*/ + +void +help(topic) + char *topic; +{ + register FILE *hf; + int len; + bool noinfo; + char buf[MAXLINE]; + extern char Version[]; + + + if (HelpFile == NULL || (hf = fopen(HelpFile, "r")) == NULL) + { + /* no help */ + errno = 0; + message("502 Sendmail %s -- HELP not implemented", Version); + return; + } + + if (topic == NULL || *topic == '\0') + { + topic = "smtp"; + message("214-This is Sendmail version %s", Version); + noinfo = FALSE; + } + else + { + makelower(topic); + noinfo = TRUE; + } + + len = strlen(topic); + + while (fgets(buf, sizeof buf, hf) != NULL) + { + if (strncmp(buf, topic, len) == 0) + { + register char *p; + + p = strchr(buf, '\t'); + if (p == NULL) + p = buf; + else + p++; + fixcrlf(p, TRUE); + message("214-%s", p); + noinfo = FALSE; + } + } + + if (noinfo) + message("504 HELP topic \"%.10s\" unknown", topic); + else + message("214 End of HELP info"); + (void) fclose(hf); +} diff --git a/usr.sbin/sendmail/src/stab.c b/usr.sbin/sendmail/src/stab.c new file mode 100644 index 000000000000..cfb02c69686b --- /dev/null +++ b/usr.sbin/sendmail/src/stab.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)stab.c 8.6 (Berkeley) 8/31/95"; +#endif /* not lint */ + +# include "sendmail.h" + +/* +** STAB -- manage the symbol table +** +** Parameters: +** name -- the name to be looked up or inserted. +** type -- the type of symbol. +** op -- what to do: +** ST_ENTER -- enter the name if not +** already present. +** ST_FIND -- find it only. +** +** Returns: +** pointer to a STAB entry for this name. +** NULL if not found and not entered. +** +** Side Effects: +** can update the symbol table. +*/ + +# define STABSIZE 2003 + +static STAB *SymTab[STABSIZE]; + +STAB * +stab(name, type, op) + char *name; + int type; + int op; +{ + register STAB *s; + register STAB **ps; + register int hfunc; + register char *p; + extern char lower(); + + if (tTd(36, 5)) + printf("STAB: %s %d ", name, type); + + /* + ** Compute the hashing function + */ + + hfunc = type; + for (p = name; *p != '\0'; p++) + hfunc = ((hfunc << 1) ^ (lower(*p) & 0377)) % STABSIZE; + + if (tTd(36, 9)) + printf("(hfunc=%d) ", hfunc); + + ps = &SymTab[hfunc]; + if (type == ST_MACRO || type == ST_RULESET) + { + while ((s = *ps) != NULL && + (s->s_type != type || strcmp(name, s->s_name))) + ps = &s->s_next; + } + else + { + while ((s = *ps) != NULL && + (s->s_type != type || strcasecmp(name, s->s_name))) + ps = &s->s_next; + } + + /* + ** Dispose of the entry. + */ + + if (s != NULL || op == ST_FIND) + { + if (tTd(36, 5)) + { + if (s == NULL) + printf("not found\n"); + else + { + long *lp = (long *) s->s_class; + + printf("type %d val %lx %lx %lx %lx\n", + s->s_type, lp[0], lp[1], lp[2], lp[3]); + } + } + return (s); + } + + /* + ** Make a new entry and link it in. + */ + + if (tTd(36, 5)) + printf("entered\n"); + + /* make new entry */ + s = (STAB *) xalloc(sizeof *s); + bzero((char *) s, sizeof *s); + s->s_name = newstr(name); + s->s_type = type; + + /* link it in */ + *ps = s; + + return (s); +} +/* +** STABAPPLY -- apply function to all stab entries +** +** Parameters: +** func -- the function to apply. It will be given one +** parameter (the stab entry). +** arg -- an arbitrary argument, passed to func. +** +** Returns: +** none. +*/ + +void +stabapply(func, arg) + void (*func)__P((STAB *, int)); + int arg; +{ + register STAB **shead; + register STAB *s; + + for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) + { + for (s = *shead; s != NULL; s = s->s_next) + { + if (tTd(36, 90)) + printf("stabapply: trying %d/%s\n", + s->s_type, s->s_name); + func(s, arg); + } + } +} diff --git a/usr.sbin/sendmail/src/stats.c b/usr.sbin/sendmail/src/stats.c new file mode 100644 index 000000000000..f59885a60674 --- /dev/null +++ b/usr.sbin/sendmail/src/stats.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)stats.c 8.5 (Berkeley) 5/28/95"; +#endif /* not lint */ + +# include "sendmail.h" +# include "mailstats.h" + +struct statistics Stat; + +bool GotStats = FALSE; /* set when we have stats to merge */ + +#define ONE_K 1000 /* one thousand (twenty-four?) */ +#define KBYTES(x) (((x) + (ONE_K - 1)) / ONE_K) +/* +** MARKSTATS -- mark statistics +*/ + +void +markstats(e, to) + register ENVELOPE *e; + register ADDRESS *to; +{ + if (to == NULL) + { + if (e->e_from.q_mailer != NULL) + { + Stat.stat_nf[e->e_from.q_mailer->m_mno]++; + Stat.stat_bf[e->e_from.q_mailer->m_mno] += + KBYTES(e->e_msgsize); + } + } + else + { + Stat.stat_nt[to->q_mailer->m_mno]++; + Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize); + } + GotStats = TRUE; +} +/* +** POSTSTATS -- post statistics in the statistics file +** +** Parameters: +** sfile -- the name of the statistics file. +** +** Returns: +** none. +** +** Side Effects: +** merges the Stat structure with the sfile file. +*/ + +void +poststats(sfile) + char *sfile; +{ + register int fd; + struct statistics stat; + extern off_t lseek(); + + if (sfile == NULL || !GotStats) + return; + + (void) time(&Stat.stat_itime); + Stat.stat_size = sizeof Stat; + + fd = open(sfile, O_RDWR); + if (fd < 0) + { + errno = 0; + return; + } + (void) lockfile(fd, sfile, NULL, LOCK_EX); + if (read(fd, (char *) &stat, sizeof stat) == sizeof stat && + stat.stat_size == sizeof stat) + { + /* merge current statistics into statfile */ + register int i; + + for (i = 0; i < MAXMAILERS; i++) + { + stat.stat_nf[i] += Stat.stat_nf[i]; + stat.stat_bf[i] += Stat.stat_bf[i]; + stat.stat_nt[i] += Stat.stat_nt[i]; + stat.stat_bt[i] += Stat.stat_bt[i]; + } + } + else + bcopy((char *) &Stat, (char *) &stat, sizeof stat); + + /* write out results */ + (void) lseek(fd, (off_t) 0, 0); + (void) write(fd, (char *) &stat, sizeof stat); + (void) close(fd); + + /* clear the structure to avoid future disappointment */ + bzero(&Stat, sizeof stat); + GotStats = FALSE; +} diff --git a/usr.sbin/sendmail/src/sysexits.c b/usr.sbin/sendmail/src/sysexits.c new file mode 100644 index 000000000000..ad4f1e1cffb8 --- /dev/null +++ b/usr.sbin/sendmail/src/sysexits.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)sysexits.c 8.5 (Berkeley) 5/24/95"; +#endif /* not lint */ + +#include <sendmail.h> + +/* +** SYSEXITS.C -- error messages corresponding to sysexits.h +** +** If the first character of the string is a colon, interpolate +** the current errno after the rest of the string. +*/ + +char *SysExMsg[] = +{ + /* 64 USAGE */ " 500 Bad usage", + /* 65 DATAERR */ " 501 Data format error", + /* 66 NOINPUT */ ":550 Cannot open input", + /* 67 NOUSER */ " 550 User unknown", + /* 68 NOHOST */ " 550 Host unknown", + /* 69 UNAVAILABLE */ " 554 Service unavailable", + /* 70 SOFTWARE */ ":554 Internal error", + /* 71 OSERR */ ":451 Operating system error", + /* 72 OSFILE */ ":554 System file missing", + /* 73 CANTCREAT */ ":550 Can't create output", + /* 74 IOERR */ ":451 I/O error", + /* 75 TEMPFAIL */ " 250 Deferred", + /* 76 PROTOCOL */ " 554 Remote protocol error", + /* 77 NOPERM */ ":550 Insufficient permission", + /* 78 CONFIG */ " 554 Local configuration error", +}; + +int N_SysEx = sizeof(SysExMsg) / sizeof(SysExMsg[0]); +/* +** DSNTOEXITSTAT -- convert DSN-style error code to EX_ style. +** +** Parameters: +** dsncode -- the text of the DSN-style code. +** +** Returns: +** The corresponding exit status. +*/ + +int +dsntoexitstat(dsncode) + char *dsncode; +{ + int code2, code3; + + /* first the easy cases.... */ + if (*dsncode == '2') + return EX_OK; + if (*dsncode == '4') + return EX_TEMPFAIL; + + /* now decode the other two field parts */ + if (*++dsncode == '.') + dsncode++; + code2 = atoi(dsncode); + while (*dsncode != '\0' && *dsncode != '.') + dsncode++; + if (*dsncode != '\0') + dsncode++; + code3 = atoi(dsncode); + + /* and do a nested switch to work them out */ + switch (code2) + { + case 0: /* Other or Undefined status */ + return EX_UNAVAILABLE; + + case 1: /* Address Status */ + switch (code3) + { + case 0: /* Other Address Status */ + return EX_DATAERR; + + case 1: /* Bad destination mailbox address */ + case 6: /* Mailbox has moved, No forwarding address */ + return EX_NOUSER; + + case 2: /* Bad destination system address */ + case 8: /* Bad senders system address */ + return EX_NOHOST; + + case 3: /* Bad destination mailbox address syntax */ + case 7: /* Bad senders mailbox address syntax */ + return EX_USAGE; + + case 4: /* Destination mailbox address ambiguous */ + return EX_UNAVAILABLE; + + case 5: /* Destination address valid */ + return EX_OK; + } + break; + + case 2: /* Mailbox Status */ + switch (code3) + { + case 0: /* Other or Undefined mailbox status */ + case 1: /* Mailbox disabled, not acccepting messages */ + case 2: /* Mailbox full */ + case 4: /* Mailing list expansion problem */ + return EX_UNAVAILABLE; + + case 3: /* Message length exceeds administrative lim */ + return EX_DATAERR; + } + break; + + case 3: /* System Status */ + return EX_OSERR; + + case 4: /* Network and Routing Status */ + switch (code3) + { + case 0: /* Other or undefined network or routing stat */ + return EX_IOERR; + + case 1: /* No answer from host */ + case 3: /* Routing server failure */ + case 5: /* Network congestion */ + return EX_TEMPFAIL; + + case 2: /* Bad connection */ + return EX_IOERR; + + case 4: /* Unable to route */ + return EX_PROTOCOL; + + case 6: /* Routing loop detected */ + return EX_CONFIG; + + case 7: /* Delivery time expired */ + return EX_UNAVAILABLE; + } + break; + + case 5: /* Protocol Status */ + return EX_PROTOCOL; + + case 6: /* Message Content or Media Status */ + return EX_UNAVAILABLE; + + case 7: /* Security Status */ + return EX_DATAERR; + } + return EX_CONFIG; +} diff --git a/usr.sbin/sendmail/src/sysexits.h b/usr.sbin/sendmail/src/sysexits.h new file mode 100644 index 000000000000..464cb11bab2d --- /dev/null +++ b/usr.sbin/sendmail/src/sysexits.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)sysexits.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _SYSEXITS_H_ +#define _SYSEXITS_H_ + +/* + * SYSEXITS.H -- Exit status codes for system programs. + * + * This include file attempts to categorize possible error + * exit statuses for system programs, notably delivermail + * and the Berkeley network. + * + * Error numbers begin at EX__BASE to reduce the possibility of + * clashing with other exit statuses that random programs may + * already return. The meaning of the codes is approximately + * as follows: + * + * EX_USAGE -- The command was used incorrectly, e.g., with + * the wrong number of arguments, a bad flag, a bad + * syntax in a parameter, or whatever. + * EX_DATAERR -- The input data was incorrect in some way. + * This should only be used for user's data & not + * system files. + * EX_NOINPUT -- An input file (not a system file) did not + * exist or was not readable. This could also include + * errors like "No message" to a mailer (if it cared + * to catch it). + * EX_NOUSER -- The user specified did not exist. This might + * be used for mail addresses or remote logins. + * EX_NOHOST -- The host specified did not exist. This is used + * in mail addresses or network requests. + * EX_UNAVAILABLE -- A service is unavailable. This can occur + * if a support program or file does not exist. This + * can also be used as a catchall message when something + * you wanted to do doesn't work, but you don't know + * why. + * EX_SOFTWARE -- An internal software error has been detected. + * This should be limited to non-operating system related + * errors as possible. + * EX_OSERR -- An operating system error has been detected. + * This is intended to be used for such things as "cannot + * fork", "cannot create pipe", or the like. It includes + * things like getuid returning a user that does not + * exist in the passwd file. + * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, + * etc.) does not exist, cannot be opened, or has some + * sort of error (e.g., syntax error). + * EX_CANTCREAT -- A (user specified) output file cannot be + * created. + * EX_IOERR -- An error occurred while doing I/O on some file. + * EX_TEMPFAIL -- temporary failure, indicating something that + * is not really an error. In sendmail, this means + * that a mailer (e.g.) could not create a connection, + * and the request should be reattempted later. + * EX_PROTOCOL -- the remote system returned something that + * was "not possible" during a protocol exchange. + * EX_NOPERM -- You did not have sufficient permission to + * perform the operation. This is not intended for + * file system problems, which should use NOINPUT or + * CANTCREAT, but rather for higher level permissions. + */ + +#define EX_OK 0 /* successful termination */ + +#define EX__BASE 64 /* base value for error messages */ + +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ + +#define EX__MAX 78 /* maximum listed value */ + +#endif /* !_SYSEXITS_H_ */ diff --git a/usr.sbin/sendmail/src/trace.c b/usr.sbin/sendmail/src/trace.c new file mode 100644 index 000000000000..9762cab18f59 --- /dev/null +++ b/usr.sbin/sendmail/src/trace.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)trace.c 8.4 (Berkeley) 5/28/95"; +#endif /* not lint */ + +# include "sendmail.h" + +/* +** TtSETUP -- set up for trace package. +** +** Parameters: +** vect -- pointer to trace vector. +** size -- number of flags in trace vector. +** defflags -- flags to set if no value given. +** +** Returns: +** none +** +** Side Effects: +** environment is set up. +*/ + +u_char *tTvect; +int tTsize; +static char *DefFlags; + +void +tTsetup(vect, size, defflags) + u_char *vect; + int size; + char *defflags; +{ + tTvect = vect; + tTsize = size; + DefFlags = defflags; +} +/* +** TtFLAG -- process an external trace flag description. +** +** Parameters: +** s -- the trace flag. +** +** Returns: +** none. +** +** Side Effects: +** sets/clears trace flags. +*/ + +void +tTflag(s) + register char *s; +{ + unsigned int first, last; + register unsigned int i; + + if (*s == '\0') + s = DefFlags; + + for (;;) + { + /* find first flag to set */ + i = 0; + while (isdigit(*s)) + i = i * 10 + (*s++ - '0'); + first = i; + + /* find last flag to set */ + if (*s == '-') + { + i = 0; + while (isdigit(*++s)) + i = i * 10 + (*s - '0'); + } + last = i; + + /* find the level to set it to */ + i = 1; + if (*s == '.') + { + i = 0; + while (isdigit(*++s)) + i = i * 10 + (*s - '0'); + } + + /* clean up args */ + if (first >= tTsize) + first = tTsize - 1; + if (last >= tTsize) + last = tTsize - 1; + + /* set the flags */ + while (first <= last) + tTvect[first++] = i; + + /* more arguments? */ + if (*s++ == '\0') + return; + } +} diff --git a/usr.sbin/sendmail/src/udb.c b/usr.sbin/sendmail/src/udb.c new file mode 100644 index 000000000000..d2b60fc19196 --- /dev/null +++ b/usr.sbin/sendmail/src/udb.c @@ -0,0 +1,1103 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sendmail.h" + +#ifndef lint +#if USERDB +static char sccsid [] = "@(#)udb.c 8.32 (Berkeley) 11/18/95 (with USERDB)"; +#else +static char sccsid [] = "@(#)udb.c 8.32 (Berkeley) 11/18/95 (without USERDB)"; +#endif +#endif + +#if USERDB + +#include <errno.h> + +#ifdef NEWDB +# include <db.h> +#else +# define DBT struct _data_base_thang_ +DBT +{ + void *data; /* pointer to data */ + size_t size; /* length of data */ +}; +#endif + +#ifdef HESIOD +# include <hesiod.h> +#endif /* HESIOD */ + +/* +** UDB.C -- interface between sendmail and Berkeley User Data Base. +** +** This depends on the 4.4BSD db package. +*/ + + +struct udbent +{ + char *udb_spec; /* string version of spec */ + int udb_type; /* type of entry */ + char *udb_default; /* default host for outgoing mail */ + union + { + /* type UE_REMOTE -- do remote call for lookup */ + struct + { + struct sockaddr_in _udb_addr; /* address */ + int _udb_timeout; /* timeout */ + } udb_remote; +#define udb_addr udb_u.udb_remote._udb_addr +#define udb_timeout udb_u.udb_remote._udb_timeout + + /* type UE_FORWARD -- forward message to remote */ + struct + { + char *_udb_fwdhost; /* name of forward host */ + } udb_forward; +#define udb_fwdhost udb_u.udb_forward._udb_fwdhost + +#ifdef NEWDB + /* type UE_FETCH -- lookup in local database */ + struct + { + char *_udb_dbname; /* pathname of database */ + DB *_udb_dbp; /* open database ptr */ + } udb_lookup; +#define udb_dbname udb_u.udb_lookup._udb_dbname +#define udb_dbp udb_u.udb_lookup._udb_dbp +#endif + } udb_u; +}; + +#define UDB_EOLIST 0 /* end of list */ +#define UDB_SKIP 1 /* skip this entry */ +#define UDB_REMOTE 2 /* look up in remote database */ +#define UDB_DBFETCH 3 /* look up in local database */ +#define UDB_FORWARD 4 /* forward to remote host */ +#define UDB_HESIOD 5 /* look up via hesiod */ + +#define MAXUDBENT 10 /* maximum number of UDB entries */ + + +struct option +{ + char *name; + char *val; +}; +/* +** UDBEXPAND -- look up user in database and expand +** +** Parameters: +** a -- address to expand. +** sendq -- pointer to head of sendq to put the expansions in. +** aliaslevel -- the current alias nesting depth. +** e -- the current envelope. +** +** Returns: +** EX_TEMPFAIL -- if something "odd" happened -- probably due +** to accessing a file on an NFS server that is down. +** EX_OK -- otherwise. +** +** Side Effects: +** Modifies sendq. +*/ + +int UdbPort = 1616; +int UdbTimeout = 10; + +struct udbent UdbEnts[MAXUDBENT + 1]; +int UdbSock = -1; +bool UdbInitialized = FALSE; + +int +udbexpand(a, sendq, aliaslevel, e) + register ADDRESS *a; + ADDRESS **sendq; + int aliaslevel; + register ENVELOPE *e; +{ + int i; + DBT key; + DBT info; + bool breakout; + register struct udbent *up; + int keylen; + int naddrs; + char keybuf[MAXKEY]; + char buf[BUFSIZ]; + + if (tTd(28, 1)) + printf("udbexpand(%s)\n", a->q_paddr); + + /* make certain we are supposed to send to this address */ + if (bitset(QDONTSEND|QVERIFIED, a->q_flags)) + return EX_OK; + e->e_to = a->q_paddr; + + /* on first call, locate the database */ + if (!UdbInitialized) + { + extern int _udbx_init(); + + if (_udbx_init() == EX_TEMPFAIL) + return EX_TEMPFAIL; + } + + /* short circuit the process if no chance of a match */ + if (UdbSpec == NULL || UdbSpec[0] == '\0') + return EX_OK; + + /* short circuit name begins with '\\' since it can't possibly match */ + if (a->q_user[0] == '\\') + return EX_OK; + + /* if name is too long, assume it won't match */ + if (strlen(a->q_user) > sizeof keybuf - 12) + return EX_OK; + + /* if name begins with a colon, it indicates our metadata */ + if (a->q_user[0] == ':') + return EX_OK; + + /* build actual database key */ + (void) strcpy(keybuf, a->q_user); + (void) strcat(keybuf, ":maildrop"); + keylen = strlen(keybuf); + + breakout = FALSE; + for (up = UdbEnts; !breakout; up++) + { + char *user; + + /* + ** Select action based on entry type. + ** + ** On dropping out of this switch, "class" should + ** explain the type of the data, and "user" should + ** contain the user information. + */ + + switch (up->udb_type) + { +#ifdef NEWDB + case UDB_DBFETCH: + key.data = keybuf; + key.size = keylen; + if (tTd(28, 80)) + printf("udbexpand: trying %s (%d) via db\n", + keybuf, keylen); + i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_CURSOR); + if (i > 0 || info.size <= 0) + { + if (tTd(28, 2)) + printf("udbexpand: no match on %s (%d)\n", + keybuf, keylen); + continue; + } + if (tTd(28, 80)) + printf("udbexpand: match %.*s: %.*s\n", + key.size, key.data, info.size, info.data); + + naddrs = 0; + a->q_flags &= ~QSELFREF; + while (i == 0 && key.size == keylen && + bcmp(key.data, keybuf, keylen) == 0) + { + if (bitset(EF_VRFYONLY, e->e_flags)) + { + a->q_flags |= QVERIFIED; + return EX_OK; + } + + breakout = TRUE; + if (info.size < sizeof buf) + user = buf; + else + user = xalloc(info.size + 1); + bcopy(info.data, user, info.size); + user[info.size] = '\0'; + + message("expanded to %s", user); +#ifdef LOG + if (LogLevel >= 10) + syslog(LOG_INFO, "%s: expand %.100s => %s", + e->e_id, e->e_to, + shortenstring(user, 203)); +#endif + naddrs += sendtolist(user, a, sendq, aliaslevel + 1, e); + + if (user != buf) + free(user); + + /* get the next record */ + i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_NEXT); + } + + /* if nothing ever matched, try next database */ + if (!breakout) + continue; + + if (naddrs > 0 && !bitset(QSELFREF, a->q_flags)) + { + if (tTd(28, 5)) + { + printf("udbexpand: QDONTSEND "); + printaddr(a, FALSE); + } + a->q_flags |= QDONTSEND; + } + if (i < 0) + { + syserr("udbexpand: db-get %.*s stat %d", + key.size, key.data, i); + return EX_TEMPFAIL; + } + + /* + ** If this address has a -request address, reflect + ** it into the envelope. + */ + + (void) strcpy(keybuf, a->q_user); + (void) strcat(keybuf, ":mailsender"); + keylen = strlen(keybuf); + key.data = keybuf; + key.size = keylen; + i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0); + if (i != 0 || info.size <= 0) + break; + a->q_owner = xalloc(info.size + 1); + bcopy(info.data, a->q_owner, info.size); + a->q_owner[info.size] = '\0'; + + /* announce delivery; NORECEIPT bit set later */ + if (e->e_xfp != NULL) + { + fprintf(e->e_xfp, + "Message delivered to mailing list %s\n", + a->q_paddr); + } + e->e_flags |= EF_SENDRECEIPT; + a->q_flags |= QDELIVERED|QEXPANDED; + break; +#endif + +#ifdef HESIOD + case UDB_HESIOD: + key.data = keybuf; + key.size = keylen; + if (tTd(28, 80)) + printf("udbexpand: trying %s (%d) via hesiod\n", + keybuf, keylen); + /* look up the key via hesiod */ + i = hes_udb_get(&key, &info); + if (i < 0) + { + syserr("udbexpand: hesiod-get %.*s stat %d", + key.size, key.data, i); + return EX_TEMPFAIL; + } + else if (i > 0 || info.size <= 0) + { +#if HES_GETMAILHOST + struct hes_postoffice *hp; +#endif + + if (tTd(28, 2)) + printf("udbexpand: no match on %s (%d)\n", + keybuf, keylen); +#if HES_GETMAILHOST + if (tTd(28, 8)) + printf(" ... trying hes_getmailhost(%s)\n", + a->q_user); + hp = hes_getmailhost(a->q_user); + if (hp == NULL) + { + if (hes_error() == HES_ER_NET) + { + syserr("udbexpand: hesiod-getmail %s stat %d", + a->q_user, hes_error()); + return EX_TEMPFAIL; + } + if (tTd(28, 2)) + printf("hes_getmailhost(%s): %d\n", + a->q_user, hes_error(); + continue; + } + sprintf(info.data, "%s@%s", + hp->po_name, hp->po_host); + info.size = strlen(info.data); +#else + continue; +#endif + } + if (tTd(28, 80)) + printf("udbexpand: match %.*s: %.*s\n", + key.size, key.data, info.size, info.data); + a->q_flags &= ~QSELFREF; + + if (bitset(EF_VRFYONLY, e->e_flags)) + { + a->q_flags |= QVERIFIED; + return EX_OK; + } + + breakout = TRUE; + if (info.size < sizeof buf) + user = buf; + else + user = xalloc(info.size + 1); + bcopy(info.data, user, info.size); + user[info.size] = '\0'; + + message("hesioded to %s", user); +#ifdef LOG + if (LogLevel >= 10) + syslog(LOG_INFO, "%s: hesiod %.100s => %s", + e->e_id, e->e_to, + shortenstring(user, 203)); +#endif + naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e); + + if (user != buf) + free(user); + + if (naddrs > 0 && !bitset(QSELFREF, a->q_flags)) + { + if (tTd(28, 5)) + { + printf("udbexpand: QDONTSEND "); + printaddr(a, FALSE); + } + a->q_flags |= QDONTSEND; + } + + /* + ** If this address has a -request address, reflect + ** it into the envelope. + */ + + (void) strcpy(keybuf, a->q_user); + (void) strcat(keybuf, ":mailsender"); + keylen = strlen(keybuf); + key.data = keybuf; + key.size = keylen; + i = hes_udb_get(&key, &info); + if (i != 0 || info.size <= 0) + break; + a->q_owner = xalloc(info.size + 1); + bcopy(info.data, a->q_owner, info.size); + a->q_owner[info.size] = '\0'; + break; +#endif /* HESIOD */ + + case UDB_REMOTE: + /* not yet implemented */ + continue; + + case UDB_FORWARD: + if (bitset(EF_VRFYONLY, e->e_flags)) + return EX_OK; + i = strlen(up->udb_fwdhost) + strlen(a->q_user) + 1; + if (i < sizeof buf) + user = buf; + else + user = xalloc(i + 1); + (void) sprintf(user, "%s@%s", a->q_user, up->udb_fwdhost); + message("expanded to %s", user); + a->q_flags &= ~QSELFREF; + naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e); + if (naddrs > 0 && !bitset(QSELFREF, a->q_flags)) + { + if (tTd(28, 5)) + { + printf("udbexpand: QDONTSEND "); + printaddr(a, FALSE); + } + a->q_flags |= QDONTSEND; + } + if (user != buf) + free(user); + breakout = TRUE; + break; + + case UDB_EOLIST: + breakout = TRUE; + continue; + + default: + /* unknown entry type */ + continue; + } + } + return EX_OK; +} +/* +** UDBSENDER -- return canonical external name of sender, given local name +** +** Parameters: +** sender -- the name of the sender on the local machine. +** +** Returns: +** The external name for this sender, if derivable from the +** database. +** NULL -- if nothing is changed from the database. +** +** Side Effects: +** none. +*/ + +char * +udbsender(sender) + char *sender; +{ + extern char *udbmatch(); + + return udbmatch(sender, "mailname"); +} + + +char * +udbmatch(user, field) + char *user; + char *field; +{ + register char *p; + register struct udbent *up; + int i; + int keylen; + DBT key, info; + char keybuf[MAXKEY]; + + if (tTd(28, 1)) + printf("udbmatch(%s, %s)\n", user, field); + + if (!UdbInitialized) + { + if (_udbx_init() == EX_TEMPFAIL) + return NULL; + } + + /* short circuit if no spec */ + if (UdbSpec == NULL || UdbSpec[0] == '\0') + return NULL; + + /* short circuit name begins with '\\' since it can't possibly match */ + if (user[0] == '\\') + return NULL; + + /* long names can never match and are a pain to deal with */ + if ((strlen(user) + strlen(field)) > sizeof keybuf - 4) + return NULL; + + /* names beginning with colons indicate metadata */ + if (user[0] == ':') + return NULL; + + /* build database key */ + (void) strcpy(keybuf, user); + (void) strcat(keybuf, ":"); + (void) strcat(keybuf, field); + keylen = strlen(keybuf); + + for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++) + { + /* + ** Select action based on entry type. + */ + + switch (up->udb_type) + { +#ifdef NEWDB + case UDB_DBFETCH: + key.data = keybuf; + key.size = keylen; + i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0); + if (i != 0 || info.size <= 0) + { + if (tTd(28, 2)) + printf("udbmatch: no match on %s (%d) via db\n", + keybuf, keylen); + continue; + } + + p = xalloc(info.size + 1); + bcopy(info.data, p, info.size); + p[info.size] = '\0'; + if (tTd(28, 1)) + printf("udbmatch ==> %s\n", p); + return p; + break; +#endif + +#ifdef HESIOD + case UDB_HESIOD: + key.data = keybuf; + key.size = keylen; + i = hes_udb_get(&key, &info); + if (i != 0 || info.size <= 0) + { + if (tTd(28, 2)) + printf("udbmatch: no match on %s (%d) via hesiod\n", + keybuf, keylen); + continue; + } + + p = xalloc(info.size + 1); + bcopy(info.data, p, info.size); + p[info.size] = '\0'; + if (tTd(28, 1)) + printf("udbmatch ==> %s\n", p); + return p; +#endif /* HESIOD */ + } + } + + if (strcmp(field, "mailname") != 0) + return NULL; + + /* + ** Nothing yet. Search again for a default case. But only + ** use it if we also have a forward (:maildrop) pointer already + ** in the database. + */ + + /* build database key */ + (void) strcpy(keybuf, user); + (void) strcat(keybuf, ":maildrop"); + keylen = strlen(keybuf); + + for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++) + { + switch (up->udb_type) + { +#ifdef NEWDB + case UDB_DBFETCH: + /* get the default case for this database */ + if (up->udb_default == NULL) + { + key.data = ":default:mailname"; + key.size = strlen(key.data); + i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0); + if (i != 0 || info.size <= 0) + { + /* no default case */ + up->udb_default = ""; + continue; + } + + /* save the default case */ + up->udb_default = xalloc(info.size + 1); + bcopy(info.data, up->udb_default, info.size); + up->udb_default[info.size] = '\0'; + } + else if (up->udb_default[0] == '\0') + continue; + + /* we have a default case -- verify user:maildrop */ + key.data = keybuf; + key.size = keylen; + i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0); + if (i != 0 || info.size <= 0) + { + /* nope -- no aliasing for this user */ + continue; + } + + /* they exist -- build the actual address */ + p = xalloc(strlen(user) + strlen(up->udb_default) + 2); + (void) strcpy(p, user); + (void) strcat(p, "@"); + (void) strcat(p, up->udb_default); + if (tTd(28, 1)) + printf("udbmatch ==> %s\n", p); + return p; + break; +#endif + +#ifdef HESIOD + case UDB_HESIOD: + /* get the default case for this database */ + if (up->udb_default == NULL) + { + key.data = ":default:mailname"; + key.size = strlen(key.data); + i = hes_udb_get(&key, &info); + + if (i != 0 || info.size <= 0) + { + /* no default case */ + up->udb_default = ""; + continue; + } + + /* save the default case */ + up->udb_default = xalloc(info.size + 1); + bcopy(info.data, up->udb_default, info.size); + up->udb_default[info.size] = '\0'; + } + else if (up->udb_default[0] == '\0') + continue; + + /* we have a default case -- verify user:maildrop */ + key.data = keybuf; + key.size = keylen; + i = hes_udb_get(&key, &info); + if (i != 0 || info.size <= 0) + { + /* nope -- no aliasing for this user */ + continue; + } + + /* they exist -- build the actual address */ + p = xalloc(strlen(user) + strlen(up->udb_default) + 2); + (void) strcpy(p, user); + (void) strcat(p, "@"); + (void) strcat(p, up->udb_default); + if (tTd(28, 1)) + printf("udbmatch ==> %s\n", p); + return p; + break; +#endif /* HESIOD */ + } + } + + /* still nothing.... too bad */ + return NULL; +} +/* +** UDB_MAP_LOOKUP -- look up arbitrary entry in user database map +** +** Parameters: +** map -- the map being queried. +** name -- the name to look up. +** av -- arguments to the map lookup. +** statp -- to get any error status. +** +** Returns: +** NULL if name not found in map. +** The rewritten name otherwise. +*/ + +char * +udb_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + char *val; + char *key; + char keybuf[MAXNAME + 1]; + + if (tTd(28, 20) || tTd(38, 20)) + printf("udb_map_lookup(%s, %s)\n", map->map_mname, name); + + if (bitset(MF_NOFOLDCASE, map->map_mflags)) + { + key = name; + } + else + { + int keysize = strlen(name); + + if (keysize > sizeof keybuf - 1) + keysize = sizeof keybuf - 1; + bcopy(name, keybuf, keysize); + keybuf[keysize] = '\0'; + makelower(keybuf); + key = keybuf; + } + val = udbmatch(key, map->map_file); + if (val == NULL) + return NULL; + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, name, strlen(name), NULL); + else + return map_rewrite(map, val, strlen(val), av); +} +/* +** _UDBX_INIT -- parse the UDB specification, opening any valid entries. +** +** Parameters: +** none. +** +** Returns: +** EX_TEMPFAIL -- if it appeared it couldn't get hold of a +** database due to a host being down or some similar +** (recoverable) situation. +** EX_OK -- otherwise. +** +** Side Effects: +** Fills in the UdbEnts structure from UdbSpec. +*/ + +#define MAXUDBOPTS 27 + +int +_udbx_init() +{ + register char *p; + register struct udbent *up; + + if (UdbInitialized) + return EX_OK; + +# ifdef UDB_DEFAULT_SPEC + if (UdbSpec == NULL) + UdbSpec = UDB_DEFAULT_SPEC; +# endif + + p = UdbSpec; + up = UdbEnts; + while (p != NULL) + { + char *spec; + int nopts; +# if 0 + auto int rcode; + int nmx; + int i; + register struct hostent *h; + char *mxhosts[MAXMXHOSTS + 1]; +# endif + struct option opts[MAXUDBOPTS + 1]; + + while (*p == ' ' || *p == '\t' || *p == ',') + p++; + if (*p == '\0') + break; + spec = p; + p = strchr(p, ','); + if (p != NULL) + *p++ = '\0'; + + /* extract options */ + nopts = _udb_parsespec(spec, opts, MAXUDBOPTS); + + /* + ** Decode database specification. + ** + ** In the sendmail tradition, the leading character + ** defines the semantics of the rest of the entry. + ** + ** +hostname -- send a datagram to the udb server + ** on host "hostname" asking for the + ** home mail server for this user. + ** *hostname -- similar to +hostname, except that the + ** hostname is searched as an MX record; + ** resulting hosts are searched as for + ** +mxhostname. If no MX host is found, + ** this is the same as +hostname. + ** @hostname -- forward email to the indicated host. + ** This should be the last in the list, + ** since it always matches the input. + ** /dbname -- search the named database on the local + ** host using the Berkeley db package. + ** Hesiod -- search the named database with BIND + ** using the MIT Hesiod package. + */ + + switch (*spec) + { +#if 0 + case '+': /* search remote database */ + case '*': /* search remote database (expand MX) */ + if (*spec == '*') + { +#if NAMED_BIND + nmx = getmxrr(spec + 1, mxhosts, FALSE, &rcode); +#else + mxhosts[0] = spec + 1; + nmx = 1; + rcode = 0; +#endif + if (tTd(28, 16)) + { + int i; + + printf("getmxrr(%s): %d", spec + 1, nmx); + for (i = 0; i <= nmx; i++) + printf(" %s", mxhosts[i]); + printf("\n"); + } + } + else + { + nmx = 1; + mxhosts[0] = spec + 1; + } + + for (i = 0; i < nmx; i++) + { + h = sm_gethostbyname(mxhosts[i]); + if (h == NULL) + continue; + up->udb_type = UDB_REMOTE; + up->udb_addr.sin_family = h->h_addrtype; + bcopy(h->h_addr_list[0], + (char *) &up->udb_addr.sin_addr, + INADDRSZ); + up->udb_addr.sin_port = UdbPort; + up->udb_timeout = UdbTimeout; + up++; + } + + /* set up a datagram socket */ + if (UdbSock < 0) + { + UdbSock = socket(AF_INET, SOCK_DGRAM, 0); + (void) fcntl(UdbSock, F_SETFD, 1); + } + break; +#endif + + case '@': /* forward to remote host */ + up->udb_type = UDB_FORWARD; + up->udb_fwdhost = spec + 1; + up++; + break; + +#ifdef HESIOD + case 'h': /* use hesiod */ + case 'H': + if (strcasecmp(spec, "hesiod") != 0) + goto badspec; + up->udb_type = UDB_HESIOD; + up++; + break; +#endif /* HESIOD */ + +#ifdef NEWDB + case '/': /* look up remote name */ + up->udb_dbname = spec; + errno = 0; + up->udb_dbp = dbopen(spec, O_RDONLY, 0644, DB_BTREE, NULL); + if (up->udb_dbp == NULL) + { + if (tTd(28, 1)) + { + int saveerrno = errno; + + printf("dbopen(%s): %s", + spec, errstring(errno)); + errno = saveerrno; + } + if (errno != ENOENT && errno != EACCES) + { +#ifdef LOG + if (LogLevel > 2) + syslog(LOG_ERR, "dbopen(%s): %s", + spec, errstring(errno)); +#endif + up->udb_type = UDB_EOLIST; + goto tempfail; + } + break; + } + up->udb_type = UDB_DBFETCH; + up++; + break; +#endif + + default: +badspec: + syserr("Unknown UDB spec %s", spec); + break; + } + } + up->udb_type = UDB_EOLIST; + + if (tTd(28, 4)) + { + for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++) + { + switch (up->udb_type) + { +#ifdef DAEMON + case UDB_REMOTE: + printf("REMOTE: addr %s, timeo %d\n", + anynet_ntoa((SOCKADDR *) &up->udb_addr), + up->udb_timeout); + break; +#endif + + case UDB_DBFETCH: +#ifdef NEWDB + printf("FETCH: file %s\n", + up->udb_dbname); +#else + printf("FETCH\n"); +#endif + break; + + case UDB_FORWARD: + printf("FORWARD: host %s\n", + up->udb_fwdhost); + break; + + case UDB_HESIOD: + printf("HESIOD\n"); + break; + + default: + printf("UNKNOWN\n"); + break; + } + } + } + + UdbInitialized = TRUE; + errno = 0; + return EX_OK; + + /* + ** On temporary failure, back out anything we've already done + */ + + tempfail: +#ifdef NEWDB + for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++) + { + if (up->udb_type == UDB_DBFETCH) + { + (*up->udb_dbp->close)(up->udb_dbp); + } + } +#endif + return EX_TEMPFAIL; +} + +int +_udb_parsespec(udbspec, opt, maxopts) + char *udbspec; + struct option opt[]; + int maxopts; +{ + register char *spec; + register char *spec_end; + register int optnum; + + spec_end = strchr(udbspec, ':'); + for (optnum = 0; optnum < maxopts && (spec = spec_end) != NULL; optnum++) + { + register char *p; + + while (isascii(*spec) && isspace(*spec)) + spec++; + spec_end = strchr(spec, ':'); + if (spec_end != NULL) + *spec_end++ = '\0'; + + opt[optnum].name = spec; + opt[optnum].val = NULL; + p = strchr(spec, '='); + if (p != NULL) + opt[optnum].val = ++p; + } + return optnum; +} + +#ifdef HESIOD + +int +hes_udb_get(key, info) + DBT *key; + DBT *info; +{ + char *name, *type; + char *p, **hp; + char kbuf[MAXKEY + 1]; + + strcpy(kbuf, key->data); + name = kbuf; + type = strrchr(name, ':'); + if (type == NULL) + return 1; + *type++ = '\0'; + if (strchr(name, '@') != NULL) + return 1; + + if (tTd(28, 1)) + printf("hes_udb_get(%s, %s)\n", name, type); + + /* make the hesiod query */ + hp = hes_resolve(name, type); + *--type = ':'; + if (hp == NULL || hp[0] == NULL) + { + /* network problem or timeout */ + if (hes_error() == HES_ER_NET) + return -1; + + return 1; + } + else + { + /* + ** If there are multiple matches, just return the + ** first one. + ** + ** XXX These should really be returned; for example, + ** XXX it is legal for :maildrop to be multi-valued. + */ + + info->data = hp[0]; + info->size = (size_t) strlen(info->data); + } + + if (tTd(28, 80)) + printf("hes_udb_get => %s\n", *hp); + + return 0; +} +#endif /* HESIOD */ + +#else /* not USERDB */ + +int +udbexpand(a, sendq, aliaslevel, e) + ADDRESS *a; + ADDRESS **sendq; + int aliaslevel; + ENVELOPE *e; +{ + return EX_OK; +} + +#endif /* USERDB */ diff --git a/usr.sbin/sendmail/src/useful.h b/usr.sbin/sendmail/src/useful.h new file mode 100644 index 000000000000..8f9009ecf0b0 --- /dev/null +++ b/usr.sbin/sendmail/src/useful.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)useful.h 8.4 (Berkeley) 4/21/95 + */ + +# include <sys/types.h> + +/* support for bool type */ +typedef int bool; +# define TRUE 1 +# define FALSE 0 + +# ifndef NULL +# define NULL 0 +# endif /* NULL */ + +/* bit hacking */ +# define bitset(bit, word) (((word) & (bit)) != 0) + +/* some simple functions */ +# ifndef max +# define max(a, b) ((a) > (b) ? (a) : (b)) +# define min(a, b) ((a) < (b) ? (a) : (b)) +# endif + +/* assertions */ +# ifndef NASSERT +# define ASSERT(expr, msg, parm)\ + if (!(expr))\ + {\ + fprintf(stderr, "assertion botch: %s:%d: ", __FILE__, __LINE__);\ + fprintf(stderr, msg, parm);\ + } +# else /* NASSERT */ +# define ASSERT(expr, msg, parm) +# endif /* NASSERT */ + +/* sccs id's */ +# ifndef lint +# ifdef __STDC__ +# define SCCSID(arg) static char SccsId[] = #arg; +# else +# define SCCSID(arg) static char SccsId[] = "arg"; +# endif +# else +# define SCCSID(arg) +# endif diff --git a/usr.sbin/sendmail/src/usersmtp.c b/usr.sbin/sendmail/src/usersmtp.c new file mode 100644 index 000000000000..d33bd5ed3d81 --- /dev/null +++ b/usr.sbin/sendmail/src/usersmtp.c @@ -0,0 +1,1055 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +# include "sendmail.h" + +#ifndef lint +#ifdef SMTP +static char sccsid[] = "@(#)usersmtp.c 8.65 (Berkeley) 9/28/95 (with SMTP)"; +#else +static char sccsid[] = "@(#)usersmtp.c 8.65 (Berkeley) 9/28/95 (without SMTP)"; +#endif +#endif /* not lint */ + +# include <sysexits.h> +# include <errno.h> + +# ifdef SMTP + +/* +** USERSMTP -- run SMTP protocol from the user end. +** +** This protocol is described in RFC821. +*/ + +#define REPLYTYPE(r) ((r) / 100) /* first digit of reply code */ +#define REPLYCLASS(r) (((r) / 10) % 10) /* second digit of reply code */ +#define SMTPCLOSING 421 /* "Service Shutting Down" */ + +char SmtpMsgBuffer[MAXLINE]; /* buffer for commands */ +char SmtpReplyBuffer[MAXLINE]; /* buffer for replies */ +char SmtpError[MAXLINE] = ""; /* save failure error messages */ +int SmtpPid; /* pid of mailer */ +bool SmtpNeedIntro; /* need "while talking" in transcript */ + +extern void smtpmessage __P((char *f, MAILER *m, MCI *mci, ...)); +/* +** SMTPINIT -- initialize SMTP. +** +** Opens the connection and sends the initial protocol. +** +** Parameters: +** m -- mailer to create connection to. +** pvp -- pointer to parameter vector to pass to +** the mailer. +** +** Returns: +** none. +** +** Side Effects: +** creates connection and sends initial protocol. +*/ + +void +smtpinit(m, mci, e) + struct mailer *m; + register MCI *mci; + ENVELOPE *e; +{ + register int r; + register char *p; + extern void esmtp_check(); + extern void helo_options(); + + if (tTd(18, 1)) + { + printf("smtpinit "); + mci_dump(mci, FALSE); + } + + /* + ** Open the connection to the mailer. + */ + + SmtpError[0] = '\0'; + CurHostName = mci->mci_host; /* XXX UGLY XXX */ + if (CurHostName == NULL) + CurHostName = MyHostName; + SmtpNeedIntro = TRUE; + switch (mci->mci_state) + { + case MCIS_ACTIVE: + /* need to clear old information */ + smtprset(m, mci, e); + /* fall through */ + + case MCIS_OPEN: + return; + + case MCIS_ERROR: + case MCIS_SSD: + /* shouldn't happen */ + smtpquit(m, mci, e); + /* fall through */ + + case MCIS_CLOSED: + syserr("451 smtpinit: state CLOSED"); + return; + + case MCIS_OPENING: + break; + } + + mci->mci_state = MCIS_OPENING; + + /* + ** Get the greeting message. + ** This should appear spontaneously. Give it five minutes to + ** happen. + */ + + SmtpPhase = mci->mci_phase = "client greeting"; + setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); + r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check); + if (r < 0 || REPLYTYPE(r) == 4) + goto tempfail1; + if (REPLYTYPE(r) != 2) + goto unavailable; + + /* + ** Send the HELO command. + ** My mother taught me to always introduce myself. + */ + + if (bitnset(M_ESMTP, m->m_flags)) + mci->mci_flags |= MCIF_ESMTP; + +tryhelo: + if (bitset(MCIF_ESMTP, mci->mci_flags)) + { + smtpmessage("EHLO %s", m, mci, MyHostName); + SmtpPhase = mci->mci_phase = "client EHLO"; + } + else + { + smtpmessage("HELO %s", m, mci, MyHostName); + SmtpPhase = mci->mci_phase = "client HELO"; + } + setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); + r = reply(m, mci, e, TimeOuts.to_helo, helo_options); + if (r < 0) + goto tempfail1; + else if (REPLYTYPE(r) == 5) + { + if (bitset(MCIF_ESMTP, mci->mci_flags)) + { + /* try old SMTP instead */ + mci->mci_flags &= ~MCIF_ESMTP; + goto tryhelo; + } + goto unavailable; + } + else if (REPLYTYPE(r) != 2) + goto tempfail1; + + /* + ** Check to see if we actually ended up talking to ourself. + ** This means we didn't know about an alias or MX, or we managed + ** to connect to an echo server. + */ + + p = strchr(&SmtpReplyBuffer[4], ' '); + if (p != NULL) + *p = '\0'; + if (!bitnset(M_NOLOOPCHECK, m->m_flags) && + strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0) + { + syserr("553 %s config error: mail loops back to me (MX problem?)", + mci->mci_host); + mci->mci_exitstat = EX_CONFIG; + mci->mci_errno = 0; + smtpquit(m, mci, e); + return; + } + + /* + ** If this is expected to be another sendmail, send some internal + ** commands. + */ + + if (bitnset(M_INTERNAL, m->m_flags)) + { + /* tell it to be verbose */ + smtpmessage("VERB", m, mci); + r = reply(m, mci, e, TimeOuts.to_miscshort, NULL); + if (r < 0) + goto tempfail2; + } + + if (mci->mci_state != MCIS_CLOSED) + { + mci->mci_state = MCIS_OPEN; + return; + } + + /* got a 421 error code during startup */ + + tempfail1: + tempfail2: + mci->mci_exitstat = EX_TEMPFAIL; + if (mci->mci_errno == 0) + mci->mci_errno = errno; + if (mci->mci_state != MCIS_CLOSED) + smtpquit(m, mci, e); + return; + + unavailable: + mci->mci_exitstat = EX_UNAVAILABLE; + mci->mci_errno = errno; + smtpquit(m, mci, e); + return; +} +/* +** ESMTP_CHECK -- check to see if this implementation likes ESMTP protocol +** +** Parameters: +** line -- the response line. +** firstline -- set if this is the first line of the reply. +** m -- the mailer. +** mci -- the mailer connection info. +** e -- the envelope. +** +** Returns: +** none. +*/ + +void +esmtp_check(line, firstline, m, mci, e) + char *line; + bool firstline; + MAILER *m; + register MCI *mci; + ENVELOPE *e; +{ + if (strstr(line, "ESMTP") != NULL) + mci->mci_flags |= MCIF_ESMTP; + if (strstr(line, "8BIT-OK") != NULL) + mci->mci_flags |= MCIF_8BITOK; +} +/* +** HELO_OPTIONS -- process the options on a HELO line. +** +** Parameters: +** line -- the response line. +** firstline -- set if this is the first line of the reply. +** m -- the mailer. +** mci -- the mailer connection info. +** e -- the envelope. +** +** Returns: +** none. +*/ + +void +helo_options(line, firstline, m, mci, e) + char *line; + bool firstline; + MAILER *m; + register MCI *mci; + ENVELOPE *e; +{ + register char *p; + + if (firstline) + return; + + if (strlen(line) < (SIZE_T) 5) + return; + line += 4; + p = strchr(line, ' '); + if (p != NULL) + *p++ = '\0'; + if (strcasecmp(line, "size") == 0) + { + mci->mci_flags |= MCIF_SIZE; + if (p != NULL) + mci->mci_maxsize = atol(p); + } + else if (strcasecmp(line, "8bitmime") == 0) + { + mci->mci_flags |= MCIF_8BITMIME; + mci->mci_flags &= ~MCIF_7BIT; + } + else if (strcasecmp(line, "expn") == 0) + mci->mci_flags |= MCIF_EXPN; + else if (strcasecmp(line, "dsn") == 0) + mci->mci_flags |= MCIF_DSN; +} +/* +** SMTPMAILFROM -- send MAIL command +** +** Parameters: +** m -- the mailer. +** mci -- the mailer connection structure. +** e -- the envelope (including the sender to specify). +*/ + +int +smtpmailfrom(m, mci, e) + struct mailer *m; + MCI *mci; + ENVELOPE *e; +{ + int r; + char *bufp; + char *bodytype; + char buf[MAXNAME + 1]; + char optbuf[MAXLINE]; + + if (tTd(18, 2)) + printf("smtpmailfrom: CurHost=%s\n", CurHostName); + + /* set up appropriate options to include */ + if (bitset(MCIF_SIZE, mci->mci_flags) && e->e_msgsize > 0) + sprintf(optbuf, " SIZE=%ld", e->e_msgsize); + else + strcpy(optbuf, ""); + + bodytype = e->e_bodytype; + if (bitset(MCIF_8BITMIME, mci->mci_flags)) + { + if (bodytype == NULL && + bitset(MM_MIME8BIT, MimeMode) && + bitset(EF_HAS8BIT, e->e_flags) && + !bitset(EF_DONT_MIME, e->e_flags) && + !bitnset(M_8BITS, m->m_flags)) + bodytype = "8BITMIME"; + if (bodytype != NULL) + { + strcat(optbuf, " BODY="); + strcat(optbuf, bodytype); + } + } + else if (bitnset(M_8BITS, m->m_flags) || + !bitset(EF_HAS8BIT, e->e_flags) || + bitset(MCIF_8BITOK, mci->mci_flags)) + { + /* just pass it through */ + } +#if MIME8TO7 + else if (bitset(MM_CVTMIME, MimeMode) && + !bitset(EF_DONT_MIME, e->e_flags) && + (!bitset(MM_PASS8BIT, MimeMode) || + bitset(EF_IS_MIME, e->e_flags))) + { + /* must convert from 8bit MIME format to 7bit encoded */ + mci->mci_flags |= MCIF_CVT8TO7; + } +#endif + else if (!bitset(MM_PASS8BIT, MimeMode)) + { + /* cannot just send a 8-bit version */ + usrerr("%s does not support 8BITMIME", mci->mci_host); + mci->mci_status = "5.6.3"; + return EX_DATAERR; + } + + if (bitset(MCIF_DSN, mci->mci_flags)) + { + if (e->e_envid != NULL) + { + strcat(optbuf, " ENVID="); + strcat(optbuf, e->e_envid); + } + + /* RET= parameter */ + if (bitset(EF_RET_PARAM, e->e_flags)) + { + strcat(optbuf, " RET="); + if (bitset(EF_NO_BODY_RETN, e->e_flags)) + strcat(optbuf, "HDRS"); + else + strcat(optbuf, "FULL"); + } + } + + /* + ** Send the MAIL command. + ** Designates the sender. + */ + + mci->mci_state = MCIS_ACTIVE; + + if (bitset(EF_RESPONSE, e->e_flags) && + !bitnset(M_NO_NULL_FROM, m->m_flags)) + (void) strcpy(buf, ""); + else + expand("\201g", buf, sizeof buf, e); + if (buf[0] == '<') + { + /* strip off <angle brackets> (put back on below) */ + bufp = &buf[strlen(buf) - 1]; + if (*bufp == '>') + *bufp = '\0'; + bufp = &buf[1]; + } + else + bufp = buf; + if (bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags) || + !bitnset(M_FROMPATH, m->m_flags)) + { + smtpmessage("MAIL From:<%s>%s", m, mci, bufp, optbuf); + } + else + { + smtpmessage("MAIL From:<@%s%c%s>%s", m, mci, MyHostName, + *bufp == '@' ? ',' : ':', bufp, optbuf); + } + SmtpPhase = mci->mci_phase = "client MAIL"; + setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); + r = reply(m, mci, e, TimeOuts.to_mail, NULL); + if (r < 0 || r == 421) + { + /* communications failure/service shutting down */ + mci->mci_exitstat = EX_TEMPFAIL; + mci->mci_errno = errno; + smtpquit(m, mci, e); + return EX_TEMPFAIL; + } + else if (REPLYTYPE(r) == 4) + { + return EX_TEMPFAIL; + } + else if (REPLYTYPE(r) == 2) + { + return EX_OK; + } + else if (r == 501) + { + /* syntax error in arguments */ + mci->mci_status = "5.5.2"; + return EX_DATAERR; + } + else if (r == 553) + { + /* mailbox name not allowed */ + mci->mci_status = "5.1.3"; + return EX_DATAERR; + } + else if (r == 552) + { + /* exceeded storage allocation */ + mci->mci_status = "5.2.2"; + return EX_UNAVAILABLE; + } + else if (REPLYTYPE(r) == 5) + { + /* unknown error */ + return EX_UNAVAILABLE; + } + +#ifdef LOG + if (LogLevel > 1) + { + syslog(LOG_CRIT, "%s: %.100s: SMTP MAIL protocol error: %s", + e->e_id, mci->mci_host, + shortenstring(SmtpReplyBuffer, 403)); + } +#endif + + /* protocol error -- close up */ + smtpquit(m, mci, e); + return EX_PROTOCOL; +} +/* +** SMTPRCPT -- designate recipient. +** +** Parameters: +** to -- address of recipient. +** m -- the mailer we are sending to. +** mci -- the connection info for this transaction. +** e -- the envelope for this transaction. +** +** Returns: +** exit status corresponding to recipient status. +** +** Side Effects: +** Sends the mail via SMTP. +*/ + +int +smtprcpt(to, m, mci, e) + ADDRESS *to; + register MAILER *m; + MCI *mci; + ENVELOPE *e; +{ + register int r; + char optbuf[MAXLINE]; + extern char *smtptodsn(); + + strcpy(optbuf, ""); + if (bitset(MCIF_DSN, mci->mci_flags)) + { + /* NOTIFY= parameter */ + if (bitset(QHASNOTIFY, to->q_flags) && + bitset(QPRIMARY, to->q_flags)) + { + bool firstone = TRUE; + + strcat(optbuf, " NOTIFY="); + if (bitset(QPINGONSUCCESS, to->q_flags)) + { + strcat(optbuf, "SUCCESS"); + firstone = FALSE; + } + if (bitset(QPINGONFAILURE, to->q_flags)) + { + if (!firstone) + strcat(optbuf, ","); + strcat(optbuf, "FAILURE"); + firstone = FALSE; + } + if (bitset(QPINGONDELAY, to->q_flags)) + { + if (!firstone) + strcat(optbuf, ","); + strcat(optbuf, "DELAY"); + firstone = FALSE; + } + if (firstone) + strcat(optbuf, "NEVER"); + } + + /* ORCPT= parameter */ + if (to->q_orcpt != NULL) + { + strcat(optbuf, " ORCPT="); + strcat(optbuf, to->q_orcpt); + } + } + + smtpmessage("RCPT To:<%s>%s", m, mci, to->q_user, optbuf); + + SmtpPhase = mci->mci_phase = "client RCPT"; + setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); + r = reply(m, mci, e, TimeOuts.to_rcpt, NULL); + to->q_rstatus = newstr(SmtpReplyBuffer); + to->q_status = smtptodsn(r); + to->q_statmta = mci->mci_host; + if (r < 0 || REPLYTYPE(r) == 4) + return EX_TEMPFAIL; + else if (REPLYTYPE(r) == 2) + return EX_OK; + else if (r == 550 || r == 551 || r == 553) + return EX_NOUSER; + else if (REPLYTYPE(r) == 5) + return EX_UNAVAILABLE; + +#ifdef LOG + if (LogLevel > 1) + { + syslog(LOG_CRIT, "%s: %.100s: SMTP RCPT protocol error: %s", + e->e_id, mci->mci_host, + shortenstring(SmtpReplyBuffer, 403)); + } +#endif + + return EX_PROTOCOL; +} +/* +** SMTPDATA -- send the data and clean up the transaction. +** +** Parameters: +** m -- mailer being sent to. +** e -- the envelope for this message. +** +** Returns: +** exit status corresponding to DATA command. +** +** Side Effects: +** none. +*/ + +static jmp_buf CtxDataTimeout; +static void datatimeout(); + +int +smtpdata(m, mci, e) + struct mailer *m; + register MCI *mci; + register ENVELOPE *e; +{ + register int r; + register EVENT *ev; + time_t timeout; + + /* + ** Send the data. + ** First send the command and check that it is ok. + ** Then send the data. + ** Follow it up with a dot to terminate. + ** Finally get the results of the transaction. + */ + + /* send the command and check ok to proceed */ + smtpmessage("DATA", m, mci); + SmtpPhase = mci->mci_phase = "client DATA 354"; + setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); + r = reply(m, mci, e, TimeOuts.to_datainit, NULL); + if (r < 0 || REPLYTYPE(r) == 4) + { + smtpquit(m, mci, e); + return EX_TEMPFAIL; + } + else if (REPLYTYPE(r) == 5) + { + smtprset(m, mci, e); + return EX_UNAVAILABLE; + } + else if (r != 354) + { +#ifdef LOG + if (LogLevel > 1) + { + syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-1 protocol error: %s", + e->e_id, mci->mci_host, + shortenstring(SmtpReplyBuffer, 403)); + } +#endif + smtprset(m, mci, e); + return (EX_PROTOCOL); + } + + /* + ** Set timeout around data writes. Make it at least large + ** enough for DNS timeouts on all recipients plus some fudge + ** factor. The main thing is that it should not be infinite. + */ + + if (setjmp(CtxDataTimeout) != 0) + { + mci->mci_errno = errno; + mci->mci_exitstat = EX_TEMPFAIL; + mci->mci_state = MCIS_ERROR; + syserr("451 timeout writing message to %s", mci->mci_host); + smtpquit(m, mci, e); + return EX_TEMPFAIL; + } + + timeout = e->e_msgsize / 16; + if (timeout < (time_t) 600) + timeout = (time_t) 600; + timeout += e->e_nrcpts * 300; + ev = setevent(timeout, datatimeout, 0); + + /* + ** Output the actual message. + */ + + (*e->e_puthdr)(mci, e->e_header, e); + (*e->e_putbody)(mci, e, NULL); + + /* + ** Cleanup after sending message. + */ + + clrevent(ev); + + if (ferror(mci->mci_out)) + { + /* error during processing -- don't send the dot */ + mci->mci_errno = EIO; + mci->mci_exitstat = EX_IOERR; + mci->mci_state = MCIS_ERROR; + smtpquit(m, mci, e); + return EX_IOERR; + } + + /* terminate the message */ + fprintf(mci->mci_out, ".%s", m->m_eol); + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%05d >>> .\n", getpid()); + if (Verbose) + nmessage(">>> ."); + + /* check for the results of the transaction */ + SmtpPhase = mci->mci_phase = "client DATA 250"; + setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); + r = reply(m, mci, e, TimeOuts.to_datafinal, NULL); + if (r < 0) + { + smtpquit(m, mci, e); + return EX_TEMPFAIL; + } + mci->mci_state = MCIS_OPEN; + e->e_statmsg = newstr(&SmtpReplyBuffer[4]); + if (REPLYTYPE(r) == 4) + return EX_TEMPFAIL; + else if (REPLYCLASS(r) != 5) + /* fall through */ ; + else if (REPLYTYPE(r) == 2) + return EX_OK; + else if (REPLYTYPE(r) == 5) + return EX_UNAVAILABLE; +#ifdef LOG + if (LogLevel > 1) + { + syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-2 protocol error: %s", + e->e_id, mci->mci_host, + shortenstring(SmtpReplyBuffer, 403)); + } +#endif + return EX_PROTOCOL; +} + + +static void +datatimeout() +{ + longjmp(CtxDataTimeout, 1); +} +/* +** SMTPQUIT -- close the SMTP connection. +** +** Parameters: +** m -- a pointer to the mailer. +** +** Returns: +** none. +** +** Side Effects: +** sends the final protocol and closes the connection. +*/ + +void +smtpquit(m, mci, e) + register MAILER *m; + register MCI *mci; + ENVELOPE *e; +{ + bool oldSuprErrs = SuprErrs; + + /* + ** Suppress errors here -- we may be processing a different + ** job when we do the quit connection, and we don't want the + ** new job to be penalized for something that isn't it's + ** problem. + */ + + SuprErrs = TRUE; + + /* send the quit message if we haven't gotten I/O error */ + if (mci->mci_state != MCIS_ERROR) + { + SmtpPhase = "client QUIT"; + smtpmessage("QUIT", m, mci); + (void) reply(m, mci, e, TimeOuts.to_quit, NULL); + SuprErrs = oldSuprErrs; + if (mci->mci_state == MCIS_CLOSED) + { + SuprErrs = oldSuprErrs; + return; + } + } + + /* now actually close the connection and pick up the zombie */ + (void) endmailer(mci, e, NULL); + + SuprErrs = oldSuprErrs; +} +/* +** SMTPRSET -- send a RSET (reset) command +*/ + +void +smtprset(m, mci, e) + register MAILER *m; + register MCI *mci; + ENVELOPE *e; +{ + int r; + + SmtpPhase = "client RSET"; + smtpmessage("RSET", m, mci); + r = reply(m, mci, e, TimeOuts.to_rset, NULL); + if (r < 0) + mci->mci_state = MCIS_ERROR; + else if (REPLYTYPE(r) == 2) + { + mci->mci_state = MCIS_OPEN; + return; + } + smtpquit(m, mci, e); +} +/* +** SMTPPROBE -- check the connection state +*/ + +int +smtpprobe(mci) + register MCI *mci; +{ + int r; + MAILER *m = mci->mci_mailer; + extern ENVELOPE BlankEnvelope; + ENVELOPE *e = &BlankEnvelope; + + SmtpPhase = "client probe"; + smtpmessage("RSET", m, mci); + r = reply(m, mci, e, TimeOuts.to_miscshort, NULL); + if (r < 0 || REPLYTYPE(r) != 2) + smtpquit(m, mci, e); + return r; +} +/* +** REPLY -- read arpanet reply +** +** Parameters: +** m -- the mailer we are reading the reply from. +** mci -- the mailer connection info structure. +** e -- the current envelope. +** timeout -- the timeout for reads. +** pfunc -- processing function called on each line of response. +** If null, no special processing is done. +** +** Returns: +** reply code it reads. +** +** Side Effects: +** flushes the mail file. +*/ + +int +reply(m, mci, e, timeout, pfunc) + MAILER *m; + MCI *mci; + ENVELOPE *e; + time_t timeout; + void (*pfunc)(); +{ + register char *bufp; + register int r; + bool firstline = TRUE; + char junkbuf[MAXLINE]; + + if (mci->mci_out != NULL) + (void) fflush(mci->mci_out); + + if (tTd(18, 1)) + printf("reply\n"); + + /* + ** Read the input line, being careful not to hang. + */ + + for (bufp = SmtpReplyBuffer;; bufp = junkbuf) + { + register char *p; + extern time_t curtime(); + + /* actually do the read */ + if (e->e_xfp != NULL) + (void) fflush(e->e_xfp); /* for debugging */ + + /* if we are in the process of closing just give the code */ + if (mci->mci_state == MCIS_CLOSED) + return (SMTPCLOSING); + + if (mci->mci_out != NULL) + fflush(mci->mci_out); + + /* get the line from the other side */ + p = sfgets(bufp, MAXLINE, mci->mci_in, timeout, SmtpPhase); + mci->mci_lastuse = curtime(); + + if (p == NULL) + { + bool oldholderrs; + + /* if the remote end closed early, fake an error */ + if (errno == 0) +# ifdef ECONNRESET + errno = ECONNRESET; +# else /* ECONNRESET */ + errno = EPIPE; +# endif /* ECONNRESET */ + + mci->mci_errno = errno; + mci->mci_exitstat = EX_TEMPFAIL; + oldholderrs = HoldErrs; + HoldErrs = TRUE; + usrerr("451 reply: read error from %s", mci->mci_host); + + /* if debugging, pause so we can see state */ + if (tTd(18, 100)) + pause(); + mci->mci_state = MCIS_ERROR; + smtpquit(m, mci, e); +#if XDEBUG + { + char wbuf[MAXLINE]; + char *p = wbuf; + + if (e->e_to != NULL) + { + sprintf(p, "%s... ", + shortenstring(e->e_to, 203)); + p += strlen(p); + } + sprintf(p, "reply(%.100s) during %s", + mci->mci_host, SmtpPhase); + checkfd012(wbuf); + } +#endif + HoldErrs = oldholderrs; + return (-1); + } + fixcrlf(bufp, TRUE); + + /* EHLO failure is not a real error */ + if (e->e_xfp != NULL && (bufp[0] == '4' || + (bufp[0] == '5' && strncmp(SmtpMsgBuffer, "EHLO", 4) != 0))) + { + /* serious error -- log the previous command */ + if (SmtpNeedIntro) + { + /* inform user who we are chatting with */ + fprintf(CurEnv->e_xfp, + "... while talking to %s:\n", + CurHostName); + SmtpNeedIntro = FALSE; + } + if (SmtpMsgBuffer[0] != '\0') + fprintf(e->e_xfp, ">>> %s\n", SmtpMsgBuffer); + SmtpMsgBuffer[0] = '\0'; + + /* now log the message as from the other side */ + fprintf(e->e_xfp, "<<< %s\n", bufp); + } + + /* display the input for verbose mode */ + if (Verbose) + nmessage("050 %s", bufp); + + /* process the line */ + if (pfunc != NULL) + (*pfunc)(bufp, firstline, m, mci, e); + + firstline = FALSE; + + /* if continuation is required, we can go on */ + if (bufp[3] == '-') + continue; + + /* ignore improperly formated input */ + if (!(isascii(bufp[0]) && isdigit(bufp[0]))) + continue; + + /* decode the reply code */ + r = atoi(bufp); + + /* extra semantics: 0xx codes are "informational" */ + if (r >= 100) + break; + } + + /* + ** Now look at SmtpReplyBuffer -- only care about the first + ** line of the response from here on out. + */ + + /* save temporary failure messages for posterity */ + if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0') + (void) strcpy(SmtpError, SmtpReplyBuffer); + + /* reply code 421 is "Service Shutting Down" */ + if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD) + { + /* send the quit protocol */ + mci->mci_state = MCIS_SSD; + smtpquit(m, mci, e); + } + + return (r); +} +/* +** SMTPMESSAGE -- send message to server +** +** Parameters: +** f -- format +** m -- the mailer to control formatting. +** a, b, c -- parameters +** +** Returns: +** none. +** +** Side Effects: +** writes message to mci->mci_out. +*/ + +/*VARARGS1*/ +void +#ifdef __STDC__ +smtpmessage(char *f, MAILER *m, MCI *mci, ...) +#else +smtpmessage(f, m, mci, va_alist) + char *f; + MAILER *m; + MCI *mci; + va_dcl +#endif +{ + VA_LOCAL_DECL + + VA_START(mci); + (void) vsnprintf(SmtpMsgBuffer, sizeof SmtpMsgBuffer, f, ap); + VA_END; + + if (tTd(18, 1) || Verbose) + nmessage(">>> %s", SmtpMsgBuffer); + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%05d >>> %s\n", getpid(), SmtpMsgBuffer); + if (mci->mci_out != NULL) + { + fprintf(mci->mci_out, "%s%s", SmtpMsgBuffer, + m == NULL ? "\r\n" : m->m_eol); + } + else if (tTd(18, 1)) + { + printf("smtpmessage: NULL mci_out\n"); + } +} + +# endif /* SMTP */ diff --git a/usr.sbin/sendmail/src/util.c b/usr.sbin/sendmail/src/util.c new file mode 100644 index 000000000000..0685bf49c0f3 --- /dev/null +++ b/usr.sbin/sendmail/src/util.c @@ -0,0 +1,2008 @@ +/* + * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)util.c 8.84 (Berkeley) 11/18/95"; +#endif /* not lint */ + +# include "sendmail.h" +# include <sysexits.h> +/* +** STRIPQUOTES -- Strip quotes & quote bits from a string. +** +** Runs through a string and strips off unquoted quote +** characters and quote bits. This is done in place. +** +** Parameters: +** s -- the string to strip. +** +** Returns: +** none. +** +** Side Effects: +** none. +** +** Called By: +** deliver +*/ + +void +stripquotes(s) + char *s; +{ + register char *p; + register char *q; + register char c; + + if (s == NULL) + return; + + p = q = s; + do + { + c = *p++; + if (c == '\\') + c = *p++; + else if (c == '"') + continue; + *q++ = c; + } while (c != '\0'); +} +/* +** XALLOC -- Allocate memory and bitch wildly on failure. +** +** THIS IS A CLUDGE. This should be made to give a proper +** error -- but after all, what can we do? +** +** Parameters: +** sz -- size of area to allocate. +** +** Returns: +** pointer to data region. +** +** Side Effects: +** Memory is allocated. +*/ + +char * +xalloc(sz) + register int sz; +{ + register char *p; + + /* some systems can't handle size zero mallocs */ + if (sz <= 0) + sz = 1; + + p = malloc((unsigned) sz); + if (p == NULL) + { + syserr("!Out of memory!!"); + /* exit(EX_UNAVAILABLE); */ + } + return (p); +} +/* +** COPYPLIST -- copy list of pointers. +** +** This routine is the equivalent of newstr for lists of +** pointers. +** +** Parameters: +** list -- list of pointers to copy. +** Must be NULL terminated. +** copycont -- if TRUE, copy the contents of the vector +** (which must be a string) also. +** +** Returns: +** a copy of 'list'. +** +** Side Effects: +** none. +*/ + +char ** +copyplist(list, copycont) + char **list; + bool copycont; +{ + register char **vp; + register char **newvp; + + for (vp = list; *vp != NULL; vp++) + continue; + + vp++; + + newvp = (char **) xalloc((int) (vp - list) * sizeof *vp); + bcopy((char *) list, (char *) newvp, (int) (vp - list) * sizeof *vp); + + if (copycont) + { + for (vp = newvp; *vp != NULL; vp++) + *vp = newstr(*vp); + } + + return (newvp); +} +/* +** COPYQUEUE -- copy address queue. +** +** This routine is the equivalent of newstr for address queues +** addresses marked with QDONTSEND aren't copied +** +** Parameters: +** addr -- list of address structures to copy. +** +** Returns: +** a copy of 'addr'. +** +** Side Effects: +** none. +*/ + +ADDRESS * +copyqueue(addr) + ADDRESS *addr; +{ + register ADDRESS *newaddr; + ADDRESS *ret; + register ADDRESS **tail = &ret; + + while (addr != NULL) + { + if (!bitset(QDONTSEND, addr->q_flags)) + { + newaddr = (ADDRESS *) xalloc(sizeof(ADDRESS)); + STRUCTCOPY(*addr, *newaddr); + *tail = newaddr; + tail = &newaddr->q_next; + } + addr = addr->q_next; + } + *tail = NULL; + + return ret; +} +/* +** PRINTAV -- print argument vector. +** +** Parameters: +** av -- argument vector. +** +** Returns: +** none. +** +** Side Effects: +** prints av. +*/ + +void +printav(av) + register char **av; +{ + while (*av != NULL) + { + if (tTd(0, 44)) + printf("\n\t%08x=", *av); + else + (void) putchar(' '); + xputs(*av++); + } + (void) putchar('\n'); +} +/* +** LOWER -- turn letter into lower case. +** +** Parameters: +** c -- character to turn into lower case. +** +** Returns: +** c, in lower case. +** +** Side Effects: +** none. +*/ + +char +lower(c) + register char c; +{ + return((isascii(c) && isupper(c)) ? tolower(c) : c); +} +/* +** XPUTS -- put string doing control escapes. +** +** Parameters: +** s -- string to put. +** +** Returns: +** none. +** +** Side Effects: +** output to stdout +*/ + +void +xputs(s) + register const char *s; +{ + register int c; + register struct metamac *mp; + extern struct metamac MetaMacros[]; + + if (s == NULL) + { + printf("<null>"); + return; + } + while ((c = (*s++ & 0377)) != '\0') + { + if (!isascii(c)) + { + if (c == MATCHREPL) + { + putchar('$'); + continue; + } + if (c == MACROEXPAND) + { + putchar('$'); + if (strchr("=~&?", *s) != NULL) + putchar(*s++); + if (bitset(0200, *s)) + printf("{%s}", macname(*s++ & 0377)); + continue; + } + for (mp = MetaMacros; mp->metaname != '\0'; mp++) + { + if ((mp->metaval & 0377) == c) + { + printf("$%c", mp->metaname); + break; + } + } + if (c == MATCHCLASS || c == MATCHNCLASS) + { + if (!bitset(0200, *s)) + continue; + printf("{%s}", macname(*s++ & 0377)); + } + if (mp->metaname != '\0') + continue; + (void) putchar('\\'); + c &= 0177; + } + if (isprint(c)) + { + putchar(c); + continue; + } + + /* wasn't a meta-macro -- find another way to print it */ + switch (c) + { + case '\n': + c = 'n'; + break; + + case '\r': + c = 'r'; + break; + + case '\t': + c = 't'; + break; + + default: + (void) putchar('^'); + (void) putchar(c ^ 0100); + continue; + } + (void) putchar('\\'); + (void) putchar(c); + } + (void) fflush(stdout); +} +/* +** MAKELOWER -- Translate a line into lower case +** +** Parameters: +** p -- the string to translate. If NULL, return is +** immediate. +** +** Returns: +** none. +** +** Side Effects: +** String pointed to by p is translated to lower case. +** +** Called By: +** parse +*/ + +void +makelower(p) + register char *p; +{ + register char c; + + if (p == NULL) + return; + for (; (c = *p) != '\0'; p++) + if (isascii(c) && isupper(c)) + *p = tolower(c); +} +/* +** BUILDFNAME -- build full name from gecos style entry. +** +** This routine interprets the strange entry that would appear +** in the GECOS field of the password file. +** +** Parameters: +** p -- name to build. +** login -- the login name of this user (for &). +** buf -- place to put the result. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +void +buildfname(gecos, login, buf) + register char *gecos; + char *login; + char *buf; +{ + register char *p; + register char *bp = buf; + int l; + + if (*gecos == '*') + gecos++; + + /* find length of final string */ + l = 0; + for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++) + { + if (*p == '&') + l += strlen(login); + else + l++; + } + + /* now fill in buf */ + for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++) + { + if (*p == '&') + { + (void) strcpy(bp, login); + *bp = toupper(*bp); + while (*bp != '\0') + bp++; + } + else + *bp++ = *p; + } + *bp = '\0'; +} +/* +** SAFEFILE -- return true if a file exists and is safe for a user. +** +** Parameters: +** fn -- filename to check. +** uid -- user id to compare against. +** gid -- group id to compare against. +** uname -- user name to compare against (used for group +** sets). +** flags -- modifiers: +** SFF_MUSTOWN -- "uid" must own this file. +** SFF_NOSLINK -- file cannot be a symbolic link. +** mode -- mode bits that must match. +** st -- if set, points to a stat structure that will +** get the stat info for the file. +** +** Returns: +** 0 if fn exists, is owned by uid, and matches mode. +** An errno otherwise. The actual errno is cleared. +** +** Side Effects: +** none. +*/ + +#include <grp.h> + +#ifndef S_IXOTH +# define S_IXOTH (S_IEXEC >> 6) +#endif + +#ifndef S_IXGRP +# define S_IXGRP (S_IEXEC >> 3) +#endif + +#ifndef S_IXUSR +# define S_IXUSR (S_IEXEC) +#endif + +#define ST_MODE_NOFILE 0171147 /* unlikely to occur */ + +int +safefile(fn, uid, gid, uname, flags, mode, st) + char *fn; + uid_t uid; + gid_t gid; + char *uname; + int flags; + int mode; + struct stat *st; +{ + register char *p; + register struct group *gr = NULL; + int file_errno = 0; + struct stat stbuf; + struct stat fstbuf; + + if (tTd(44, 4)) + printf("safefile(%s, uid=%d, gid=%d, flags=%x, mode=%o):\n", + fn, uid, gid, flags, mode); + errno = 0; + if (st == NULL) + st = &fstbuf; + + /* first check to see if the file exists at all */ +#ifdef HASLSTAT + if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, st) + : stat(fn, st)) < 0) +#else + if (stat(fn, st) < 0) +#endif + { + file_errno = errno; + } + else if (bitset(SFF_SETUIDOK, flags) && + !bitset(S_IXUSR|S_IXGRP|S_IXOTH, st->st_mode) && + S_ISREG(st->st_mode)) + { + /* + ** If final file is setuid, run as the owner of that + ** file. Gotta be careful not to reveal anything too + ** soon here! + */ + +#ifdef SUID_ROOT_FILES_OK + if (bitset(S_ISUID, st->st_mode)) +#else + if (bitset(S_ISUID, st->st_mode) && st->st_uid != 0) +#endif + { + uid = st->st_uid; + uname = NULL; + } +#ifdef SUID_ROOT_FILES_OK + if (bitset(S_ISGID, st->st_mode)) +#else + if (bitset(S_ISGID, st->st_mode) && st->st_gid != 0) +#endif + gid = st->st_gid; + } + + if (!bitset(SFF_NOPATHCHECK, flags) || + (uid == 0 && !bitset(SFF_ROOTOK, flags))) + { + /* check the path to the file for acceptability */ + for (p = fn; (p = strchr(++p, '/')) != NULL; *p = '/') + { + *p = '\0'; + if (stat(fn, &stbuf) < 0) + break; + if (uid == 0 && bitset(S_IWGRP|S_IWOTH, stbuf.st_mode)) + message("051 WARNING: writable directory %s", + fn); + if (uid == 0 && !bitset(SFF_ROOTOK, flags)) + { + if (bitset(S_IXOTH, stbuf.st_mode)) + continue; + break; + } + if (stbuf.st_uid == uid && + bitset(S_IXUSR, stbuf.st_mode)) + continue; + if (stbuf.st_gid == gid && + bitset(S_IXGRP, stbuf.st_mode)) + continue; +#ifndef NO_GROUP_SET + if (uname != NULL && + ((gr != NULL && gr->gr_gid == stbuf.st_gid) || + (gr = getgrgid(stbuf.st_gid)) != NULL)) + { + register char **gp; + + for (gp = gr->gr_mem; gp != NULL && *gp != NULL; gp++) + if (strcmp(*gp, uname) == 0) + break; + if (gp != NULL && *gp != NULL && + bitset(S_IXGRP, stbuf.st_mode)) + continue; + } +#endif + if (!bitset(S_IXOTH, stbuf.st_mode)) + break; + } + if (p != NULL) + { + int ret = errno; + + if (ret == 0) + ret = EACCES; + if (tTd(44, 4)) + printf("\t[dir %s] %s\n", fn, errstring(ret)); + *p = '/'; + return ret; + } + } + + /* + ** If the target file doesn't exist, check the directory to + ** ensure that it is writable by this user. + */ + + if (file_errno != 0) + { + int ret = file_errno; + + if (tTd(44, 4)) + printf("\t%s\n", errstring(ret)); + + errno = 0; + if (!bitset(SFF_CREAT, flags)) + return ret; + + /* check to see if legal to create the file */ + p = strrchr(fn, '/'); + if (p == NULL) + return ENOTDIR; + *p = '\0'; + if (stat(fn, &stbuf) >= 0) + { + int md = S_IWRITE|S_IEXEC; + if (stbuf.st_uid != uid) + md >>= 6; + if ((stbuf.st_mode & md) != md) + errno = EACCES; + } + ret = errno; + if (tTd(44, 4)) + printf("\t[final dir %s uid %d mode %o] %s\n", + fn, stbuf.st_uid, stbuf.st_mode, + errstring(ret)); + *p = '/'; + st->st_mode = ST_MODE_NOFILE; + return ret; + } + +#ifdef S_ISLNK + if (bitset(SFF_NOSLINK, flags) && S_ISLNK(st->st_mode)) + { + if (tTd(44, 4)) + printf("\t[slink mode %o]\tEPERM\n", st->st_mode); + return EPERM; + } +#endif + if (bitset(SFF_REGONLY, flags) && !S_ISREG(st->st_mode)) + { + if (tTd(44, 4)) + printf("\t[non-reg mode %o]\tEPERM\n", st->st_mode); + return EPERM; + } + if (bitset(S_IWUSR|S_IWGRP|S_IWOTH, mode) && + bitset(S_IXUSR|S_IXGRP|S_IXOTH, st->st_mode)) + { + if (tTd(44, 4)) + printf("\t[exec bits %o]\tEPERM]\n", st->st_mode); + return EPERM; + } + + if (uid == 0 && !bitset(SFF_ROOTOK, flags)) + mode >>= 6; + else if (st->st_uid != uid) + { + mode >>= 3; + if (st->st_gid == gid) + ; +#ifndef NO_GROUP_SET + else if (uname != NULL && + ((gr != NULL && gr->gr_gid == st->st_gid) || + (gr = getgrgid(st->st_gid)) != NULL)) + { + register char **gp; + + for (gp = gr->gr_mem; *gp != NULL; gp++) + if (strcmp(*gp, uname) == 0) + break; + if (*gp == NULL) + mode >>= 3; + } +#endif + else + mode >>= 3; + } + if (tTd(44, 4)) + printf("\t[uid %d, stat %o, mode %o] ", + st->st_uid, st->st_mode, mode); + if ((st->st_uid == uid || st->st_uid == 0 || + !bitset(SFF_MUSTOWN, flags)) && + (st->st_mode & mode) == mode) + { + if (tTd(44, 4)) + printf("\tOK\n"); + return 0; + } + if (tTd(44, 4)) + printf("\tEACCES\n"); + return EACCES; +} +/* +** SAFEFOPEN -- do a file open with extra checking +** +** Parameters: +** fn -- the file name to open. +** omode -- the open-style mode flags. +** cmode -- the create-style mode flags. +** sff -- safefile flags. +** +** Returns: +** Same as fopen. +*/ + +#ifndef O_ACCMODE +# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +FILE * +safefopen(fn, omode, cmode, sff) + char *fn; + int omode; + int cmode; + int sff; +{ + int rval; + FILE *fp; + int smode; + struct stat stb, sta; + + if (bitset(O_CREAT, omode)) + sff |= SFF_CREAT; + smode = 0; + switch (omode & O_ACCMODE) + { + case O_RDONLY: + smode = S_IREAD; + break; + + case O_WRONLY: + smode = S_IWRITE; + break; + + case O_RDWR: + smode = S_IREAD|S_IWRITE; + break; + + default: + smode = 0; + break; + } + if (bitset(SFF_OPENASROOT, sff)) + rval = safefile(fn, 0, 0, NULL, sff, smode, &stb); + else + rval = safefile(fn, RealUid, RealGid, RealUserName, + sff, smode, &stb); + if (rval != 0) + { + errno = rval; + return NULL; + } + if (stb.st_mode == ST_MODE_NOFILE) + omode |= O_EXCL; + + fp = dfopen(fn, omode, cmode); + if (fp == NULL) + return NULL; + if (bitset(O_EXCL, omode)) + return fp; + if (fstat(fileno(fp), &sta) < 0 || + sta.st_nlink != stb.st_nlink || + sta.st_dev != stb.st_dev || + sta.st_ino != stb.st_ino || + sta.st_uid != stb.st_uid || + sta.st_gid != stb.st_gid) + { + syserr("554 cannot open: file %s changed after open", fn); + fclose(fp); + errno = EPERM; + return NULL; + } + return fp; +} +/* +** FIXCRLF -- fix <CR><LF> in line. +** +** Looks for the <CR><LF> combination and turns it into the +** UNIX canonical <NL> character. It only takes one line, +** i.e., it is assumed that the first <NL> found is the end +** of the line. +** +** Parameters: +** line -- the line to fix. +** stripnl -- if true, strip the newline also. +** +** Returns: +** none. +** +** Side Effects: +** line is changed in place. +*/ + +void +fixcrlf(line, stripnl) + char *line; + bool stripnl; +{ + register char *p; + + p = strchr(line, '\n'); + if (p == NULL) + return; + if (p > line && p[-1] == '\r') + p--; + if (!stripnl) + *p++ = '\n'; + *p = '\0'; +} +/* +** DFOPEN -- determined file open +** +** This routine has the semantics of fopen, except that it will +** keep trying a few times to make this happen. The idea is that +** on very loaded systems, we may run out of resources (inodes, +** whatever), so this tries to get around it. +*/ + +struct omodes +{ + int mask; + int mode; + char *farg; +} OpenModes[] = +{ + O_ACCMODE, O_RDONLY, "r", + O_ACCMODE|O_APPEND, O_WRONLY, "w", + O_ACCMODE|O_APPEND, O_WRONLY|O_APPEND, "a", + O_TRUNC, 0, "w+", + O_APPEND, O_APPEND, "a+", + 0, 0, "r+", +}; + +FILE * +dfopen(filename, omode, cmode) + char *filename; + int omode; + int cmode; +{ + register int tries; + int fd; + register struct omodes *om; + struct stat st; + + for (om = OpenModes; om->mask != 0; om++) + if ((omode & om->mask) == om->mode) + break; + + for (tries = 0; tries < 10; tries++) + { + sleep((unsigned) (10 * tries)); + errno = 0; + fd = open(filename, omode, cmode); + if (fd >= 0) + break; + switch (errno) + { + case ENFILE: /* system file table full */ + case EINTR: /* interrupted syscall */ +#ifdef ETXTBSY + case ETXTBSY: /* Apollo: net file locked */ +#endif + continue; + } + break; + } + if (fd >= 0 && fstat(fd, &st) >= 0 && S_ISREG(st.st_mode)) + { + int locktype; + + /* lock the file to avoid accidental conflicts */ + if ((omode & O_ACCMODE) != O_RDONLY) + locktype = LOCK_EX; + else + locktype = LOCK_SH; + (void) lockfile(fd, filename, NULL, locktype); + errno = 0; + } + if (fd < 0) + return NULL; + else + return fdopen(fd, om->farg); +} +/* +** PUTLINE -- put a line like fputs obeying SMTP conventions +** +** This routine always guarantees outputing a newline (or CRLF, +** as appropriate) at the end of the string. +** +** Parameters: +** l -- line to put. +** mci -- the mailer connection information. +** +** Returns: +** none +** +** Side Effects: +** output of l to fp. +*/ + +void +putline(l, mci) + register char *l; + register MCI *mci; +{ + putxline(l, mci, PXLF_MAPFROM); +} +/* +** PUTXLINE -- putline with flags bits. +** +** This routine always guarantees outputing a newline (or CRLF, +** as appropriate) at the end of the string. +** +** Parameters: +** l -- line to put. +** mci -- the mailer connection information. +** pxflags -- flag bits: +** PXLF_MAPFROM -- map From_ to >From_. +** PXLF_STRIP8BIT -- strip 8th bit. +** +** Returns: +** none +** +** Side Effects: +** output of l to fp. +*/ + +void +putxline(l, mci, pxflags) + register char *l; + register MCI *mci; + int pxflags; +{ + register char *p; + register char svchar; + int slop = 0; + + /* strip out 0200 bits -- these can look like TELNET protocol */ + if (bitset(MCIF_7BIT, mci->mci_flags) || + bitset(PXLF_STRIP8BIT, pxflags)) + { + for (p = l; (svchar = *p) != '\0'; ++p) + if (bitset(0200, svchar)) + *p = svchar &~ 0200; + } + + do + { + /* find the end of the line */ + p = strchr(l, '\n'); + if (p == NULL) + p = &l[strlen(l)]; + + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%05d >>> ", getpid()); + + /* check for line overflow */ + while (mci->mci_mailer->m_linelimit > 0 && + (p - l + slop) > mci->mci_mailer->m_linelimit) + { + register char *q = &l[mci->mci_mailer->m_linelimit - slop - 1]; + + svchar = *q; + *q = '\0'; + if (l[0] == '.' && slop == 0 && + bitnset(M_XDOT, mci->mci_mailer->m_flags)) + { + (void) putc('.', mci->mci_out); + if (TrafficLogFile != NULL) + (void) putc('.', TrafficLogFile); + } + else if (l[0] == 'F' && slop == 0 && + bitset(PXLF_MAPFROM, pxflags) && + strncmp(l, "From ", 5) == 0 && + bitnset(M_ESCFROM, mci->mci_mailer->m_flags)) + { + (void) putc('>', mci->mci_out); + if (TrafficLogFile != NULL) + (void) putc('>', TrafficLogFile); + } + fputs(l, mci->mci_out); + (void) putc('!', mci->mci_out); + fputs(mci->mci_mailer->m_eol, mci->mci_out); + (void) putc(' ', mci->mci_out); + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%s!\n%05d >>> ", + l, getpid()); + *q = svchar; + l = q; + slop = 1; + } + + /* output last part */ + if (l[0] == '.' && slop == 0 && + bitnset(M_XDOT, mci->mci_mailer->m_flags)) + { + (void) putc('.', mci->mci_out); + if (TrafficLogFile != NULL) + (void) putc('.', TrafficLogFile); + } + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%.*s\n", p - l, l); + for ( ; l < p; ++l) + (void) putc(*l, mci->mci_out); + fputs(mci->mci_mailer->m_eol, mci->mci_out); + if (*l == '\n') + ++l; + } while (l[0] != '\0'); +} +/* +** XUNLINK -- unlink a file, doing logging as appropriate. +** +** Parameters: +** f -- name of file to unlink. +** +** Returns: +** none. +** +** Side Effects: +** f is unlinked. +*/ + +void +xunlink(f) + char *f; +{ + register int i; + +# ifdef LOG + if (LogLevel > 98) + syslog(LOG_DEBUG, "%s: unlink %s", CurEnv->e_id, f); +# endif /* LOG */ + + i = unlink(f); +# ifdef LOG + if (i < 0 && LogLevel > 97) + syslog(LOG_DEBUG, "%s: unlink-fail %d", f, errno); +# endif /* LOG */ +} +/* +** XFCLOSE -- close a file, doing logging as appropriate. +** +** Parameters: +** fp -- file pointer for the file to close +** a, b -- miscellaneous crud to print for debugging +** +** Returns: +** none. +** +** Side Effects: +** fp is closed. +*/ + +void +xfclose(fp, a, b) + FILE *fp; + char *a, *b; +{ + if (tTd(53, 99)) + printf("xfclose(%x) %s %s\n", fp, a, b); +#if XDEBUG + if (fileno(fp) == 1) + syserr("xfclose(%s %s): fd = 1", a, b); +#endif + if (fclose(fp) < 0 && tTd(53, 99)) + printf("xfclose FAILURE: %s\n", errstring(errno)); +} +/* +** SFGETS -- "safe" fgets -- times out and ignores random interrupts. +** +** Parameters: +** buf -- place to put the input line. +** siz -- size of buf. +** fp -- file to read from. +** timeout -- the timeout before error occurs. +** during -- what we are trying to read (for error messages). +** +** Returns: +** NULL on error (including timeout). This will also leave +** buf containing a null string. +** buf otherwise. +** +** Side Effects: +** none. +*/ + +static jmp_buf CtxReadTimeout; +static void readtimeout(); + +char * +sfgets(buf, siz, fp, timeout, during) + char *buf; + int siz; + FILE *fp; + time_t timeout; + char *during; +{ + register EVENT *ev = NULL; + register char *p; + + if (fp == NULL) + { + buf[0] = '\0'; + return NULL; + } + + /* set the timeout */ + if (timeout != 0) + { + if (setjmp(CtxReadTimeout) != 0) + { +# ifdef LOG + syslog(LOG_NOTICE, + "timeout waiting for input from %.100s during %s", + CurHostName? CurHostName: "local", during); +# endif + errno = 0; + usrerr("451 timeout waiting for input during %s", + during); + buf[0] = '\0'; +#if XDEBUG + checkfd012(during); +#endif + return (NULL); + } + ev = setevent(timeout, readtimeout, 0); + } + + /* try to read */ + p = NULL; + while (!feof(fp) && !ferror(fp)) + { + errno = 0; + p = fgets(buf, siz, fp); + if (p != NULL || errno != EINTR) + break; + clearerr(fp); + } + + /* clear the event if it has not sprung */ + clrevent(ev); + + /* clean up the books and exit */ + LineNumber++; + if (p == NULL) + { + buf[0] = '\0'; + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%05d <<< [EOF]\n", getpid()); + return (NULL); + } + if (TrafficLogFile != NULL) + fprintf(TrafficLogFile, "%05d <<< %s", getpid(), buf); + if (SevenBitInput) + { + for (p = buf; *p != '\0'; p++) + *p &= ~0200; + } + else if (!HasEightBits) + { + for (p = buf; *p != '\0'; p++) + { + if (bitset(0200, *p)) + { + HasEightBits = TRUE; + break; + } + } + } + return (buf); +} + +static void +readtimeout(timeout) + time_t timeout; +{ + longjmp(CtxReadTimeout, 1); +} +/* +** FGETFOLDED -- like fgets, but know about folded lines. +** +** Parameters: +** buf -- place to put result. +** n -- bytes available. +** f -- file to read from. +** +** Returns: +** input line(s) on success, NULL on error or EOF. +** This will normally be buf -- unless the line is too +** long, when it will be xalloc()ed. +** +** Side Effects: +** buf gets lines from f, with continuation lines (lines +** with leading white space) appended. CRLF's are mapped +** into single newlines. Any trailing NL is stripped. +*/ + +char * +fgetfolded(buf, n, f) + char *buf; + register int n; + FILE *f; +{ + register char *p = buf; + char *bp = buf; + register int i; + + n--; + while ((i = getc(f)) != EOF) + { + if (i == '\r') + { + i = getc(f); + if (i != '\n') + { + if (i != EOF) + (void) ungetc(i, f); + i = '\r'; + } + } + if (--n <= 0) + { + /* allocate new space */ + char *nbp; + int nn; + + nn = (p - bp); + if (nn < MEMCHUNKSIZE) + nn *= 2; + else + nn += MEMCHUNKSIZE; + nbp = xalloc(nn); + bcopy(bp, nbp, p - bp); + p = &nbp[p - bp]; + if (bp != buf) + free(bp); + bp = nbp; + n = nn - (p - bp); + } + *p++ = i; + if (i == '\n') + { + LineNumber++; + i = getc(f); + if (i != EOF) + (void) ungetc(i, f); + if (i != ' ' && i != '\t') + break; + } + } + if (p == bp) + return (NULL); + if (p[-1] == '\n') + p--; + *p = '\0'; + return (bp); +} +/* +** CURTIME -- return current time. +** +** Parameters: +** none. +** +** Returns: +** the current time. +** +** Side Effects: +** none. +*/ + +time_t +curtime() +{ + auto time_t t; + + (void) time(&t); + return (t); +} +/* +** ATOBOOL -- convert a string representation to boolean. +** +** Defaults to "TRUE" +** +** Parameters: +** s -- string to convert. Takes "tTyY" as true, +** others as false. +** +** Returns: +** A boolean representation of the string. +** +** Side Effects: +** none. +*/ + +bool +atobool(s) + register char *s; +{ + if (s == NULL || *s == '\0' || strchr("tTyY", *s) != NULL) + return (TRUE); + return (FALSE); +} +/* +** ATOOCT -- convert a string representation to octal. +** +** Parameters: +** s -- string to convert. +** +** Returns: +** An integer representing the string interpreted as an +** octal number. +** +** Side Effects: +** none. +*/ + +int +atooct(s) + register char *s; +{ + register int i = 0; + + while (*s >= '0' && *s <= '7') + i = (i << 3) | (*s++ - '0'); + return (i); +} +/* +** WAITFOR -- wait for a particular process id. +** +** Parameters: +** pid -- process id to wait for. +** +** Returns: +** status of pid. +** -1 if pid never shows up. +** +** Side Effects: +** none. +*/ + +int +waitfor(pid) + int pid; +{ +#ifdef WAITUNION + union wait st; +#else + auto int st; +#endif + int i; + + do + { + errno = 0; + i = wait(&st); + } while ((i >= 0 || errno == EINTR) && i != pid); + if (i < 0) + return -1; +#ifdef WAITUNION + return st.w_status; +#else + return st; +#endif +} +/* +** BITINTERSECT -- tell if two bitmaps intersect +** +** Parameters: +** a, b -- the bitmaps in question +** +** Returns: +** TRUE if they have a non-null intersection +** FALSE otherwise +** +** Side Effects: +** none. +*/ + +bool +bitintersect(a, b) + BITMAP a; + BITMAP b; +{ + int i; + + for (i = BITMAPBYTES / sizeof (int); --i >= 0; ) + if ((a[i] & b[i]) != 0) + return (TRUE); + return (FALSE); +} +/* +** BITZEROP -- tell if a bitmap is all zero +** +** Parameters: +** map -- the bit map to check +** +** Returns: +** TRUE if map is all zero. +** FALSE if there are any bits set in map. +** +** Side Effects: +** none. +*/ + +bool +bitzerop(map) + BITMAP map; +{ + int i; + + for (i = BITMAPBYTES / sizeof (int); --i >= 0; ) + if (map[i] != 0) + return (FALSE); + return (TRUE); +} +/* +** STRCONTAINEDIN -- tell if one string is contained in another +** +** Parameters: +** a -- possible substring. +** b -- possible superstring. +** +** Returns: +** TRUE if a is contained in b. +** FALSE otherwise. +*/ + +bool +strcontainedin(a, b) + register char *a; + register char *b; +{ + int la; + int lb; + int c; + + la = strlen(a); + lb = strlen(b); + c = *a; + if (isascii(c) && isupper(c)) + c = tolower(c); + for (; lb-- >= la; b++) + { + if (*b != c && isascii(*b) && isupper(*b) && tolower(*b) != c) + continue; + if (strncasecmp(a, b, la) == 0) + return TRUE; + } + return FALSE; +} +/* +** CHECKFD012 -- check low numbered file descriptors +** +** File descriptors 0, 1, and 2 should be open at all times. +** This routine verifies that, and fixes it if not true. +** +** Parameters: +** where -- a tag printed if the assertion failed +** +** Returns: +** none +*/ + +void +checkfd012(where) + char *where; +{ +#if XDEBUG + register int i; + struct stat stbuf; + + for (i = 0; i < 3; i++) + { + if (fstat(i, &stbuf) < 0 && errno != EOPNOTSUPP) + { + /* oops.... */ + int fd; + + syserr("%s: fd %d not open", where, i); + fd = open("/dev/null", i == 0 ? O_RDONLY : O_WRONLY, 0666); + if (fd != i) + { + (void) dup2(fd, i); + (void) close(fd); + } + } + } +#endif /* XDEBUG */ +} +/* +** PRINTOPENFDS -- print the open file descriptors (for debugging) +** +** Parameters: +** logit -- if set, send output to syslog; otherwise +** print for debugging. +** +** Returns: +** none. +*/ + +#include <arpa/inet.h> + +void +printopenfds(logit) + bool logit; +{ + register int fd; + extern int DtableSize; + + for (fd = 0; fd < DtableSize; fd++) + dumpfd(fd, FALSE, logit); +} +/* +** DUMPFD -- dump a file descriptor +** +** Parameters: +** fd -- the file descriptor to dump. +** printclosed -- if set, print a notification even if +** it is closed; otherwise print nothing. +** logit -- if set, send output to syslog instead of stdout. +*/ + +void +dumpfd(fd, printclosed, logit) + int fd; + bool printclosed; + bool logit; +{ + register char *p; + char *hp; + char *fmtstr; +#ifdef S_IFSOCK + SOCKADDR sa; +#endif + auto int slen; + struct stat st; + char buf[200]; + extern char *hostnamebyanyaddr(); + + p = buf; + sprintf(p, "%3d: ", fd); + p += strlen(p); + + if (fstat(fd, &st) < 0) + { + if (printclosed || errno != EBADF) + { + sprintf(p, "CANNOT STAT (%s)", errstring(errno)); + goto printit; + } + return; + } + + slen = fcntl(fd, F_GETFL, NULL); + if (slen != -1) + { + sprintf(p, "fl=0x%x, ", slen); + p += strlen(p); + } + + sprintf(p, "mode=%o: ", st.st_mode); + p += strlen(p); + switch (st.st_mode & S_IFMT) + { +#ifdef S_IFSOCK + case S_IFSOCK: + sprintf(p, "SOCK "); + p += strlen(p); + slen = sizeof sa; + if (getsockname(fd, &sa.sa, &slen) < 0) + sprintf(p, "(%s)", errstring(errno)); + else + { + hp = hostnamebyanyaddr(&sa); + if (sa.sa.sa_family == AF_INET) + sprintf(p, "%s/%d", hp, ntohs(sa.sin.sin_port)); + else + sprintf(p, "%s", hp); + } + p += strlen(p); + sprintf(p, "->"); + p += strlen(p); + slen = sizeof sa; + if (getpeername(fd, &sa.sa, &slen) < 0) + sprintf(p, "(%s)", errstring(errno)); + else + { + hp = hostnamebyanyaddr(&sa); + if (sa.sa.sa_family == AF_INET) + sprintf(p, "%s/%d", hp, ntohs(sa.sin.sin_port)); + else + sprintf(p, "%s", hp); + } + break; +#endif + + case S_IFCHR: + sprintf(p, "CHR: "); + p += strlen(p); + goto defprint; + + case S_IFBLK: + sprintf(p, "BLK: "); + p += strlen(p); + goto defprint; + +#if defined(S_IFIFO) && (!defined(S_IFSOCK) || S_IFIFO != S_IFSOCK) + case S_IFIFO: + sprintf(p, "FIFO: "); + p += strlen(p); + goto defprint; +#endif + +#ifdef S_IFDIR + case S_IFDIR: + sprintf(p, "DIR: "); + p += strlen(p); + goto defprint; +#endif + +#ifdef S_IFLNK + case S_IFLNK: + sprintf(p, "LNK: "); + p += strlen(p); + goto defprint; +#endif + + default: +defprint: + if (sizeof st.st_size > sizeof (long)) + fmtstr = "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%qd"; + else + fmtstr = "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%ld"; + sprintf(p, fmtstr, + major(st.st_dev), minor(st.st_dev), st.st_ino, + st.st_nlink, st.st_uid, st.st_gid, st.st_size); + break; + } + +printit: +#ifdef LOG + if (logit) + syslog(LOG_DEBUG, "%.800s", buf); + else +#endif + printf("%s\n", buf); +} +/* +** SHORTENSTRING -- return short version of a string +** +** If the string is already short, just return it. If it is too +** long, return the head and tail of the string. +** +** Parameters: +** s -- the string to shorten. +** m -- the max length of the string. +** +** Returns: +** Either s or a short version of s. +*/ + +#ifndef MAXSHORTSTR +# define MAXSHORTSTR 203 +#endif + +char * +shortenstring(s, m) + register const char *s; + int m; +{ + int l; + static char buf[MAXSHORTSTR + 1]; + + l = strlen(s); + if (l < m) + return (char *) s; + if (m > MAXSHORTSTR) + m = MAXSHORTSTR; + else if (m < 10) + { + if (m < 5) + { + strncpy(buf, s, m); + buf[m] = '\0'; + return buf; + } + strncpy(buf, s, m - 3); + strcpy(buf + m - 3, "..."); + return buf; + } + m = (m - 3) / 2; + strncpy(buf, s, m); + strcpy(buf + m, "..."); + strcpy(buf + m + 3, s + l - m); + return buf; +} +/* +** SHORTEN_HOSTNAME -- strip local domain information off of hostname. +** +** Parameters: +** host -- the host to shorten (stripped in place). +** +** Returns: +** none. +*/ + +void +shorten_hostname(host) + char host[]; +{ + register char *p; + char *mydom; + int i; + bool canon = FALSE; + + /* strip off final dot */ + p = &host[strlen(host) - 1]; + if (*p == '.') + { + *p = '\0'; + canon = TRUE; + } + + /* see if there is any domain at all -- if not, we are done */ + p = strchr(host, '.'); + if (p == NULL) + return; + + /* yes, we have a domain -- see if it looks like us */ + mydom = macvalue('m', CurEnv); + if (mydom == NULL) + mydom = ""; + i = strlen(++p); + if ((canon ? strcasecmp(p, mydom) : strncasecmp(p, mydom, i)) == 0 && + (mydom[i] == '.' || mydom[i] == '\0')) + *--p = '\0'; +} +/* +** PROG_OPEN -- open a program for reading +** +** Parameters: +** argv -- the argument list. +** pfd -- pointer to a place to store the file descriptor. +** e -- the current envelope. +** +** Returns: +** pid of the process -- -1 if it failed. +*/ + +int +prog_open(argv, pfd, e) + char **argv; + int *pfd; + ENVELOPE *e; +{ + int pid; + int i; + int saveerrno; + int fdv[2]; + char *p, *q; + char buf[MAXLINE + 1]; + extern int DtableSize; + + if (pipe(fdv) < 0) + { + syserr("%s: cannot create pipe for stdout", argv[0]); + return -1; + } + pid = fork(); + if (pid < 0) + { + syserr("%s: cannot fork", argv[0]); + close(fdv[0]); + close(fdv[1]); + return -1; + } + if (pid > 0) + { + /* parent */ + close(fdv[1]); + *pfd = fdv[0]; + return pid; + } + + /* child -- close stdin */ + close(0); + + /* stdout goes back to parent */ + close(fdv[0]); + if (dup2(fdv[1], 1) < 0) + { + syserr("%s: cannot dup2 for stdout", argv[0]); + _exit(EX_OSERR); + } + close(fdv[1]); + + /* stderr goes to transcript if available */ + if (e->e_xfp != NULL) + { + if (dup2(fileno(e->e_xfp), 2) < 0) + { + syserr("%s: cannot dup2 for stderr", argv[0]); + _exit(EX_OSERR); + } + } + + /* this process has no right to the queue file */ + if (e->e_lockfp != NULL) + close(fileno(e->e_lockfp)); + + /* run as default user */ + endpwent(); + setgid(DefGid); + setuid(DefUid); + + /* run in some directory */ + if (ProgMailer != NULL) + p = ProgMailer->m_execdir; + else + p = NULL; + for (; p != NULL; p = q) + { + q = strchr(p, ':'); + if (q != NULL) + *q = '\0'; + expand(p, buf, sizeof buf, e); + if (q != NULL) + *q++ = ':'; + if (buf[0] != '\0' && chdir(buf) >= 0) + break; + } + if (p == NULL) + { + /* backup directories */ + if (chdir("/tmp") < 0) + (void) chdir("/"); + } + + /* arrange for all the files to be closed */ + for (i = 3; i < DtableSize; i++) + { + register int j; + + if ((j = fcntl(i, F_GETFD, 0)) != -1) + (void) fcntl(i, F_SETFD, j | 1); + } + + /* now exec the process */ + execve(argv[0], (ARGV_T) argv, (ARGV_T) UserEnviron); + + /* woops! failed */ + saveerrno = errno; + syserr("%s: cannot exec", argv[0]); + if (transienterror(saveerrno)) + _exit(EX_OSERR); + _exit(EX_CONFIG); +} +/* +** GET_COLUMN -- look up a Column in a line buffer +** +** Parameters: +** line -- the raw text line to search. +** col -- the column number to fetch. +** delim -- the delimiter between columns. If null, +** use white space. +** buf -- the output buffer. +** +** Returns: +** buf if successful. +** NULL otherwise. +*/ + +char * +get_column(line, col, delim, buf) + char line[]; + int col; + char delim; + char buf[]; +{ + char *p; + char *begin, *end; + int i; + char delimbuf[3]; + + if (delim == '\0') + strcpy(delimbuf, "\n\t "); + else + { + delimbuf[0] = delim; + delimbuf[1] = '\0'; + } + + p = line; + if (*p == '\0') + return NULL; /* line empty */ + if (*p == delim && col == 0) + return NULL; /* first column empty */ + + begin = line; + + if (col == 0 && delim == '\0') + { + while (*begin && isspace(*begin)) + begin++; + } + + for (i = 0; i < col; i++) + { + if ((begin = strpbrk(begin, delimbuf)) == NULL) + return NULL; /* no such column */ + begin++; + if (delim == '\0') + { + while (*begin && isspace(*begin)) + begin++; + } + } + + end = strpbrk(begin, delimbuf); + if (end == NULL) + { + strcpy(buf, begin); + } + else + { + strncpy(buf, begin, end - begin); + buf[end - begin] = '\0'; + } + return buf; +} +/* +** CLEANSTRCPY -- copy string keeping out bogus characters +** +** Parameters: +** t -- "to" string. +** f -- "from" string. +** l -- length of space available in "to" string. +** +** Returns: +** none. +*/ + +void +cleanstrcpy(t, f, l) + register char *t; + register char *f; + int l; +{ +#ifdef LOG + /* check for newlines and log if necessary */ + (void) denlstring(f, TRUE, TRUE); +#endif + + l--; + while (l > 0 && *f != '\0') + { + if (isascii(*f) && + (isalnum(*f) || strchr("!#$%&'*+-./^_`{|}~", *f) != NULL)) + { + l--; + *t++ = *f; + } + f++; + } + *t = '\0'; +} +/* +** DENLSTRING -- convert newlines in a string to spaces +** +** Parameters: +** s -- the input string +** strict -- if set, don't permit continuation lines. +** logattacks -- if set, log attempted attacks. +** +** Returns: +** A pointer to a version of the string with newlines +** mapped to spaces. This should be copied. +*/ + +char * +denlstring(s, strict, logattacks) + char *s; + bool strict; + bool logattacks; +{ + register char *p; + int l; + static char *bp = NULL; + static int bl = 0; + + p = s; + while ((p = strchr(p, '\n')) != NULL) + if (strict || (*++p != ' ' && *p != '\t')) + break; + if (p == NULL) + return s; + + l = strlen(s) + 1; + if (bl < l) + { + /* allocate more space */ + if (bp != NULL) + free(bp); + bp = xalloc(l); + bl = l; + } + strcpy(bp, s); + for (p = bp; (p = strchr(p, '\n')) != NULL; ) + *p++ = ' '; + +/* +#ifdef LOG + if (logattacks) + { + syslog(LOG_NOTICE, "POSSIBLE ATTACK from %.100s: newline in string \"%s\"", + RealHostName == NULL ? "[UNKNOWN]" : RealHostName, + shortenstring(bp, 203)); + } +#endif +*/ + + return bp; +} diff --git a/usr.sbin/sendmail/src/version.c b/usr.sbin/sendmail/src/version.c new file mode 100644 index 000000000000..2d51c38c826f --- /dev/null +++ b/usr.sbin/sendmail/src/version.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1983 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)version.c 8.7.2.2 (Berkeley) 11/20/95"; +#endif /* not lint */ + +char Version[] = "8.7.2"; diff --git a/usr.sbin/sendmail/test/Results b/usr.sbin/sendmail/test/Results new file mode 100644 index 000000000000..d703fe4881cb --- /dev/null +++ b/usr.sbin/sendmail/test/Results @@ -0,0 +1,65 @@ +The following are results of running t_setreuid on various architectures. + +OPSYS VERSION STATUS DATE TESTER/NOTES +===== ======= ====== ==== ============ + +SunOS 4.1 OK 93.07.19 eric +SunOS 4.1.2 OK 93.07.19 eric +SunOS 4.1.3 OK 93.09.25 Robert Elz + +BSD 4.4 OK 93.07.19 eric (wierd results, but functional) +BSD 4.3Utah OK 93.07.19 eric + +Ultrix 4.2A OK 93.07.19 eric +Ultrix 4.3A OK 93.07.19 Allan Johannesen + +HP-UX 8.07 OK 93.07.19 eric (on 7xx series) +HP-UX 8.02 OK 93.07.19 Michael Corrigan (on 8xx series) +HP-UX 8.00 OK 93.07.21 Michael Corrigan (on 3xx/4xx series) +HP-UX 9.01 OK 93.11.19 Cassidy (on 7xx series) + +Solaris 2.1 +Solaris 2.2 FAIL 93.07.19 Bill Wisner + +OSF/1 T1.3-4 OK 93.07.19 eric (on DEC Alpha) +OSF/1 1.3 OK 94.12.10 Jeff A. Earickson (on Intel Paragon) + +CxOS 11.0 OK 93.01.21 Eric Schnoebelen (CxOS 11.0 beta 1) +CxOS 10.x OK 93.01.21 Eric Schnoebelen + +AIX 3.1.5 FAIL 93.08.07 David J. N. Begley +AIX 3.2.3e FAIL 93.07.26 Steve Bauer <sbauer@silver.sdsmt.edu> +AIX 3.2.4 FAIL 93.10.07 David J. N. Begley +AIX 3.2.5 FAIL 94.05.17 Steve Bauer <sbauer@hpcmmib.hpc.sdsmt.edu> + +IRIX 4.0.4 OK 93.09.25 Robert Elz +IRIX 5.2 OK 94.12.06 Mark Andrews <mandrews@alias.com> +IRIX 5.3 OK 94.12.06 Mark Andrews <mandrews@alias.com> + +SCO 3.2v4.0 OK 93.10.02 Peter Wemm (with -lsocket from 3.2v4 devsys) + +NeXT 2.1 OK 93.07.28 eric +NeXT 3.0 OK 34.05.05 Kevin John Wang <kwang@lore.acs.calpoly.edu> + +Linux 0.99p10 OK 93.08.08 Karl London +Linux 0.99p13 OK 93.09.27 Christian Kuhtz +Linux 0.99p14 OK 93.11.30 Christian Kuhtz <chk@data-hh.Hanse.DE> +Linux 1.0 OK 94.03.19 Shayne Smith <snsmith@rastus.brisnet.org.au> +Linux 1.2.13 OK 95.11.02 Sven Neuhaus <sven@ping.de> + +BSD/386 1.0 OK 93.11.13 Tony Sanders + +DELL 2.2 OK 93.11.15 Peter Wemm (using -DSETEUID) + +Pyramid 5.0d OK 95.01.14 David Miller <davem@nadzieja.rutgers.edu> + + + +The following are results of running t_seteuid on various architectures. + +OPSYS VERSION STATUS DATE TESTER/NOTES +===== ======= ====== ==== ============ + +Solaris 2.4 OK 95.09.22 Thomas 'Mike' Michlmayr <mike@cosy.sbg.ac.at> + +Linux 1.2.13 FAIL 95.11.02 Sven Neuhaus <sven@ping.de> diff --git a/usr.sbin/sendmail/test/t_seteuid.c b/usr.sbin/sendmail/test/t_seteuid.c new file mode 100644 index 000000000000..4dfe3d63bf77 --- /dev/null +++ b/usr.sbin/sendmail/test/t_seteuid.c @@ -0,0 +1,120 @@ +/* +** This program checks to see if your version of seteuid works. +** Compile it, make it setuid root, and run it as yourself (NOT as +** root). If it won't compile or outputs any MAYDAY messages, don't +** define USESETEUID in conf.h. +** +** NOTE: It is not sufficient to have seteuid in your library. +** You must also have saved uids that function properly. +** +** Compilation is trivial -- just "cc t_seteuid.c". Make it setuid, +** root and then execute it as a non-root user. +*/ + +#include <sys/types.h> +#include <unistd.h> +#include <stdio.h> + +#ifdef __hpux +#define seteuid(e) setresuid(-1, e, -1) +#endif + +main() +{ + int fail = 0; + uid_t realuid = getuid(); + + printuids("initial uids", realuid, 0); + + if (geteuid() != 0) + { + printf("SETUP ERROR: re-run setuid root\n"); + exit(1); + } + + if (getuid() == 0) + { + printf("SETUP ERROR: must be run by a non-root user\n"); + exit(1); + } + + if (seteuid(1) < 0) + printf("seteuid(1) failure\n"); + printuids("after seteuid(1)", realuid, 1); + + if (geteuid() != 1) + { + fail++; + printf("MAYDAY! Wrong effective uid\n"); + } + + /* do activity here */ + + if (seteuid(0) < 0) + { + fail++; + printf("seteuid(0) failure\n"); + } + printuids("after seteuid(0)", realuid, 0); + + if (geteuid() != 0) + { + fail++; + printf("MAYDAY! Wrong effective uid\n"); + } + if (getuid() != realuid) + { + fail++; + printf("MAYDAY! Wrong real uid\n"); + } + printf("\n"); + + if (seteuid(2) < 0) + { + fail++; + printf("seteuid(2) failure\n"); + } + printuids("after seteuid(2)", realuid, 2); + + if (geteuid() != 2) + { + fail++; + printf("MAYDAY! Wrong effective uid\n"); + } + + /* do activity here */ + + if (seteuid(0) < 0) + { + fail++; + printf("seteuid(0) failure\n"); + } + printuids("after seteuid(0)", realuid, 0); + + if (geteuid() != 0) + { + fail++; + printf("MAYDAY! Wrong effective uid\n"); + } + if (getuid() != realuid) + { + fail++; + printf("MAYDAY! Wrong real uid\n"); + } + + if (fail) + { + printf("\nThis system cannot use seteuid\n"); + exit(1); + } + + exit(0); +} + +printuids(str, r, e) + char *str; + int r, e; +{ + printf("%s (should be %d/%d): r/euid=%d/%d\n", str, r, e, + getuid(), geteuid()); +} diff --git a/usr.sbin/sendmail/test/t_setreuid.c b/usr.sbin/sendmail/test/t_setreuid.c new file mode 100644 index 000000000000..ca9a06f448b6 --- /dev/null +++ b/usr.sbin/sendmail/test/t_setreuid.c @@ -0,0 +1,132 @@ +/* +** This program checks to see if your version of setreuid works. +** Compile it, make it setuid root, and run it as yourself (NOT as +** root). If it won't compile or outputs any MAYDAY messages, don't +** define HASSETREUID in conf.h. +** +** Compilation is trivial -- just "cc t_setreuid.c". Make it setuid, +** root and then execute it as a non-root user. +*/ + +#include <sys/types.h> +#include <unistd.h> +#include <stdio.h> + +#ifdef __hpux +#define setreuid(r, e) setresuid(r, e, -1) +#endif + +main() +{ + int fail = 0; + uid_t realuid = getuid(); + + printuids("initial uids", realuid, 0); + + if (geteuid() != 0) + { + printf("SETUP ERROR: re-run setuid root\n"); + exit(1); + } + + if (getuid() == 0) + { + printf("SETUP ERROR: must be run by a non-root user\n"); + exit(1); + } + + if (setreuid(0, 1) < 0) + { + fail++; + printf("setreuid(0, 1) failure\n"); + } + printuids("after setreuid(0, 1)", 0, 1); + + if (geteuid() != 1) + { + fail++; + printf("MAYDAY! Wrong effective uid\n"); + } + + /* do activity here */ + + if (setreuid(-1, 0) < 0) + { + fail++; + printf("setreuid(-1, 0) failure\n"); + } + printuids("after setreuid(-1, 0)", 0, 0); + if (setreuid(realuid, 0) < 0) + { + fail++; + printf("setreuid(%d, 0) failure\n", realuid); + } + printuids("after setreuid(realuid, 0)", realuid, 0); + + if (geteuid() != 0) + { + fail++; + printf("MAYDAY! Wrong effective uid\n"); + } + if (getuid() != realuid) + { + fail++; + printf("MAYDAY! Wrong real uid\n"); + } + printf("\n"); + + if (setreuid(0, 2) < 0) + { + fail++; + printf("setreuid(0, 2) failure\n"); + } + printuids("after setreuid(0, 2)", 0, 2); + + if (geteuid() != 2) + { + fail++; + printf("MAYDAY! Wrong effective uid\n"); + } + + /* do activity here */ + + if (setreuid(-1, 0) < 0) + { + fail++; + printf("setreuid(-1, 0) failure\n"); + } + printuids("after setreuid(-1, 0)", 0, 0); + if (setreuid(realuid, 0) < 0) + { + fail++; + printf("setreuid(%d, 0) failure\n", realuid); + } + printuids("after setreuid(realuid, 0)", realuid, 0); + + if (geteuid() != 0) + { + fail++; + printf("MAYDAY! Wrong effective uid\n"); + } + if (getuid() != realuid) + { + fail++; + printf("MAYDAY! Wrong real uid\n"); + } + + if (fail) + { + printf("\nThis system cannot use setreuid\n"); + exit(1); + } + + exit(0); +} + +printuids(str, r, e) + char *str; + int r, e; +{ + printf("%s (should be %d/%d): r/euid=%d/%d\n", str, r, e, + getuid(), geteuid()); +} |