Annotation of 43BSDReno/usr.sbin/sendmail/src/conf.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.