home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / sendmail / src / conf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-20  |  11.6 KB  |  581 lines

  1. /*
  2.  * Copyright (c) 1983 Eric P. Allman
  3.  * Copyright (c) 1988 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  *    This product includes software developed by the University of
  17.  *    California, Berkeley and its contributors.
  18.  * 4. Neither the name of the University nor the names of its contributors
  19.  *    may be used to endorse or promote products derived from this software
  20.  *    without specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  */
  34.  
  35. #ifndef lint
  36. static char sccsid[] = "@(#)conf.c    5.28 (Berkeley) 3/12/91";
  37. #endif /* not lint */
  38.  
  39. # include <sys/ioctl.h>
  40. # include <sys/param.h>
  41. # include <pwd.h>
  42. # include "sendmail.h"
  43. # include "pathnames.h"
  44.  
  45. /*
  46. **  CONF.C -- Sendmail Configuration Tables.
  47. **
  48. **    Defines the configuration of this installation.
  49. **
  50. **    Compilation Flags:
  51. **        VMUNIX -- running on a Berkeley UNIX system.
  52. **
  53. **    Configuration Variables:
  54. **        HdrInfo -- a table describing well-known header fields.
  55. **            Each entry has the field name and some flags,
  56. **            which are described in sendmail.h.
  57. **
  58. **    Notes:
  59. **        I have tried to put almost all the reasonable
  60. **        configuration information into the configuration
  61. **        file read at runtime.  My intent is that anything
  62. **        here is a function of the version of UNIX you
  63. **        are running, or is really static -- for example
  64. **        the headers are a superset of widely used
  65. **        protocols.  If you find yourself playing with
  66. **        this file too much, you may be making a mistake!
  67. */
  68.  
  69.  
  70.  
  71.  
  72. /*
  73. **  Header info table
  74. **    Final (null) entry contains the flags used for any other field.
  75. **
  76. **    Not all of these are actually handled specially by sendmail
  77. **    at this time.  They are included as placeholders, to let
  78. **    you know that "someday" I intend to have sendmail do
  79. **    something with them.
  80. */
  81.  
  82. struct hdrinfo    HdrInfo[] =
  83. {
  84.         /* originator fields, most to least significant  */
  85.     "resent-sender",    H_FROM|H_RESENT,
  86.     "resent-from",        H_FROM|H_RESENT,
  87.     "resent-reply-to",    H_FROM|H_RESENT,
  88.     "sender",        H_FROM,
  89.     "from",            H_FROM,
  90.     "reply-to",        H_FROM,
  91.     "full-name",        H_ACHECK,
  92.     "return-receipt-to",    H_FROM,
  93.     "errors-to",        H_FROM,
  94.         /* destination fields */
  95.     "to",            H_RCPT,
  96.     "resent-to",        H_RCPT|H_RESENT,
  97.     "cc",            H_RCPT,
  98.     "resent-cc",        H_RCPT|H_RESENT,
  99.     "bcc",            H_RCPT|H_ACHECK,
  100.     "resent-bcc",        H_RCPT|H_ACHECK|H_RESENT,
  101.         /* message identification and control */
  102.     "message-id",        0,
  103.     "resent-message-id",    H_RESENT,
  104.     "message",        H_EOH,
  105.     "text",            H_EOH,
  106.         /* date fields */
  107.     "date",            0,
  108.     "resent-date",        H_RESENT,
  109.         /* trace fields */
  110.     "received",        H_TRACE|H_FORCE,
  111.     "via",            H_TRACE|H_FORCE,
  112.     "mail-from",        H_TRACE|H_FORCE,
  113.  
  114.     NULL,            0,
  115. };
  116.  
  117.  
  118. /*
  119. **  ARPANET error message numbers.
  120. */
  121.  
  122. char    Arpa_Info[] =        "050";    /* arbitrary info */
  123. char    Arpa_TSyserr[] =    "451";    /* some (transient) system error */
  124. char    Arpa_PSyserr[] =    "554";    /* some (permanent) system error */
  125. char    Arpa_Usrerr[] =        "554";    /* some (fatal) user error */
  126.  
  127.  
  128.  
  129. /*
  130. **  Location of system files/databases/etc.
  131. */
  132.  
  133. char    *ConfFile =    _PATH_SENDMAILCF;    /* runtime configuration */
  134. char    *FreezeFile =    _PATH_SENDMAILFC;    /* frozen version of above */
  135.  
  136.  
  137.  
  138. /*
  139. **  Miscellaneous stuff.
  140. */
  141.  
  142. int    DtableSize =    50;        /* max open files; reset in 4.2bsd */
  143. extern int la;                /* load average */
  144. /*
  145. **  SETDEFAULTS -- set default values
  146. **
  147. **    Because of the way freezing is done, these must be initialized
  148. **    using direct code.
  149. **
  150. **    Parameters:
  151. **        none.
  152. **
  153. **    Returns:
  154. **        none.
  155. **
  156. **    Side Effects:
  157. **        Initializes a bunch of global variables to their
  158. **        default values.
  159. */
  160.  
  161. setdefaults()
  162. {
  163.     QueueLA = 8;
  164.     QueueFactor = 10000;
  165.     RefuseLA = 12;
  166.     SpaceSub = ' ';
  167.     WkRecipFact = 1000;
  168.     WkClassFact = 1800;
  169.     WkTimeFact = 9000;
  170.     FileMode = 0644;
  171.     DefUid = 1;
  172.     DefGid = 1;
  173.     CheckpointInterval = 10;
  174.     setdefuser();
  175. }
  176.  
  177.  
  178. /*
  179. **  SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
  180. */
  181.  
  182. setdefuser()
  183. {
  184.     struct passwd *defpwent;
  185.  
  186.     if (DefUser != NULL)
  187.         free(DefUser);
  188.     if ((defpwent = getpwuid(DefUid)) != NULL)
  189.         DefUser = newstr(defpwent->pw_name);
  190.     else
  191.         DefUser = newstr("nobody");
  192. }
  193.  
  194.  
  195. /*
  196. **  GETRUID -- get real user id (V7)
  197. */
  198.  
  199. getruid()
  200. {
  201.     if (OpMode == MD_DAEMON)
  202.         return (RealUid);
  203.     else
  204.         return (getuid());
  205. }
  206.  
  207.  
  208. /*
  209. **  GETRGID -- get real group id (V7).
  210. */
  211.  
  212. getrgid()
  213. {
  214.     if (OpMode == MD_DAEMON)
  215.         return (RealGid);
  216.     else
  217.         return (getgid());
  218. }
  219.  
  220. /*
  221. **  USERNAME -- return the user id of the logged in user.
  222. **
  223. **    Parameters:
  224. **        none.
  225. **
  226. **    Returns:
  227. **        The login name of the logged in user.
  228. **
  229. **    Side Effects:
  230. **        none.
  231. **
  232. **    Notes:
  233. **        The return value is statically allocated.
  234. */
  235.  
  236. char *
  237. username()
  238. {
  239.     static char *myname = NULL;
  240.     extern char *getlogin();
  241.     register struct passwd *pw;
  242.  
  243.     /* cache the result */
  244.     if (myname == NULL)
  245.     {
  246.         myname = getlogin();
  247.         if (myname == NULL || myname[0] == '\0')
  248.         {
  249.  
  250.             pw = getpwuid(getruid());
  251.             if (pw != NULL)
  252.                 myname = newstr(pw->pw_name);
  253.         }
  254.         else
  255.         {
  256.  
  257.             myname = newstr(myname);
  258.             if ((pw = getpwnam(myname)) == NULL ||
  259.                   getuid() != pw->pw_uid)
  260.             {
  261.                 pw = getpwuid(getuid());
  262.                 if (pw != NULL)
  263.                     myname = newstr(pw->pw_name);
  264.             }
  265.         }
  266.         if (myname == NULL || myname[0] == '\0')
  267.         {
  268.             syserr("Who are you?");
  269.             myname = "postmaster";
  270.         }
  271.     }
  272.  
  273.     return (myname);
  274. }
  275. /*
  276. **  TTYPATH -- Get the path of the user's tty
  277. **
  278. **    Returns the pathname of the user's tty.  Returns NULL if
  279. **    the user is not logged in or if s/he has write permission
  280. **    denied.
  281. **
  282. **    Parameters:
  283. **        none
  284. **
  285. **    Returns:
  286. **        pathname of the user's tty.
  287. **        NULL if not logged in or write permission denied.
  288. **
  289. **    Side Effects:
  290. **        none.
  291. **
  292. **    WARNING:
  293. **        Return value is in a local buffer.
  294. **
  295. **    Called By:
  296. **        savemail
  297. */
  298.  
  299. # include <sys/stat.h>
  300.  
  301. char *
  302. ttypath()
  303. {
  304.     struct stat stbuf;
  305.     register char *pathn;
  306.     extern char *ttyname();
  307.     extern char *getlogin();
  308.  
  309.     /* compute the pathname of the controlling tty */
  310.     if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
  311.         (pathn = ttyname(0)) == NULL)
  312.     {
  313.         errno = 0;
  314.         return (NULL);
  315.     }
  316.  
  317.     /* see if we have write permission */
  318.     if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
  319.     {
  320.         errno = 0;
  321.         return (NULL);
  322.     }
  323.  
  324.     /* see if the user is logged in */
  325.     if (getlogin() == NULL)
  326.         return (NULL);
  327.  
  328.     /* looks good */
  329.     return (pathn);
  330. }
  331. /*
  332. **  CHECKCOMPAT -- check for From and To person compatible.
  333. **
  334. **    This routine can be supplied on a per-installation basis
  335. **    to determine whether a person is allowed to send a message.
  336. **    This allows restriction of certain types of internet
  337. **    forwarding or registration of users.
  338. **
  339. **    If the hosts are found to be incompatible, an error
  340. **    message should be given using "usrerr" and FALSE should
  341. **    be returned.
  342. **
  343. **    'NoReturn' can be set to suppress the return-to-sender
  344. **    function; this should be done on huge messages.
  345. **
  346. **    Parameters:
  347. **        to -- the person being sent to.
  348. **
  349. **    Returns:
  350. **        TRUE -- ok to send.
  351. **        FALSE -- not ok.
  352. **
  353. **    Side Effects:
  354. **        none (unless you include the usrerr stuff)
  355. */
  356.  
  357. bool
  358. checkcompat(to)
  359.     register ADDRESS *to;
  360. {
  361. # ifdef lint
  362.     if (to == NULL)
  363.         to++;
  364. # endif lint
  365. # ifdef EXAMPLE_CODE
  366.     /* this code is intended as an example only */
  367.     register STAB *s;
  368.  
  369.     s = stab("arpa", ST_MAILER, ST_FIND);
  370.     if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
  371.         to->q_mailer == s->s_mailer)
  372.     {
  373.         usrerr("No ARPA mail through this machine: see your system administration");
  374.         /* NoReturn = TRUE; to supress return copy */
  375.         return (FALSE);
  376.     }
  377. # endif EXAMPLE_CODE
  378.     return (TRUE);
  379. }
  380. /*
  381. **  HOLDSIGS -- arrange to hold all signals
  382. **
  383. **    Parameters:
  384. **        none.
  385. **
  386. **    Returns:
  387. **        none.
  388. **
  389. **    Side Effects:
  390. **        Arranges that signals are held.
  391. */
  392.  
  393. holdsigs()
  394. {
  395. }
  396. /*
  397. **  RLSESIGS -- arrange to release all signals
  398. **
  399. **    This undoes the effect of holdsigs.
  400. **
  401. **    Parameters:
  402. **        none.
  403. **
  404. **    Returns:
  405. **        none.
  406. **
  407. **    Side Effects:
  408. **        Arranges that signals are released.
  409. */
  410.  
  411. rlsesigs()
  412. {
  413. }
  414. /*
  415. **  GETLA -- get the current load average
  416. **
  417. **    This code stolen from la.c.
  418. **
  419. **    Parameters:
  420. **        none.
  421. **
  422. **    Returns:
  423. **        The current load average as an integer.
  424. **
  425. **    Side Effects:
  426. **        none.
  427. */
  428.  
  429. #ifndef sun
  430.  
  431. getla()
  432. {
  433.     double avenrun[3];
  434.  
  435.     if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
  436.         return (0);
  437.     return ((int) (avenrun[0] + 0.5));
  438. }
  439.  
  440. #else /* sun */
  441.  
  442. #include <nlist.h>
  443.  
  444. struct    nlist Nl[] =
  445. {
  446.     { "_avenrun" },
  447. #define    X_AVENRUN    0
  448.     { 0 },
  449. };
  450.  
  451.  
  452. extern int la;
  453.  
  454. getla()
  455. {
  456.     static int kmem = -1;
  457.     long avenrun[3];
  458.     extern off_t lseek();
  459.  
  460.     if (kmem < 0)
  461.     {
  462.         kmem = open("/dev/kmem", 0, 0);
  463.         if (kmem < 0)
  464.             return (-1);
  465.         (void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
  466.         nlist("/vmunix", Nl);
  467.         if (Nl[0].n_type == 0)
  468.             return (-1);
  469.     }
  470.     if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
  471.         read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
  472.     {
  473.         /* thank you Ian */
  474.         return (-1);
  475.     }
  476.     return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
  477. }
  478.  
  479. #endif /* sun */
  480. /*
  481. **  SHOULDQUEUE -- should this message be queued or sent?
  482. **
  483. **    Compares the message cost to the load average to decide.
  484. **
  485. **    Parameters:
  486. **        pri -- the priority of the message in question.
  487. **
  488. **    Returns:
  489. **        TRUE -- if this message should be queued up for the
  490. **            time being.
  491. **        FALSE -- if the load is low enough to send this message.
  492. **
  493. **    Side Effects:
  494. **        none.
  495. */
  496.  
  497. bool
  498. shouldqueue(pri)
  499.     long pri;
  500. {
  501.     if (la < QueueLA)
  502.         return (FALSE);
  503.     return (pri > (QueueFactor / (la - QueueLA + 1)));
  504. }
  505. /*
  506. **  SETPROCTITLE -- set process title for ps
  507. **
  508. **    Parameters:
  509. **        fmt -- a printf style format string.
  510. **        a, b, c -- possible parameters to fmt.
  511. **
  512. **    Returns:
  513. **        none.
  514. **
  515. **    Side Effects:
  516. **        Clobbers argv of our main procedure so ps(1) will
  517. **        display the title.
  518. */
  519.  
  520. /*VARARGS1*/
  521. setproctitle(fmt, a, b, c)
  522.     char *fmt;
  523. {
  524. # ifdef SETPROCTITLE
  525.     register char *p;
  526.     register int i;
  527.     extern char **Argv;
  528.     extern char *LastArgv;
  529.     char buf[MAXLINE];
  530.  
  531.     (void) sprintf(buf, fmt, a, b, c);
  532.  
  533.     /* make ps print "(sendmail)" */
  534.     p = Argv[0];
  535.     *p++ = '-';
  536.  
  537.     i = strlen(buf);
  538.     if (i > LastArgv - p - 2)
  539.     {
  540.         i = LastArgv - p - 2;
  541.         buf[i] = '\0';
  542.     }
  543.     (void) strcpy(p, buf);
  544.     p += i;
  545.     while (p < LastArgv)
  546.         *p++ = ' ';
  547. # endif SETPROCTITLE
  548. }
  549. /*
  550. **  REAPCHILD -- pick up the body of my child, lest it become a zombie
  551. **
  552. **    Parameters:
  553. **        none.
  554. **
  555. **    Returns:
  556. **        none.
  557. **
  558. **    Side Effects:
  559. **        Picks up extant zombies.
  560. */
  561.  
  562. # ifdef VMUNIX
  563. # include <sys/wait.h>
  564. # endif VMUNIX
  565.  
  566. void
  567. reapchild()
  568. {
  569. # ifdef WNOHANG
  570.     union wait status;
  571.  
  572.     while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0)
  573.         continue;
  574. # else WNOHANG
  575.     auto int status;
  576.  
  577.     while (wait((int *)&status) > 0)
  578.         continue;
  579. # endif WNOHANG
  580. }
  581.