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.4 08/28/83); 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 = 8; /* load avg > QueueLA -> just queue */ 111 int RefuseLA = 12; /* 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 extern char *getlogin(); 317 318 return (getlogin()); 319 } 320 /* 321 ** TTYPATH -- Get the path of the user's tty 322 ** 323 ** Returns the pathname of the user's tty. Returns NULL if 324 ** the user is not logged in or if s/he has write permission 325 ** denied. 326 ** 327 ** Parameters: 328 ** none 329 ** 330 ** Returns: 331 ** pathname of the user's tty. 332 ** NULL if not logged in or write permission denied. 333 ** 334 ** Side Effects: 335 ** none. 336 ** 337 ** WARNING: 338 ** Return value is in a local buffer. 339 ** 340 ** Called By: 341 ** savemail 342 */ 343 344 # include <sys/stat.h> 345 346 char * 347 ttypath() 348 { 349 struct stat stbuf; 350 register char *pathn; 351 extern char *ttyname(); 352 extern char *getlogin(); 353 354 /* compute the pathname of the controlling tty */ 355 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 356 (pathn = ttyname(0)) == NULL) 357 { 358 errno = 0; 359 return (NULL); 360 } 361 362 /* see if we have write permission */ 363 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 364 { 365 errno = 0; 366 return (NULL); 367 } 368 369 /* see if the user is logged in */ 370 if (getlogin() == NULL) 371 return (NULL); 372 373 /* looks good */ 374 return (pathn); 375 } 376 /* 377 ** CHECKCOMPAT -- check for From and To person compatible. 378 ** 379 ** This routine can be supplied on a per-installation basis 380 ** to determine whether a person is allowed to send a message. 381 ** This allows restriction of certain types of internet 382 ** forwarding or registration of users. 383 ** 384 ** If the hosts are found to be incompatible, an error 385 ** message should be given using "usrerr" and FALSE should 386 ** be returned. 387 ** 388 ** 'NoReturn' can be set to suppress the return-to-sender 389 ** function; this should be done on huge messages. 390 ** 391 ** Parameters: 392 ** to -- the person being sent to. 393 ** 394 ** Returns: 395 ** TRUE -- ok to send. 396 ** FALSE -- not ok. 397 ** 398 ** Side Effects: 399 ** none (unless you include the usrerr stuff) 400 */ 401 402 bool 403 checkcompat(to) 404 register ADDRESS *to; 405 { 406 # ifdef lint 407 if (to == NULL) 408 to++; 409 # endif lint 410 # ifdef EXAMPLE_CODE 411 /* this code is intended as an example only */ 412 register STAB *s; 413 414 s = stab("arpa", ST_MAILER, ST_FIND); 415 if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 416 to->q_mailer == s->s_mailer) 417 { 418 usrerr("No ARPA mail through this machine: see your system administration"); 419 /* NoReturn = TRUE; to supress return copy */ 420 return (FALSE); 421 } 422 # endif EXAMPLE_CODE 423 return (TRUE); 424 } 425 /* 426 ** HOLDSIGS -- arrange to hold all signals 427 ** 428 ** Parameters: 429 ** none. 430 ** 431 ** Returns: 432 ** none. 433 ** 434 ** Side Effects: 435 ** Arranges that signals are held. 436 */ 437 438 holdsigs() 439 { 440 } 441 /* 442 ** RLSESIGS -- arrange to release all signals 443 ** 444 ** This undoes the effect of holdsigs. 445 ** 446 ** Parameters: 447 ** none. 448 ** 449 ** Returns: 450 ** none. 451 ** 452 ** Side Effects: 453 ** Arranges that signals are released. 454 */ 455 456 rlsesigs() 457 { 458 } 459 /* 460 ** GETLA -- get the current load average 461 ** 462 ** This code stolen from la.c. 463 ** 464 ** Parameters: 465 ** none. 466 ** 467 ** Returns: 468 ** The current load average as an integer. 469 ** 470 ** Side Effects: 471 ** none. 472 */ 473 474 #ifdef VMUNIX 475 476 #include <nlist.h> 477 478 struct nlist Nl[] = 479 { 480 { "_avenrun" }, 481 #define X_AVENRUN 0 482 { 0 }, 483 }; 484 485 getla() 486 { 487 static int kmem = -1; 488 double avenrun[3]; 489 490 if (kmem < 0) 491 { 492 kmem = open("/dev/kmem", 0); 493 if (kmem < 0) 494 return (-1); 495 (void) ioctl(kmem, FIOCLEX, 0); 496 nlist("/vmunix", Nl); 497 if (Nl[0].n_type == 0) 498 return (-1); 499 } 500 (void) lseek(kmem, (long) Nl[X_AVENRUN].n_value, 0); 501 (void) read(kmem, avenrun, sizeof(avenrun)); 502 return ((int) (avenrun[0] + 0.5)); 503 } 504 505 #else VMUNIX 506 507 getla() 508 { 509 return (0); 510 } 511 512 #endif VMUNIX 513