1294Seric # include <stdio.h> 2294Seric # include <pwd.h> 33309Seric # include "sendmail.h" 4404Seric 5294Seric /* 63309Seric ** CONF.C -- Sendmail Configuration Tables. 7294Seric ** 8294Seric ** Defines the configuration of this installation. 9294Seric ** 101388Seric ** Compilation Flags: 111388Seric ** NETV6MAIL -- set if you want to use "v6mail" that 121388Seric ** comes with the Berkeley network. Normally 131388Seric ** /bin/mail will work fine, but around Berkeley 141388Seric ** we use v6mail because it is a "fixed target". 152355Seric ** Also, only v6mail has the "/dev/mail" stuff 162355Seric ** in it (for biff(1)). 171388Seric ** V6 -- running on a version 6 system. This determines 181388Seric ** whether to define certain routines between 191388Seric ** the two systems. If you are running a funny 201388Seric ** system, e.g., V6 with long tty names, this 211388Seric ** should be checked carefully. 22294Seric ** 231388Seric ** Configuration Variables: 241388Seric ** Mailer -- a table of mailers known to the system. 253438Seric ** This should be fairly static. The fields are: 261388Seric ** - the pathname of the mailer. 271388Seric ** - a list of flags describing the properties 281388Seric ** of this mailer: 291388Seric ** M_FOPT -- if set, the mailer has a picky "-f" 301388Seric ** option. In this mode, the mailer will 311388Seric ** only accept the "-f" option if the 321388Seric ** sender is actually "root", "network", 331388Seric ** and possibly (but not necessarily) if 341388Seric ** the -f argument matches the real sender. 351388Seric ** The effect is that if the "-f" option 363309Seric ** is given to sendmail then it will be 371388Seric ** passed through (as arguments 1 & 2) to 381388Seric ** the mailer. 391388Seric ** M_ROPT -- identical to M_FOPT, except uses 401388Seric ** -r instead. 411388Seric ** M_QUIET -- if set, don't print a message if 421388Seric ** the mailer returns bad status. 431388Seric ** M_RESTR -- if set, this mailer is restricted 441388Seric ** to use by "daemon"; otherwise, we do a 451388Seric ** setuid(getuid()) before calling the 461388Seric ** mailer. 473185Seric ** M_NHDR -- if set, the mailer doesn't want us 483185Seric ** to insert a UNIX "From" line before 491388Seric ** outputing. 501388Seric ** M_NOHOST -- if set, this mailer doesn't care 511388Seric ** about the host part (e.g., the local 521388Seric ** mailer). 531388Seric ** M_STRIPQ -- if set, strip quote (`"') 541388Seric ** characters out of parameters as you 551388Seric ** transliterate them into the argument 561388Seric ** vector. For example, the local mailer 571388Seric ** is called directly, so these should be 581388Seric ** stripped, but the program-mailer (i.e., 591388Seric ** csh) should leave them in. 602897Seric ** M_NEEDDATE -- this mailer requires a Date: 612897Seric ** field in the message. 622897Seric ** M_NEEDFROM -- this mailer requires a From: 632897Seric ** field in the message. 642897Seric ** M_MSGID -- this mailer requires a Message-Id 652897Seric ** field in the message. 663185Seric ** M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID. 671388Seric ** - an exit status to use as the code for the 681388Seric ** error message print if the mailer returns 691388Seric ** something we don't understand. 701388Seric ** - A list of names that are to be considered 711388Seric ** "local" (and hence are stripped off) for 721388Seric ** this mailer. 731388Seric ** - An argument vector to be passed to the 743438Seric ** mailer; this is macro substituted. 751388Seric ** >>>>>>>>>> Entry zero must be for the local 761388Seric ** >> NOTE >> mailer and entry one must be for 771388Seric ** >>>>>>>>>> the shell. 782897Seric ** HdrInfo -- a table describing well-known header fields. 792897Seric ** Each entry has the field name and some flags, 802897Seric ** which can be: 813057Seric ** - H_EOH -- this field is equivalent to a blank 823057Seric ** line; i.e., it signifies end of header. 833057Seric ** - H_DELETE -- delete this field. 843057Seric ** There is also a field pointing to a pointer 853057Seric ** that should be set to point to this header. 86294Seric */ 87294Seric 88294Seric 89294Seric 90294Seric 91*4081Seric static char SccsId[] = "@(#)conf.c 3.15 08/09/81"; 92294Seric 931388Seric 941388Seric # include <whoami.h> /* definitions of machine id's at berkeley */ 951388Seric 961573Seric # ifdef BERKELEY 972355Seric # define NETV6MAIL /* use /usr/net/bin/v6mail for local delivery */ 983061Seric # endif BERKELEY 993061Seric 1003061Seric 1013061Seric 1023046Seric /* local mail -- must be #0 */ 1033046Seric static char *LocalArgv[] = 104294Seric { 1053046Seric "...local%mail", 1063046Seric "-d", 1073046Seric "$u", 1083046Seric NULL 1093046Seric }; 1103046Seric 1113046Seric static struct mailer LocalMailer = 1123046Seric { 113294Seric # ifdef NETV6MAIL 1143185Seric "local", "/usr/net/bin/v6mail", 115294Seric # else 1163185Seric "local", "/bin/mail", 117294Seric # endif 1183185Seric M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT|M_MUSER|M_NHDR, 1193185Seric EX_NOUSER, "$f", LocalArgv, NULL, 1203046Seric }; 1213046Seric 1223185Seric /* pipes through programs -- must be #1 -- also used for files */ 1233046Seric static char *ProgArgv[] = 1243046Seric { 1253046Seric "...prog%mail", 1263046Seric "-fc", 1273046Seric "$u", 1283046Seric NULL 1293046Seric }; 1303046Seric 1313046Seric static struct mailer ProgMailer = 1323046Seric { 1333185Seric "prog", "/bin/csh", 1343185Seric M_NOHOST|M_ARPAFMT, 1353185Seric EX_UNAVAILABLE, "$f", ProgArgv, NULL, 1363046Seric }; 1373046Seric 1384078Seric /* user-private mailers -- must be #2 */ 1394078Seric static char *PrivArgv[] = 1404078Seric { 1414078Seric "...priv%mail", 1424078Seric "$u", 1434078Seric NULL 1444078Seric }; 1454078Seric 1464078Seric static struct mailer PrivMailer = 1474078Seric { 1484078Seric "priv", NULL, 1494078Seric M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT, 1504078Seric EX_UNAVAILABLE, "$f", PrivArgv, NULL, 1514078Seric }; 1524078Seric 1533046Seric /* local berkeley mail */ 1543046Seric static char *BerkArgv[] = 1553046Seric { 1563046Seric "...berk%mail", 1573046Seric "-m", 1583046Seric "$h", 1593232Seric "-h", 1603232Seric "$c", 1613046Seric "-t", 1623046Seric "$u", 1633046Seric NULL 1643046Seric }; 1653046Seric 1663046Seric static struct mailer BerkMailer = 1673046Seric { 1683185Seric "berk", "/usr/net/bin/sendberkmail", 1693388Seric M_FOPT|M_NEEDDATE|M_FULLNAME|M_STRIPQ, 1703185Seric EX_UNAVAILABLE, "$B:$f", BerkArgv, NULL, 1713046Seric }; 1723046Seric 1733046Seric /* arpanet mail */ 1743046Seric static char *ArpaArgv[] = 1753046Seric { 1763046Seric "...arpa%mail", 1773046Seric "$f", 1783046Seric "$h", 1793046Seric "$u", 1803046Seric NULL 1813046Seric }; 1823046Seric 1833046Seric static struct mailer ArpaMailer = 1843046Seric { 1853185Seric "arpa", "/usr/lib/mailers/arpa", 1863185Seric M_STRIPQ|M_ARPAFMT|M_USR_UPPER, 1873185Seric 0, "$f@$A", ArpaArgv, NULL, 1883046Seric }; 1893046Seric 1903046Seric /* uucp mail (cheat & use Bell's v7 mail) */ 1913046Seric static char *UucpArgv[] = 1923046Seric { 1933046Seric "...uucp%mail", 1943232Seric "-", 1953232Seric "$h!rmail", 1963232Seric "($u)", 1973046Seric NULL 198294Seric }; 199294Seric 2003046Seric static struct mailer UucpMailer = 2013046Seric { 2023232Seric "uucp", "/usr/bin/uux", 2033388Seric M_ROPT|M_STRIPQ|M_NEEDDATE|M_FULLNAME|M_MUSER, 2043185Seric EX_NOUSER, "$U!$f", UucpArgv, NULL, 2053046Seric }; 2063046Seric 2073046Seric struct mailer *Mailer[] = 2083046Seric { 2093046Seric &LocalMailer, /* 0 -- must be 0 */ 2103046Seric &ProgMailer, /* 1 -- must be 1 */ 2114078Seric &PrivMailer, /* 2 -- must be 2 */ 2124078Seric &BerkMailer, /* 3 */ 2134078Seric &ArpaMailer, /* 4 */ 2144078Seric &UucpMailer, /* 5 */ 2153144Seric NULL 2163046Seric }; 2173046Seric 2184078Seric /* offsets for arbitrary mailers */ 2194078Seric # define M_BERK 2 /* berknet */ 2204078Seric # define M_ARPA 3 /* arpanet */ 2214078Seric # define M_UUCP 4 /* UUCPnet */ 222294Seric 223294Seric 224294Seric 2253046Seric 2262897Seric 2272897Seric /* 2282897Seric ** Header info table 2293057Seric ** Final (null) entry contains the flags used for any other field. 2302897Seric */ 2312897Seric 2322897Seric struct hdrinfo HdrInfo[] = 2332897Seric { 2343384Seric "date", H_CHECK, M_NEEDDATE, 2353384Seric "from", H_CHECK, M_NEEDFROM, 2363388Seric "full-name", H_ACHECK, M_FULLNAME, 2373057Seric "to", 0, NULL, 2383057Seric "cc", 0, NULL, 2393057Seric "subject", 0, NULL, 2403384Seric "message-id", H_CHECK, M_MSGID, 2413057Seric "message", H_EOH, NULL, 2423057Seric NULL, 0, NULL, 2432897Seric }; 244294Seric 245294Seric # ifdef V6 246294Seric /* 247294Seric ** TTYPATH -- Get the path of the user's tty -- Version 6 version. 248294Seric ** 249294Seric ** Returns the pathname of the user's tty. Returns NULL if 250294Seric ** the user is not logged in or if s/he has write permission 251294Seric ** denied. 252294Seric ** 253294Seric ** Parameters: 254294Seric ** none 255294Seric ** 256294Seric ** Returns: 257294Seric ** pathname of the user's tty. 258294Seric ** NULL if not logged in or write permission denied. 259294Seric ** 260294Seric ** Side Effects: 261294Seric ** none. 262294Seric ** 263294Seric ** WARNING: 264294Seric ** Return value is in a local buffer. 265294Seric ** 266294Seric ** Called By: 267294Seric ** savemail 268294Seric */ 269294Seric 270294Seric # include <sys/types.h> 271294Seric # include <sys/stat.h> 272294Seric 273294Seric char * 274294Seric ttypath() 275294Seric { 276294Seric struct stat stbuf; 277294Seric register int i; 278294Seric static char pathn[] = "/dev/ttyx"; 279294Seric 280294Seric /* compute the pathname of the controlling tty */ 281294Seric if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 282294Seric { 283294Seric errno = 0; 284294Seric return (NULL); 285294Seric } 286294Seric pathn[8] = i; 287294Seric 288294Seric /* see if we have write permission */ 2892967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 290294Seric { 291294Seric errno = 0; 292294Seric return (NULL); 293294Seric } 294294Seric 295294Seric /* see if the user is logged in */ 296294Seric if (getlogin() == NULL) 297294Seric return (NULL); 298294Seric 299294Seric /* looks good */ 300294Seric return (pathn); 301294Seric } 302294Seric /* 303294Seric ** FDOPEN -- Open a stdio file given an open file descriptor. 304294Seric ** 305294Seric ** This is included here because it is standard in v7, but we 306294Seric ** need it in v6. 307294Seric ** 308294Seric ** Algorithm: 309294Seric ** Open /dev/null to create a descriptor. 310294Seric ** Close that descriptor. 311294Seric ** Copy the existing fd into the descriptor. 312294Seric ** 313294Seric ** Parameters: 314294Seric ** fd -- the open file descriptor. 315294Seric ** type -- "r", "w", or whatever. 316294Seric ** 317294Seric ** Returns: 318294Seric ** The file descriptor it creates. 319294Seric ** 320294Seric ** Side Effects: 321294Seric ** none 322294Seric ** 323294Seric ** Called By: 324294Seric ** deliver 325294Seric ** 326294Seric ** Notes: 327294Seric ** The mode of fd must match "type". 328294Seric */ 329294Seric 330294Seric FILE * 331294Seric fdopen(fd, type) 332294Seric int fd; 333294Seric char *type; 334294Seric { 335294Seric register FILE *f; 336294Seric 337294Seric f = fopen("/dev/null", type); 338*4081Seric (void) close(fileno(f)); 339294Seric fileno(f) = fd; 340294Seric return (f); 341294Seric } 342294Seric /* 343294Seric ** INDEX -- Return pointer to character in string 344294Seric ** 345294Seric ** For V7 compatibility. 346294Seric ** 347294Seric ** Parameters: 348294Seric ** s -- a string to scan. 349294Seric ** c -- a character to look for. 350294Seric ** 351294Seric ** Returns: 352294Seric ** If c is in s, returns the address of the first 353294Seric ** instance of c in s. 354294Seric ** NULL if c is not in s. 355294Seric ** 356294Seric ** Side Effects: 357294Seric ** none. 358294Seric */ 359294Seric 360294Seric index(s, c) 361294Seric register char *s; 362294Seric register char c; 363294Seric { 364294Seric while (*s != '\0') 365294Seric { 366294Seric if (*s++ == c) 367294Seric return (--s); 368294Seric } 369294Seric return (NULL); 370294Seric } 371294Seric # endif V6 372294Seric 373294Seric # ifndef V6 374294Seric /* 375294Seric ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 376294Seric ** 377294Seric ** Returns the pathname of the user's tty. Returns NULL if 378294Seric ** the user is not logged in or if s/he has write permission 379294Seric ** denied. 380294Seric ** 381294Seric ** Parameters: 382294Seric ** none 383294Seric ** 384294Seric ** Returns: 385294Seric ** pathname of the user's tty. 386294Seric ** NULL if not logged in or write permission denied. 387294Seric ** 388294Seric ** Side Effects: 389294Seric ** none. 390294Seric ** 391294Seric ** WARNING: 392294Seric ** Return value is in a local buffer. 393294Seric ** 394294Seric ** Called By: 395294Seric ** savemail 396294Seric */ 397294Seric 398294Seric # include <sys/types.h> 399294Seric # include <sys/stat.h> 400294Seric 401294Seric char * 402294Seric ttypath() 403294Seric { 404294Seric struct stat stbuf; 405294Seric register char *pathn; 406294Seric extern char *ttyname(); 407*4081Seric extern char *getlogin(); 408294Seric 409294Seric /* compute the pathname of the controlling tty */ 410294Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 411294Seric { 412294Seric errno = 0; 413294Seric return (NULL); 414294Seric } 415294Seric 416294Seric /* see if we have write permission */ 4172967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 418294Seric { 419294Seric errno = 0; 420294Seric return (NULL); 421294Seric } 422294Seric 423294Seric /* see if the user is logged in */ 424294Seric if (getlogin() == NULL) 425294Seric return (NULL); 426294Seric 427294Seric /* looks good */ 428294Seric return (pathn); 429294Seric } 430294Seric # endif V6 4312967Seric /* 4322967Seric ** CHECKCOMPAT -- check for From and To person compatible. 4332967Seric ** 4342967Seric ** This routine can be supplied on a per-installation basis 4352967Seric ** to determine whether a person is allowed to send a message. 4362967Seric ** This allows restriction of certain types of internet 4372967Seric ** forwarding or registration of users. 4382967Seric ** 4392967Seric ** If the hosts are found to be incompatible, an error 4402967Seric ** message should be given using "usrerr" and FALSE should 4412967Seric ** be returned. 4422967Seric ** 4432967Seric ** Parameters: 4442967Seric ** to -- the person being sent to. 4452967Seric ** 4462967Seric ** Returns: 4472967Seric ** TRUE -- ok to send. 4482967Seric ** FALSE -- not ok. 4492967Seric ** 4502967Seric ** Side Effects: 4512967Seric ** none (unless you include the usrerr stuff) 4522967Seric */ 4532967Seric 4542967Seric bool 4552967Seric checkcompat(to) 4562967Seric register ADDRESS *to; 4572967Seric { 458*4081Seric # ifdef lint 459*4081Seric ADDRESS *x = to; 460*4081Seric 461*4081Seric to = x; 462*4081Seric # endif lint 463*4081Seric 4642967Seric return (TRUE); 4652967Seric } 466