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