1 # include <stdio.h> 2 # include <pwd.h> 3 # include "postbox.h" 4 5 /* 6 ** CONF.C -- Postbox Configuration Tables. 7 ** 8 ** Defines the configuration of this installation. 9 ** 10 ** Compilation Flags: 11 ** HASARPA -- set if this machine has a connection to 12 ** the Arpanet. 13 ** HASUUCP -- set if this machine has a connection to 14 ** the UUCP network. 15 ** NETV6MAIL -- set if you want to use "v6mail" that 16 ** comes with the Berkeley network. Normally 17 ** /bin/mail will work fine, but around Berkeley 18 ** we use v6mail because it is a "fixed target". 19 ** Also, only v6mail has the "/dev/mail" stuff 20 ** in it (for biff(1)). 21 ** V6 -- running on a version 6 system. This determines 22 ** whether to define certain routines between 23 ** the two systems. If you are running a funny 24 ** system, e.g., V6 with long tty names, this 25 ** should be checked carefully. 26 ** DUMBMAIL -- set if your /bin/mail doesn't have the 27 ** -d flag. 28 ** 29 ** Configuration Variables: 30 ** ArpaHost -- the arpanet name of the host through 31 ** which arpanet mail will be sent. 32 ** MyLocName -- the name of the host on a local network. 33 ** This is used to disambiguate the contents of 34 ** ArpaHost among many hosts who may be sharing 35 ** a gateway. 36 ** DaemonName -- the name of this agent for use in 37 ** error messages, typically "~MAILER~DAEMON~" 38 ** at this host on the local net. 39 ** ArpaLocal -- a list of local names for this host on 40 ** the arpanet. Only functional if HASARPA set. 41 ** UucpLocal -- ditto for the Arpanet. 42 ** BerkLocal -- ditto for the Berknet. 43 ** Mailer -- a table of mailers known to the system. 44 ** The fields are: 45 ** - the pathname of the mailer. 46 ** - a list of flags describing the properties 47 ** of this mailer: 48 ** M_FOPT -- if set, the mailer has a picky "-f" 49 ** option. In this mode, the mailer will 50 ** only accept the "-f" option if the 51 ** sender is actually "root", "network", 52 ** and possibly (but not necessarily) if 53 ** the -f argument matches the real sender. 54 ** The effect is that if the "-f" option 55 ** is given to postbox then it will be 56 ** passed through (as arguments 1 & 2) to 57 ** the mailer. 58 ** M_ROPT -- identical to M_FOPT, except uses 59 ** -r instead. 60 ** M_QUIET -- if set, don't print a message if 61 ** the mailer returns bad status. 62 ** M_RESTR -- if set, this mailer is restricted 63 ** to use by "daemon"; otherwise, we do a 64 ** setuid(getuid()) before calling the 65 ** mailer. 66 ** M_HDR -- if set, the mailer wants us to 67 ** insert a UNIX "From" line before 68 ** outputing. 69 ** M_FHDR -- if set, the header that we 70 ** generate will be used literally, so 71 ** we must force it to be correct. The 72 ** effect is that we generate a header 73 ** even if one exists. 74 ** M_NOHOST -- if set, this mailer doesn't care 75 ** about the host part (e.g., the local 76 ** mailer). 77 ** M_STRIPQ -- if set, strip quote (`"') 78 ** characters out of parameters as you 79 ** transliterate them into the argument 80 ** vector. For example, the local mailer 81 ** is called directly, so these should be 82 ** stripped, but the program-mailer (i.e., 83 ** csh) should leave them in. 84 ** M_NEEDDATE -- this mailer requires a Date: 85 ** field in the message. 86 ** M_NEEDFROM -- this mailer requires a From: 87 ** field in the message. 88 ** M_MSGID -- this mailer requires a Message-Id 89 ** field in the message. 90 ** M_COMMAS -- this mailer wants comma- 91 ** seperated To: and Cc: fields. 92 ** M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID| 93 ** M_COMMAS. 94 ** - an exit status to use as the code for the 95 ** error message print if the mailer returns 96 ** something we don't understand. 97 ** - A list of names that are to be considered 98 ** "local" (and hence are stripped off) for 99 ** this mailer. 100 ** - An argument vector to be passed to the 101 ** mailer with the following substitutions: 102 ** $f - the from person name. 103 ** $u - the target user name. 104 ** $h - the target user host. 105 ** $c - the hop count. 106 ** >>>>>>>>>> Entry zero must be for the local 107 ** >> NOTE >> mailer and entry one must be for 108 ** >>>>>>>>>> the shell. 109 ** ParseTab -- a table driving the parsing process. Each 110 ** entry contains: 111 ** - a character that will trigger this entry. 112 ** - an index into the Mailer table. 113 ** - a word of flags, described in postbox.h. 114 ** - an argument. If we have P_MAP, it is the 115 ** character to turn the trigger character into. 116 ** If we have P_MOVE, it is the site to send it 117 ** to, using the mailer specified above. 118 ** This table will almost certainly have to be 119 ** changed on your site if you have anything more 120 ** than the UUCP net. 121 ** HdrInfo -- a table describing well-known header fields. 122 ** Each entry has the field name and some flags, 123 ** which can be: 124 ** - H_EOH -- this field is equivalent to a blank 125 ** line; i.e., it signifies end of header. 126 ** - H_DELETE -- delete this field. 127 ** There is also a field pointing to a pointer 128 ** that should be set to point to this header. 129 */ 130 131 132 133 134 static char SccsId[] = "@(#)conf.c 3.5 03/07/81"; 135 136 137 # include <whoami.h> /* definitions of machine id's at berkeley */ 138 139 # ifdef BERKELEY 140 141 char *ArpaHost = "Berkeley"; /* host name of gateway on Arpanet */ 142 char *UucpHost = "ucbvax"; /* host name of gateway on UUCP net */ 143 # define BerkHost MyLocName /* host name of gateway on Berk net */ 144 # define NETV6MAIL /* use /usr/net/bin/v6mail for local delivery */ 145 146 # else BERKELEY 147 148 char *ArpaHost = "[unknown]"; 149 char *MyLocName = sysname; 150 # define HASUUCP /* default to having UUCP net */ 151 char *UucpLocal[] = { sysname, NULL }; 152 153 # endif BERKELEY 154 155 156 /* Specific Configurations for Berkeley Machines */ 157 158 /* Berkeley people: mail changes to csvax:eric or they will be lost! */ 159 160 # ifdef ING70 161 static char *BerkLocal[] = { "i", "ingres", "ing70", NULL }; 162 char *ArpaLocal = { "berkeley", "ucb", NULL }; 163 char *MyLocName = "Ing70"; 164 char *DaemonName = "Ing70:~MAILER~DAEMON~"; 165 # define HASARPA 166 # define V6 167 # endif ING70 168 169 # ifdef INGVAX 170 static char *BerkLocal[] = { "j", "ingvax", NULL }; 171 char *MyLocName = "IngVax"; 172 char *DaemonName = "IngVax:~MAILER~DAEMON~"; 173 # endif INGVAX 174 175 # ifdef CSVAX 176 static char *BerkLocal[] = { "v", "csvax", "vax", NULL }; 177 static char *UucpLocal[] = { "ucbvax", "ernie", NULL }; 178 char *MyLocName = "CSVAX"; 179 char *DaemonName = "CSVAX:~MAILER~DAEMON~"; 180 # define HASUUCP 181 # endif CSVAX 182 183 # ifdef ARPAVAX 184 static char *BerkLocal[] = { "r", "arpavax", NULL }; 185 char *MyLocName = "ARPAVAX"; 186 char *DaemonName = "ARPAVAX:~MAILER~DAEMON~"; 187 # endif ARPAVAX 188 189 # ifdef CORY 190 static char *BerkLocal[] = { "y", "cory", NULL }; 191 char *MyLocName = "Cory"; 192 char *DaemonName = "Cory:~MAILER~DAEMON~"; 193 # endif CORY 194 195 # ifdef ONYX 196 static char *BerkLocal[[] = { "x", "onyx", NULL }; 197 char *MyLocName = "Onyx"; 198 char *DaemonName = "Onyx:~MAILER~DAEMON~"; 199 # endif ONYX 200 201 # ifdef IMAGE 202 /* untested */ 203 static char *BerkLocal[] = { "m", "image", NULL }; 204 char *MyLocName = "Image"; 205 char *DaemonName = "Image:~MAILER~DAEMON~"; 206 # define V6 207 # endif IMAGE 208 209 # ifdef ESVAX 210 static char *BerkLocal[] = { "o", "esvax", NULL }; 211 char *MyLocName = "ESVAX"; 212 char *DaemonName = "ESVAX:~MAILER~DAEMON~"; 213 # endif ESVAX 214 215 # ifdef EECS40 216 /* untested */ 217 static char *BerkLocal[] = { "z", "eecs40", NULL }; 218 char *MyLocName = "EECS40"; 219 char *DaemonName = "EECS40:~MAILER~DAEMON~"; 220 # define V6 221 # endif EECS40 222 223 224 # ifndef HASARPA 225 # define ArpaLocal NULL 226 # endif HASARPA 227 228 # ifndef HASUUCP 229 # define UucpLocal NULL 230 # endif HASUUCP 231 232 233 /* local mail -- must be #0 */ 234 static char *LocalArgv[] = 235 { 236 "...local%mail", 237 "-d", 238 "$u", 239 NULL 240 }; 241 242 static struct mailer LocalMailer = 243 { 244 # ifdef NETV6MAIL 245 "/usr/net/bin/v6mail", 246 # else 247 "/bin/mail", 248 # endif 249 M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT, EX_NOUSER, NULL, 250 "$f", NULL, LocalArgv, 251 }; 252 253 /* pipes through programs -- must be #1 */ 254 static char *ProgArgv[] = 255 { 256 "...prog%mail", 257 "-fc", 258 "$u", 259 NULL 260 }; 261 262 static struct mailer ProgMailer = 263 { 264 "/bin/csh", 265 M_HDR|M_FHDR|M_NOHOST, EX_UNAVAILABLE, NULL, 266 "$f", NULL, ProgArgv, 267 }; 268 269 /* local berkeley mail */ 270 static char *BerkArgv[] = 271 { 272 "...berk%mail", 273 "-m", 274 "$h", 275 "-t", 276 "$u", 277 "-h", 278 "$c", 279 NULL 280 }; 281 282 static struct mailer BerkMailer = 283 { 284 "/usr/net/bin/sendberkmail", 285 M_FOPT|M_HDR|M_STRIPQ, EX_UNAVAILABLE, BerkLocal, 286 "$B:$f", NULL, BerkArgv, 287 }; 288 289 /* arpanet mail */ 290 static char *ArpaArgv[] = 291 { 292 "...arpa%mail", 293 "$f", 294 "$h", 295 "$u", 296 NULL 297 }; 298 299 static struct mailer ArpaMailer = 300 { 301 "/usr/lib/mailers/arpa", 302 M_STRIPQ|M_ARPAFMT, 0, ArpaLocal, 303 "$f@$A", NULL, ArpaArgv, 304 }; 305 306 /* uucp mail (cheat & use Bell's v7 mail) */ 307 static char *UucpArgv[] = 308 { 309 "...uucp%mail", 310 # ifdef DUMBMAIL 311 "-d", 312 # endif DUMBMAIL 313 "$h!$u", 314 NULL 315 }; 316 317 static struct mailer UucpMailer = 318 { 319 "/bin/mail", 320 M_ROPT|M_STRIPQ, EX_NOUSER, UucpLocal, 321 "$U!$f", NULL, UucpArgv, 322 }; 323 324 struct mailer *Mailer[] = 325 { 326 &LocalMailer, /* 0 -- must be 0 */ 327 &ProgMailer, /* 1 -- must be 1 */ 328 &BerkMailer, /* 2 */ 329 &ArpaMailer, /* 3 */ 330 &UucpMailer, /* 4 */ 331 }; 332 333 # define NMAILERS (sizeof Mailer / sizeof Mailer[0]) 334 335 # define M_LOCAL 0 336 # define M_PROG 1 337 # define M_BERK 2 338 # define M_ARPA 3 339 # define M_UUCP 4 340 341 /* list of messages for each mailer (sorted by host) */ 342 ADDRESS MailList[NMAILERS]; 343 344 345 346 # ifdef BERKELEY 347 struct parsetab ParseTab[] = 348 { 349 ':', M_BERK, P_ONE, NULL, 350 # ifdef HASARPA 351 '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 352 # else 353 '@', M_BERK, P_HLAST|P_USR_UPPER|P_MOVE, "ing70", 354 # endif HASARPA 355 '^', -1, P_MAP, "!", 356 # ifdef HASUUCP 357 '!', M_UUCP, 0, NULL, 358 # else 359 '!', M_BERK, P_MOVE, "csvax", 360 # endif HASUUCP 361 '.', -1, P_MAP|P_ONE, ":", 362 '\0', M_LOCAL, P_MOVE, "", 363 }; 364 # else BERKELEY 365 struct parsetab ParseTab[] = 366 { 367 # ifdef HASARPA 368 '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 369 # endif HASARPA 370 # ifdef HASUUCP 371 '^', -1, P_MAP, "!", 372 '!', M_UUCP, 0, NULL, 373 # endif HASUUCP 374 '\0', M_LOCAL, P_MOVE, "", 375 }; 376 # endif BERKELEY 377 378 379 /* 380 ** Header info table 381 ** Final (null) entry contains the flags used for any other field. 382 */ 383 384 struct hdrinfo HdrInfo[] = 385 { 386 "date", 0, NULL, 387 "from", 0, NULL, 388 "to", 0, NULL, 389 "cc", 0, NULL, 390 "subject", 0, NULL, 391 "message-id", 0, &MsgId, 392 "message", H_EOH, NULL, 393 NULL, 0, NULL, 394 }; 395 /* 396 ** INITMACS -- initialize predefined macros. 397 ** 398 ** Parameters: 399 ** none. 400 ** 401 ** Returns: 402 ** none. 403 ** 404 ** Side Effects: 405 ** Macros array gets initialized. 406 */ 407 408 char *Macro[26]; 409 410 # define MACRO(x) Macro[x - 'A'] 411 412 initmacs() 413 { 414 MACRO('A') = ArpaHost; 415 MACRO('B') = BerkHost; 416 MACRO('U') = UucpHost; 417 } 418 419 # ifdef V6 420 /* 421 ** TTYPATH -- Get the path of the user's tty -- Version 6 version. 422 ** 423 ** Returns the pathname of the user's tty. Returns NULL if 424 ** the user is not logged in or if s/he has write permission 425 ** denied. 426 ** 427 ** Parameters: 428 ** none 429 ** 430 ** Returns: 431 ** pathname of the user's tty. 432 ** NULL if not logged in or write permission denied. 433 ** 434 ** Side Effects: 435 ** none. 436 ** 437 ** WARNING: 438 ** Return value is in a local buffer. 439 ** 440 ** Called By: 441 ** savemail 442 */ 443 444 # include <sys/types.h> 445 # include <sys/stat.h> 446 447 char * 448 ttypath() 449 { 450 struct stat stbuf; 451 register int i; 452 static char pathn[] = "/dev/ttyx"; 453 extern int errno; 454 455 /* compute the pathname of the controlling tty */ 456 if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 457 { 458 errno = 0; 459 return (NULL); 460 } 461 pathn[8] = i; 462 463 /* see if we have write permission */ 464 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 465 { 466 errno = 0; 467 return (NULL); 468 } 469 470 /* see if the user is logged in */ 471 if (getlogin() == NULL) 472 return (NULL); 473 474 /* looks good */ 475 return (pathn); 476 } 477 /* 478 ** FDOPEN -- Open a stdio file given an open file descriptor. 479 ** 480 ** This is included here because it is standard in v7, but we 481 ** need it in v6. 482 ** 483 ** Algorithm: 484 ** Open /dev/null to create a descriptor. 485 ** Close that descriptor. 486 ** Copy the existing fd into the descriptor. 487 ** 488 ** Parameters: 489 ** fd -- the open file descriptor. 490 ** type -- "r", "w", or whatever. 491 ** 492 ** Returns: 493 ** The file descriptor it creates. 494 ** 495 ** Side Effects: 496 ** none 497 ** 498 ** Called By: 499 ** deliver 500 ** 501 ** Notes: 502 ** The mode of fd must match "type". 503 */ 504 505 FILE * 506 fdopen(fd, type) 507 int fd; 508 char *type; 509 { 510 register FILE *f; 511 512 f = fopen("/dev/null", type); 513 close(fileno(f)); 514 fileno(f) = fd; 515 return (f); 516 } 517 /* 518 ** INDEX -- Return pointer to character in string 519 ** 520 ** For V7 compatibility. 521 ** 522 ** Parameters: 523 ** s -- a string to scan. 524 ** c -- a character to look for. 525 ** 526 ** Returns: 527 ** If c is in s, returns the address of the first 528 ** instance of c in s. 529 ** NULL if c is not in s. 530 ** 531 ** Side Effects: 532 ** none. 533 */ 534 535 index(s, c) 536 register char *s; 537 register char c; 538 { 539 while (*s != '\0') 540 { 541 if (*s++ == c) 542 return (--s); 543 } 544 return (NULL); 545 } 546 # endif V6 547 548 # ifndef V6 549 /* 550 ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 551 ** 552 ** Returns the pathname of the user's tty. Returns NULL if 553 ** the user is not logged in or if s/he has write permission 554 ** denied. 555 ** 556 ** Parameters: 557 ** none 558 ** 559 ** Returns: 560 ** pathname of the user's tty. 561 ** NULL if not logged in or write permission denied. 562 ** 563 ** Side Effects: 564 ** none. 565 ** 566 ** WARNING: 567 ** Return value is in a local buffer. 568 ** 569 ** Called By: 570 ** savemail 571 */ 572 573 # include <sys/types.h> 574 # include <sys/stat.h> 575 576 char * 577 ttypath() 578 { 579 struct stat stbuf; 580 register char *pathn; 581 extern int errno; 582 extern char *ttyname(); 583 584 /* compute the pathname of the controlling tty */ 585 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 586 { 587 errno = 0; 588 return (NULL); 589 } 590 591 /* see if we have write permission */ 592 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 593 { 594 errno = 0; 595 return (NULL); 596 } 597 598 /* see if the user is logged in */ 599 if (getlogin() == NULL) 600 return (NULL); 601 602 /* looks good */ 603 return (pathn); 604 } 605 # endif V6 606 /* 607 ** CHECKCOMPAT -- check for From and To person compatible. 608 ** 609 ** This routine can be supplied on a per-installation basis 610 ** to determine whether a person is allowed to send a message. 611 ** This allows restriction of certain types of internet 612 ** forwarding or registration of users. 613 ** 614 ** If the hosts are found to be incompatible, an error 615 ** message should be given using "usrerr" and FALSE should 616 ** be returned. 617 ** 618 ** Parameters: 619 ** to -- the person being sent to. 620 ** 621 ** Returns: 622 ** TRUE -- ok to send. 623 ** FALSE -- not ok. 624 ** 625 ** Side Effects: 626 ** none (unless you include the usrerr stuff) 627 */ 628 629 bool 630 checkcompat(to) 631 register ADDRESS *to; 632 { 633 return (TRUE); 634 } 635