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*4078Seric static char SccsId[] = "@(#)conf.c 3.14 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 138*4078Seric /* user-private mailers -- must be #2 */ 139*4078Seric static char *PrivArgv[] = 140*4078Seric { 141*4078Seric "...priv%mail", 142*4078Seric "$u", 143*4078Seric NULL 144*4078Seric }; 145*4078Seric 146*4078Seric static struct mailer PrivMailer = 147*4078Seric { 148*4078Seric "priv", NULL, 149*4078Seric M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT, 150*4078Seric EX_UNAVAILABLE, "$f", PrivArgv, NULL, 151*4078Seric }; 152*4078Seric 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 */ 211*4078Seric &PrivMailer, /* 2 -- must be 2 */ 212*4078Seric &BerkMailer, /* 3 */ 213*4078Seric &ArpaMailer, /* 4 */ 214*4078Seric &UucpMailer, /* 5 */ 2153144Seric NULL 2163046Seric }; 2173046Seric 218*4078Seric /* offsets for arbitrary mailers */ 219*4078Seric # define M_BERK 2 /* berknet */ 220*4078Seric # define M_ARPA 3 /* arpanet */ 221*4078Seric # 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 extern int errno; 280294Seric 281294Seric /* compute the pathname of the controlling tty */ 282294Seric if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 283294Seric { 284294Seric errno = 0; 285294Seric return (NULL); 286294Seric } 287294Seric pathn[8] = i; 288294Seric 289294Seric /* see if we have write permission */ 2902967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 291294Seric { 292294Seric errno = 0; 293294Seric return (NULL); 294294Seric } 295294Seric 296294Seric /* see if the user is logged in */ 297294Seric if (getlogin() == NULL) 298294Seric return (NULL); 299294Seric 300294Seric /* looks good */ 301294Seric return (pathn); 302294Seric } 303294Seric /* 304294Seric ** FDOPEN -- Open a stdio file given an open file descriptor. 305294Seric ** 306294Seric ** This is included here because it is standard in v7, but we 307294Seric ** need it in v6. 308294Seric ** 309294Seric ** Algorithm: 310294Seric ** Open /dev/null to create a descriptor. 311294Seric ** Close that descriptor. 312294Seric ** Copy the existing fd into the descriptor. 313294Seric ** 314294Seric ** Parameters: 315294Seric ** fd -- the open file descriptor. 316294Seric ** type -- "r", "w", or whatever. 317294Seric ** 318294Seric ** Returns: 319294Seric ** The file descriptor it creates. 320294Seric ** 321294Seric ** Side Effects: 322294Seric ** none 323294Seric ** 324294Seric ** Called By: 325294Seric ** deliver 326294Seric ** 327294Seric ** Notes: 328294Seric ** The mode of fd must match "type". 329294Seric */ 330294Seric 331294Seric FILE * 332294Seric fdopen(fd, type) 333294Seric int fd; 334294Seric char *type; 335294Seric { 336294Seric register FILE *f; 337294Seric 338294Seric f = fopen("/dev/null", type); 339294Seric close(fileno(f)); 340294Seric fileno(f) = fd; 341294Seric return (f); 342294Seric } 343294Seric /* 344294Seric ** INDEX -- Return pointer to character in string 345294Seric ** 346294Seric ** For V7 compatibility. 347294Seric ** 348294Seric ** Parameters: 349294Seric ** s -- a string to scan. 350294Seric ** c -- a character to look for. 351294Seric ** 352294Seric ** Returns: 353294Seric ** If c is in s, returns the address of the first 354294Seric ** instance of c in s. 355294Seric ** NULL if c is not in s. 356294Seric ** 357294Seric ** Side Effects: 358294Seric ** none. 359294Seric */ 360294Seric 361294Seric index(s, c) 362294Seric register char *s; 363294Seric register char c; 364294Seric { 365294Seric while (*s != '\0') 366294Seric { 367294Seric if (*s++ == c) 368294Seric return (--s); 369294Seric } 370294Seric return (NULL); 371294Seric } 372294Seric # endif V6 373294Seric 374294Seric # ifndef V6 375294Seric /* 376294Seric ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 377294Seric ** 378294Seric ** Returns the pathname of the user's tty. Returns NULL if 379294Seric ** the user is not logged in or if s/he has write permission 380294Seric ** denied. 381294Seric ** 382294Seric ** Parameters: 383294Seric ** none 384294Seric ** 385294Seric ** Returns: 386294Seric ** pathname of the user's tty. 387294Seric ** NULL if not logged in or write permission denied. 388294Seric ** 389294Seric ** Side Effects: 390294Seric ** none. 391294Seric ** 392294Seric ** WARNING: 393294Seric ** Return value is in a local buffer. 394294Seric ** 395294Seric ** Called By: 396294Seric ** savemail 397294Seric */ 398294Seric 399294Seric # include <sys/types.h> 400294Seric # include <sys/stat.h> 401294Seric 402294Seric char * 403294Seric ttypath() 404294Seric { 405294Seric struct stat stbuf; 406294Seric register char *pathn; 407294Seric extern int errno; 408294Seric extern char *ttyname(); 409294Seric 410294Seric /* compute the pathname of the controlling tty */ 411294Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 412294Seric { 413294Seric errno = 0; 414294Seric return (NULL); 415294Seric } 416294Seric 417294Seric /* see if we have write permission */ 4182967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 419294Seric { 420294Seric errno = 0; 421294Seric return (NULL); 422294Seric } 423294Seric 424294Seric /* see if the user is logged in */ 425294Seric if (getlogin() == NULL) 426294Seric return (NULL); 427294Seric 428294Seric /* looks good */ 429294Seric return (pathn); 430294Seric } 431294Seric # endif V6 4322967Seric /* 4332967Seric ** CHECKCOMPAT -- check for From and To person compatible. 4342967Seric ** 4352967Seric ** This routine can be supplied on a per-installation basis 4362967Seric ** to determine whether a person is allowed to send a message. 4372967Seric ** This allows restriction of certain types of internet 4382967Seric ** forwarding or registration of users. 4392967Seric ** 4402967Seric ** If the hosts are found to be incompatible, an error 4412967Seric ** message should be given using "usrerr" and FALSE should 4422967Seric ** be returned. 4432967Seric ** 4442967Seric ** Parameters: 4452967Seric ** to -- the person being sent to. 4462967Seric ** 4472967Seric ** Returns: 4482967Seric ** TRUE -- ok to send. 4492967Seric ** FALSE -- not ok. 4502967Seric ** 4512967Seric ** Side Effects: 4522967Seric ** none (unless you include the usrerr stuff) 4532967Seric */ 4542967Seric 4552967Seric bool 4562967Seric checkcompat(to) 4572967Seric register ADDRESS *to; 4582967Seric { 4592967Seric return (TRUE); 4602967Seric } 461