1 /* 2 ** Sendmail 3 ** Copyright (c) 1983 Eric P. Allman 4 ** Berkeley, California 5 ** 6 ** Copyright (c) 1983 Regents of the University of California. 7 ** All rights reserved. The Berkeley software License Agreement 8 ** specifies the terms and conditions for redistribution. 9 */ 10 11 #ifndef lint 12 static char SccsId[] = "@(#)conf.c 5.3 (Berkeley) 06/08/85"; 13 #endif not lint 14 15 # include <pwd.h> 16 # include <sys/ioctl.h> 17 # include "sendmail.h" 18 19 /* 20 ** CONF.C -- Sendmail Configuration Tables. 21 ** 22 ** Defines the configuration of this installation. 23 ** 24 ** Compilation Flags: 25 ** V6 -- running on a version 6 system. This determines 26 ** whether to define certain routines between 27 ** the two systems. If you are running a funny 28 ** system, e.g., V6 with long tty names, this 29 ** should be checked carefully. 30 ** VMUNIX -- running on a Berkeley UNIX system. 31 ** 32 ** Configuration Variables: 33 ** HdrInfo -- a table describing well-known header fields. 34 ** Each entry has the field name and some flags, 35 ** which are described in sendmail.h. 36 ** 37 ** Notes: 38 ** I have tried to put almost all the reasonable 39 ** configuration information into the configuration 40 ** file read at runtime. My intent is that anything 41 ** here is a function of the version of UNIX you 42 ** are running, or is really static -- for example 43 ** the headers are a superset of widely used 44 ** protocols. If you find yourself playing with 45 ** this file too much, you may be making a mistake! 46 */ 47 48 49 50 51 /* 52 ** Header info table 53 ** Final (null) entry contains the flags used for any other field. 54 ** 55 ** Not all of these are actually handled specially by sendmail 56 ** at this time. They are included as placeholders, to let 57 ** you know that "someday" I intend to have sendmail do 58 ** something with them. 59 */ 60 61 struct hdrinfo HdrInfo[] = 62 { 63 /* originator fields, most to least significant */ 64 "resent-sender", H_FROM|H_RESENT, 65 "resent-from", H_FROM|H_RESENT, 66 "sender", H_FROM, 67 "from", H_FROM, 68 "full-name", H_ACHECK, 69 "return-receipt-to", H_FROM, 70 "errors-to", H_FROM, 71 /* destination fields */ 72 "to", H_RCPT, 73 "resent-to", H_RCPT|H_RESENT, 74 "cc", H_RCPT, 75 "resent-cc", H_RCPT|H_RESENT, 76 "bcc", H_RCPT|H_ACHECK, 77 "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 78 /* message identification and control */ 79 "message-id", 0, 80 "resent-message-id", H_RESENT, 81 "message", H_EOH, 82 "text", H_EOH, 83 /* date fields */ 84 "date", 0, 85 "resent-date", H_RESENT, 86 /* trace fields */ 87 "received", H_TRACE|H_FORCE, 88 "via", H_TRACE|H_FORCE, 89 "mail-from", H_TRACE|H_FORCE, 90 91 NULL, 0, 92 }; 93 94 95 /* 96 ** ARPANET error message numbers. 97 */ 98 99 char Arpa_Info[] = "050"; /* arbitrary info */ 100 char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 101 char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 102 char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 103 104 105 106 /* 107 ** Location of system files/databases/etc. 108 */ 109 110 char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */ 111 char *FreezeFile = "/usr/lib/sendmail.fc"; /* frozen version of above */ 112 113 114 115 /* 116 ** Some other configuration.... 117 */ 118 119 char SpaceSub; /* character to replace <lwsp> in addrs */ 120 int QueueLA; /* load avg > QueueLA -> just queue */ 121 int RefuseLA; /* load avg > RefuseLA -> refuse connections */ 122 123 # ifdef V6 124 /* 125 ** TTYNAME -- return name of terminal. 126 ** 127 ** Parameters: 128 ** fd -- file descriptor to check. 129 ** 130 ** Returns: 131 ** pointer to full path of tty. 132 ** NULL if no tty. 133 ** 134 ** Side Effects: 135 ** none. 136 */ 137 138 char * 139 ttyname(fd) 140 int fd; 141 { 142 register char tn; 143 static char pathn[] = "/dev/ttyx"; 144 145 /* compute the pathname of the controlling tty */ 146 if ((tn = ttyn(fd)) == NULL) 147 { 148 errno = 0; 149 return (NULL); 150 } 151 pathn[8] = tn; 152 return (pathn); 153 } 154 /* 155 ** FDOPEN -- Open a stdio file given an open file descriptor. 156 ** 157 ** This is included here because it is standard in v7, but we 158 ** need it in v6. 159 ** 160 ** Algorithm: 161 ** Open /dev/null to create a descriptor. 162 ** Close that descriptor. 163 ** Copy the existing fd into the descriptor. 164 ** 165 ** Parameters: 166 ** fd -- the open file descriptor. 167 ** type -- "r", "w", or whatever. 168 ** 169 ** Returns: 170 ** The file descriptor it creates. 171 ** 172 ** Side Effects: 173 ** none 174 ** 175 ** Called By: 176 ** deliver 177 ** 178 ** Notes: 179 ** The mode of fd must match "type". 180 */ 181 182 FILE * 183 fdopen(fd, type) 184 int fd; 185 char *type; 186 { 187 register FILE *f; 188 189 f = fopen("/dev/null", type); 190 (void) close(fileno(f)); 191 fileno(f) = fd; 192 return (f); 193 } 194 /* 195 ** INDEX -- Return pointer to character in string 196 ** 197 ** For V7 compatibility. 198 ** 199 ** Parameters: 200 ** s -- a string to scan. 201 ** c -- a character to look for. 202 ** 203 ** Returns: 204 ** If c is in s, returns the address of the first 205 ** instance of c in s. 206 ** NULL if c is not in s. 207 ** 208 ** Side Effects: 209 ** none. 210 */ 211 212 char * 213 index(s, c) 214 register char *s; 215 register char c; 216 { 217 while (*s != '\0') 218 { 219 if (*s++ == c) 220 return (--s); 221 } 222 return (NULL); 223 } 224 /* 225 ** UMASK -- fake the umask system call. 226 ** 227 ** Since V6 always acts like the umask is zero, we will just 228 ** assume the same thing. 229 */ 230 231 /*ARGSUSED*/ 232 umask(nmask) 233 { 234 return (0); 235 } 236 237 238 /* 239 ** GETRUID -- get real user id. 240 */ 241 242 getruid() 243 { 244 return (getuid() & 0377); 245 } 246 247 248 /* 249 ** GETRGID -- get real group id. 250 */ 251 252 getrgid() 253 { 254 return (getgid() & 0377); 255 } 256 257 258 /* 259 ** GETEUID -- get effective user id. 260 */ 261 262 geteuid() 263 { 264 return ((getuid() >> 8) & 0377); 265 } 266 267 268 /* 269 ** GETEGID -- get effective group id. 270 */ 271 272 getegid() 273 { 274 return ((getgid() >> 8) & 0377); 275 } 276 277 # endif V6 278 279 # ifndef V6 280 281 /* 282 ** GETRUID -- get real user id (V7) 283 */ 284 285 getruid() 286 { 287 if (OpMode == MD_DAEMON) 288 return (RealUid); 289 else 290 return (getuid()); 291 } 292 293 294 /* 295 ** GETRGID -- get real group id (V7). 296 */ 297 298 getrgid() 299 { 300 if (OpMode == MD_DAEMON) 301 return (RealGid); 302 else 303 return (getgid()); 304 } 305 306 # endif V6 307 /* 308 ** USERNAME -- return the user id of the logged in user. 309 ** 310 ** Parameters: 311 ** none. 312 ** 313 ** Returns: 314 ** The login name of the logged in user. 315 ** 316 ** Side Effects: 317 ** none. 318 ** 319 ** Notes: 320 ** The return value is statically allocated. 321 */ 322 323 char * 324 username() 325 { 326 static char *myname = NULL; 327 extern char *getlogin(); 328 register struct passwd *pw; 329 extern struct passwd *getpwuid(); 330 331 /* cache the result */ 332 if (myname == NULL) 333 { 334 myname = getlogin(); 335 if (myname == NULL || myname[0] == '\0') 336 { 337 338 pw = getpwuid(getruid()); 339 if (pw != NULL) 340 myname = pw->pw_name; 341 } 342 else 343 { 344 345 pw = getpwnam(myname); 346 if(getuid() != pw->pw_uid) 347 { 348 pw = getpwuid(getuid()); 349 myname = pw->pw_name; 350 } 351 } 352 if (myname == NULL || myname[0] == '\0') 353 { 354 syserr("Who are you?"); 355 myname = "postmaster"; 356 } 357 } 358 359 return (myname); 360 } 361 /* 362 ** TTYPATH -- Get the path of the user's tty 363 ** 364 ** Returns the pathname of the user's tty. Returns NULL if 365 ** the user is not logged in or if s/he has write permission 366 ** denied. 367 ** 368 ** Parameters: 369 ** none 370 ** 371 ** Returns: 372 ** pathname of the user's tty. 373 ** NULL if not logged in or write permission denied. 374 ** 375 ** Side Effects: 376 ** none. 377 ** 378 ** WARNING: 379 ** Return value is in a local buffer. 380 ** 381 ** Called By: 382 ** savemail 383 */ 384 385 # include <sys/stat.h> 386 387 char * 388 ttypath() 389 { 390 struct stat stbuf; 391 register char *pathn; 392 extern char *ttyname(); 393 extern char *getlogin(); 394 395 /* compute the pathname of the controlling tty */ 396 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 397 (pathn = ttyname(0)) == NULL) 398 { 399 errno = 0; 400 return (NULL); 401 } 402 403 /* see if we have write permission */ 404 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 405 { 406 errno = 0; 407 return (NULL); 408 } 409 410 /* see if the user is logged in */ 411 if (getlogin() == NULL) 412 return (NULL); 413 414 /* looks good */ 415 return (pathn); 416 } 417 /* 418 ** CHECKCOMPAT -- check for From and To person compatible. 419 ** 420 ** This routine can be supplied on a per-installation basis 421 ** to determine whether a person is allowed to send a message. 422 ** This allows restriction of certain types of internet 423 ** forwarding or registration of users. 424 ** 425 ** If the hosts are found to be incompatible, an error 426 ** message should be given using "usrerr" and FALSE should 427 ** be returned. 428 ** 429 ** 'NoReturn' can be set to suppress the return-to-sender 430 ** function; this should be done on huge messages. 431 ** 432 ** Parameters: 433 ** to -- the person being sent to. 434 ** 435 ** Returns: 436 ** TRUE -- ok to send. 437 ** FALSE -- not ok. 438 ** 439 ** Side Effects: 440 ** none (unless you include the usrerr stuff) 441 */ 442 443 bool 444 checkcompat(to) 445 register ADDRESS *to; 446 { 447 # ifdef lint 448 if (to == NULL) 449 to++; 450 # endif lint 451 # ifdef EXAMPLE_CODE 452 /* this code is intended as an example only */ 453 register STAB *s; 454 455 s = stab("arpa", ST_MAILER, ST_FIND); 456 if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 457 to->q_mailer == s->s_mailer) 458 { 459 usrerr("No ARPA mail through this machine: see your system administration"); 460 /* NoReturn = TRUE; to supress return copy */ 461 return (FALSE); 462 } 463 # endif EXAMPLE_CODE 464 return (TRUE); 465 } 466 /* 467 ** HOLDSIGS -- arrange to hold all signals 468 ** 469 ** Parameters: 470 ** none. 471 ** 472 ** Returns: 473 ** none. 474 ** 475 ** Side Effects: 476 ** Arranges that signals are held. 477 */ 478 479 holdsigs() 480 { 481 } 482 /* 483 ** RLSESIGS -- arrange to release all signals 484 ** 485 ** This undoes the effect of holdsigs. 486 ** 487 ** Parameters: 488 ** none. 489 ** 490 ** Returns: 491 ** none. 492 ** 493 ** Side Effects: 494 ** Arranges that signals are released. 495 */ 496 497 rlsesigs() 498 { 499 } 500 /* 501 ** GETLA -- get the current load average 502 ** 503 ** This code stolen from la.c. 504 ** 505 ** Parameters: 506 ** none. 507 ** 508 ** Returns: 509 ** The current load average as an integer. 510 ** 511 ** Side Effects: 512 ** none. 513 */ 514 515 #ifdef VMUNIX 516 517 #include <nlist.h> 518 519 struct nlist Nl[] = 520 { 521 { "_avenrun" }, 522 #define X_AVENRUN 0 523 { 0 }, 524 }; 525 526 getla() 527 { 528 static int kmem = -1; 529 double avenrun[3]; 530 531 if (kmem < 0) 532 { 533 kmem = open("/dev/kmem", 0); 534 if (kmem < 0) 535 return (-1); 536 (void) ioctl(kmem, (int) FIOCLEX, (char *) 0); 537 nlist("/vmunix", Nl); 538 if (Nl[0].n_type == 0) 539 return (-1); 540 } 541 if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) < 0 || 542 read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 543 { 544 /* thank you Ian */ 545 return (-1); 546 } 547 return ((int) (avenrun[0] + 0.5)); 548 } 549 550 #else VMUNIX 551 552 getla() 553 { 554 return (0); 555 } 556 557 #endif VMUNIX 558