Commit | Line | Data |
---|---|---|
d185cb11 | 1 | /* |
dc45ba8c | 2 | * Copyright (c) 1983 Eric P. Allman |
bee79b64 KB |
3 | * Copyright (c) 1988 Regents of the University of California. |
4 | * All rights reserved. | |
5 | * | |
af359dea C |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. All advertising materials mentioning features or use of this software | |
15 | * must display the following acknowledgement: | |
16 | * This product includes software developed by the University of | |
17 | * California, Berkeley and its contributors. | |
18 | * 4. Neither the name of the University nor the names of its contributors | |
19 | * may be used to endorse or promote products derived from this software | |
20 | * without specific prior written permission. | |
21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | |
bee79b64 | 33 | */ |
d185cb11 DF |
34 | |
35 | #ifndef lint | |
af359dea | 36 | static char sccsid[] = "@(#)conf.c 5.28 (Berkeley) 3/12/91"; |
bee79b64 | 37 | #endif /* not lint */ |
d185cb11 | 38 | |
d209c154 | 39 | # include <sys/ioctl.h> |
2e3062fe | 40 | # include <sys/param.h> |
611050b6 | 41 | # include <pwd.h> |
96faada8 | 42 | # include "sendmail.h" |
84048894 | 43 | # include "pathnames.h" |
916b3375 | 44 | |
b3cbe40f | 45 | /* |
96faada8 | 46 | ** CONF.C -- Sendmail Configuration Tables. |
b3cbe40f EA |
47 | ** |
48 | ** Defines the configuration of this installation. | |
49 | ** | |
cb590f52 | 50 | ** Compilation Flags: |
f7e74083 | 51 | ** VMUNIX -- running on a Berkeley UNIX system. |
b3cbe40f | 52 | ** |
cb590f52 | 53 | ** Configuration Variables: |
1a12c7d6 EA |
54 | ** HdrInfo -- a table describing well-known header fields. |
55 | ** Each entry has the field name and some flags, | |
df960d9b | 56 | ** which are described in sendmail.h. |
9c6d4c70 EA |
57 | ** |
58 | ** Notes: | |
59 | ** I have tried to put almost all the reasonable | |
60 | ** configuration information into the configuration | |
61 | ** file read at runtime. My intent is that anything | |
62 | ** here is a function of the version of UNIX you | |
63 | ** are running, or is really static -- for example | |
64 | ** the headers are a superset of widely used | |
65 | ** protocols. If you find yourself playing with | |
66 | ** this file too much, you may be making a mistake! | |
b3cbe40f EA |
67 | */ |
68 | ||
69 | ||
70 | ||
71 | ||
e804469b | 72 | /* |
1a12c7d6 | 73 | ** Header info table |
355a2a04 | 74 | ** Final (null) entry contains the flags used for any other field. |
df960d9b EA |
75 | ** |
76 | ** Not all of these are actually handled specially by sendmail | |
77 | ** at this time. They are included as placeholders, to let | |
78 | ** you know that "someday" I intend to have sendmail do | |
79 | ** something with them. | |
1a12c7d6 EA |
80 | */ |
81 | ||
82 | struct hdrinfo HdrInfo[] = | |
83 | { | |
6144e1d1 | 84 | /* originator fields, most to least significant */ |
a90807d8 EA |
85 | "resent-sender", H_FROM|H_RESENT, |
86 | "resent-from", H_FROM|H_RESENT, | |
4e969be0 | 87 | "resent-reply-to", H_FROM|H_RESENT, |
be2fcca9 EA |
88 | "sender", H_FROM, |
89 | "from", H_FROM, | |
4e969be0 | 90 | "reply-to", H_FROM, |
be2fcca9 EA |
91 | "full-name", H_ACHECK, |
92 | "return-receipt-to", H_FROM, | |
93 | "errors-to", H_FROM, | |
6144e1d1 | 94 | /* destination fields */ |
be2fcca9 | 95 | "to", H_RCPT, |
a90807d8 | 96 | "resent-to", H_RCPT|H_RESENT, |
be2fcca9 | 97 | "cc", H_RCPT, |
a90807d8 | 98 | "resent-cc", H_RCPT|H_RESENT, |
be2fcca9 | 99 | "bcc", H_RCPT|H_ACHECK, |
a90807d8 | 100 | "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, |
6144e1d1 | 101 | /* message identification and control */ |
a90807d8 EA |
102 | "message-id", 0, |
103 | "resent-message-id", H_RESENT, | |
be2fcca9 EA |
104 | "message", H_EOH, |
105 | "text", H_EOH, | |
a90807d8 EA |
106 | /* date fields */ |
107 | "date", 0, | |
108 | "resent-date", H_RESENT, | |
6144e1d1 | 109 | /* trace fields */ |
be2fcca9 EA |
110 | "received", H_TRACE|H_FORCE, |
111 | "via", H_TRACE|H_FORCE, | |
112 | "mail-from", H_TRACE|H_FORCE, | |
6144e1d1 | 113 | |
be2fcca9 | 114 | NULL, 0, |
1a12c7d6 | 115 | }; |
15b28570 EA |
116 | |
117 | ||
118 | /* | |
119 | ** ARPANET error message numbers. | |
120 | */ | |
121 | ||
314d2f52 EA |
122 | char Arpa_Info[] = "050"; /* arbitrary info */ |
123 | char Arpa_TSyserr[] = "451"; /* some (transient) system error */ | |
124 | char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ | |
125 | char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ | |
4e1f4d4b EA |
126 | |
127 | ||
128 | ||
4e1f4d4b EA |
129 | /* |
130 | ** Location of system files/databases/etc. | |
131 | */ | |
132 | ||
84048894 KB |
133 | char *ConfFile = _PATH_SENDMAILCF; /* runtime configuration */ |
134 | char *FreezeFile = _PATH_SENDMAILFC; /* frozen version of above */ | |
acae5a9d EA |
135 | |
136 | ||
1744384a EA |
137 | |
138 | /* | |
2e3062fe | 139 | ** Miscellaneous stuff. |
1744384a EA |
140 | */ |
141 | ||
2e3062fe | 142 | int DtableSize = 50; /* max open files; reset in 4.2bsd */ |
329f2298 | 143 | extern int la; /* load average */ |
2e3062fe EA |
144 | \f/* |
145 | ** SETDEFAULTS -- set default values | |
146 | ** | |
147 | ** Because of the way freezing is done, these must be initialized | |
148 | ** using direct code. | |
149 | ** | |
150 | ** Parameters: | |
151 | ** none. | |
152 | ** | |
153 | ** Returns: | |
154 | ** none. | |
155 | ** | |
156 | ** Side Effects: | |
157 | ** Initializes a bunch of global variables to their | |
158 | ** default values. | |
159 | */ | |
160 | ||
161 | setdefaults() | |
162 | { | |
163 | QueueLA = 8; | |
164 | QueueFactor = 10000; | |
165 | RefuseLA = 12; | |
166 | SpaceSub = ' '; | |
a0225d08 EA |
167 | WkRecipFact = 1000; |
168 | WkClassFact = 1800; | |
9da8ffc8 | 169 | WkTimeFact = 9000; |
a0225d08 EA |
170 | FileMode = 0644; |
171 | DefUid = 1; | |
172 | DefGid = 1; | |
8dcff118 | 173 | CheckpointInterval = 10; |
3fbc69d6 | 174 | setdefuser(); |
2e3062fe | 175 | } |
a0554f81 | 176 | |
3fbc69d6 KB |
177 | |
178 | /* | |
179 | ** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups()) | |
180 | */ | |
181 | ||
182 | setdefuser() | |
183 | { | |
184 | struct passwd *defpwent; | |
185 | ||
186 | if (DefUser != NULL) | |
187 | free(DefUser); | |
188 | if ((defpwent = getpwuid(DefUid)) != NULL) | |
189 | DefUser = newstr(defpwent->pw_name); | |
190 | else | |
191 | DefUser = newstr("nobody"); | |
192 | } | |
193 | ||
194 | ||
a0554f81 EA |
195 | /* |
196 | ** GETRUID -- get real user id (V7) | |
197 | */ | |
198 | ||
199 | getruid() | |
200 | { | |
75f95954 | 201 | if (OpMode == MD_DAEMON) |
f6a0cc15 EA |
202 | return (RealUid); |
203 | else | |
204 | return (getuid()); | |
a0554f81 EA |
205 | } |
206 | ||
207 | ||
208 | /* | |
209 | ** GETRGID -- get real group id (V7). | |
210 | */ | |
211 | ||
212 | getrgid() | |
213 | { | |
75f95954 | 214 | if (OpMode == MD_DAEMON) |
f6a0cc15 EA |
215 | return (RealGid); |
216 | else | |
217 | return (getgid()); | |
a0554f81 EA |
218 | } |
219 | ||
46e5d822 | 220 | /* |
7338e3d4 EA |
221 | ** USERNAME -- return the user id of the logged in user. |
222 | ** | |
223 | ** Parameters: | |
224 | ** none. | |
225 | ** | |
226 | ** Returns: | |
227 | ** The login name of the logged in user. | |
228 | ** | |
229 | ** Side Effects: | |
230 | ** none. | |
231 | ** | |
232 | ** Notes: | |
233 | ** The return value is statically allocated. | |
234 | */ | |
235 | ||
236 | char * | |
237 | username() | |
238 | { | |
560a80d9 | 239 | static char *myname = NULL; |
7338e3d4 | 240 | extern char *getlogin(); |
19c3b81a | 241 | register struct passwd *pw; |
7338e3d4 | 242 | |
560a80d9 EA |
243 | /* cache the result */ |
244 | if (myname == NULL) | |
245 | { | |
246 | myname = getlogin(); | |
247 | if (myname == NULL || myname[0] == '\0') | |
248 | { | |
560a80d9 EA |
249 | |
250 | pw = getpwuid(getruid()); | |
251 | if (pw != NULL) | |
2a669966 | 252 | myname = newstr(pw->pw_name); |
560a80d9 | 253 | } |
19c3b81a MAN |
254 | else |
255 | { | |
1a626eeb | 256 | |
2a669966 KB |
257 | myname = newstr(myname); |
258 | if ((pw = getpwnam(myname)) == NULL || | |
259 | getuid() != pw->pw_uid) | |
19c3b81a | 260 | { |
1a626eeb | 261 | pw = getpwuid(getuid()); |
84f20e6d | 262 | if (pw != NULL) |
2a669966 | 263 | myname = newstr(pw->pw_name); |
1a626eeb MAN |
264 | } |
265 | } | |
560a80d9 EA |
266 | if (myname == NULL || myname[0] == '\0') |
267 | { | |
268 | syserr("Who are you?"); | |
269 | myname = "postmaster"; | |
270 | } | |
271 | } | |
272 | ||
273 | return (myname); | |
7338e3d4 EA |
274 | } |
275 | \f/* | |
14e42c2b | 276 | ** TTYPATH -- Get the path of the user's tty |
b3cbe40f EA |
277 | ** |
278 | ** Returns the pathname of the user's tty. Returns NULL if | |
279 | ** the user is not logged in or if s/he has write permission | |
280 | ** denied. | |
281 | ** | |
282 | ** Parameters: | |
283 | ** none | |
284 | ** | |
285 | ** Returns: | |
286 | ** pathname of the user's tty. | |
287 | ** NULL if not logged in or write permission denied. | |
288 | ** | |
289 | ** Side Effects: | |
290 | ** none. | |
291 | ** | |
292 | ** WARNING: | |
293 | ** Return value is in a local buffer. | |
294 | ** | |
b3cbe40f EA |
295 | ** Called By: |
296 | ** savemail | |
b3cbe40f EA |
297 | */ |
298 | ||
b3cbe40f EA |
299 | # include <sys/stat.h> |
300 | ||
301 | char * | |
302 | ttypath() | |
303 | { | |
304 | struct stat stbuf; | |
305 | register char *pathn; | |
b3cbe40f | 306 | extern char *ttyname(); |
29871fef | 307 | extern char *getlogin(); |
b3cbe40f EA |
308 | |
309 | /* compute the pathname of the controlling tty */ | |
7338e3d4 EA |
310 | if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && |
311 | (pathn = ttyname(0)) == NULL) | |
b3cbe40f EA |
312 | { |
313 | errno = 0; | |
314 | return (NULL); | |
315 | } | |
316 | ||
317 | /* see if we have write permission */ | |
a530c75f | 318 | if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) |
b3cbe40f EA |
319 | { |
320 | errno = 0; | |
321 | return (NULL); | |
322 | } | |
323 | ||
324 | /* see if the user is logged in */ | |
325 | if (getlogin() == NULL) | |
326 | return (NULL); | |
327 | ||
328 | /* looks good */ | |
329 | return (pathn); | |
330 | } | |
a530c75f EA |
331 | \f/* |
332 | ** CHECKCOMPAT -- check for From and To person compatible. | |
333 | ** | |
334 | ** This routine can be supplied on a per-installation basis | |
335 | ** to determine whether a person is allowed to send a message. | |
336 | ** This allows restriction of certain types of internet | |
337 | ** forwarding or registration of users. | |
338 | ** | |
339 | ** If the hosts are found to be incompatible, an error | |
340 | ** message should be given using "usrerr" and FALSE should | |
341 | ** be returned. | |
342 | ** | |
46b14b48 EA |
343 | ** 'NoReturn' can be set to suppress the return-to-sender |
344 | ** function; this should be done on huge messages. | |
345 | ** | |
a530c75f EA |
346 | ** Parameters: |
347 | ** to -- the person being sent to. | |
348 | ** | |
349 | ** Returns: | |
350 | ** TRUE -- ok to send. | |
351 | ** FALSE -- not ok. | |
352 | ** | |
353 | ** Side Effects: | |
354 | ** none (unless you include the usrerr stuff) | |
355 | */ | |
356 | ||
357 | bool | |
358 | checkcompat(to) | |
359 | register ADDRESS *to; | |
360 | { | |
22e6d6b8 EA |
361 | # ifdef lint |
362 | if (to == NULL) | |
363 | to++; | |
364 | # endif lint | |
97ad25b6 EA |
365 | # ifdef EXAMPLE_CODE |
366 | /* this code is intended as an example only */ | |
b14547d5 EA |
367 | register STAB *s; |
368 | ||
b14547d5 | 369 | s = stab("arpa", ST_MAILER, ST_FIND); |
7338e3d4 EA |
370 | if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && |
371 | to->q_mailer == s->s_mailer) | |
b14547d5 EA |
372 | { |
373 | usrerr("No ARPA mail through this machine: see your system administration"); | |
97ad25b6 | 374 | /* NoReturn = TRUE; to supress return copy */ |
b14547d5 EA |
375 | return (FALSE); |
376 | } | |
97ad25b6 | 377 | # endif EXAMPLE_CODE |
a530c75f EA |
378 | return (TRUE); |
379 | } | |
7338e3d4 EA |
380 | \f/* |
381 | ** HOLDSIGS -- arrange to hold all signals | |
382 | ** | |
383 | ** Parameters: | |
384 | ** none. | |
385 | ** | |
386 | ** Returns: | |
387 | ** none. | |
388 | ** | |
389 | ** Side Effects: | |
390 | ** Arranges that signals are held. | |
391 | */ | |
392 | ||
393 | holdsigs() | |
394 | { | |
395 | } | |
396 | \f/* | |
397 | ** RLSESIGS -- arrange to release all signals | |
398 | ** | |
399 | ** This undoes the effect of holdsigs. | |
400 | ** | |
401 | ** Parameters: | |
402 | ** none. | |
403 | ** | |
404 | ** Returns: | |
405 | ** none. | |
406 | ** | |
407 | ** Side Effects: | |
408 | ** Arranges that signals are released. | |
409 | */ | |
410 | ||
411 | rlsesigs() | |
412 | { | |
413 | } | |
f7e74083 EA |
414 | \f/* |
415 | ** GETLA -- get the current load average | |
416 | ** | |
d209c154 EA |
417 | ** This code stolen from la.c. |
418 | ** | |
f7e74083 EA |
419 | ** Parameters: |
420 | ** none. | |
421 | ** | |
422 | ** Returns: | |
423 | ** The current load average as an integer. | |
424 | ** | |
425 | ** Side Effects: | |
426 | ** none. | |
427 | */ | |
428 | ||
b02d33b6 KM |
429 | #ifndef sun |
430 | ||
431 | getla() | |
432 | { | |
433 | double avenrun[3]; | |
434 | ||
435 | if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) | |
436 | return (0); | |
437 | return ((int) (avenrun[0] + 0.5)); | |
438 | } | |
439 | ||
440 | #else /* sun */ | |
f7e74083 EA |
441 | |
442 | #include <nlist.h> | |
443 | ||
444 | struct nlist Nl[] = | |
445 | { | |
446 | { "_avenrun" }, | |
447 | #define X_AVENRUN 0 | |
448 | { 0 }, | |
449 | }; | |
450 | ||
27355bf0 RA |
451 | |
452 | extern int la; | |
453 | ||
f7e74083 EA |
454 | getla() |
455 | { | |
456 | static int kmem = -1; | |
2e3062fe | 457 | long avenrun[3]; |
901911f8 | 458 | extern off_t lseek(); |
f7e74083 EA |
459 | |
460 | if (kmem < 0) | |
461 | { | |
fa483327 | 462 | kmem = open("/dev/kmem", 0, 0); |
f7e74083 EA |
463 | if (kmem < 0) |
464 | return (-1); | |
17a67c62 | 465 | (void) ioctl(kmem, (int) FIOCLEX, (char *) 0); |
f7e74083 EA |
466 | nlist("/vmunix", Nl); |
467 | if (Nl[0].n_type == 0) | |
468 | return (-1); | |
469 | } | |
fa483327 | 470 | if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || |
17a67c62 | 471 | read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) |
fa42ff8e EA |
472 | { |
473 | /* thank you Ian */ | |
474 | return (-1); | |
475 | } | |
2e3062fe | 476 | return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); |
f7e74083 EA |
477 | } |
478 | ||
b02d33b6 | 479 | #endif /* sun */ |
2e3062fe EA |
480 | \f/* |
481 | ** SHOULDQUEUE -- should this message be queued or sent? | |
482 | ** | |
483 | ** Compares the message cost to the load average to decide. | |
484 | ** | |
485 | ** Parameters: | |
486 | ** pri -- the priority of the message in question. | |
487 | ** | |
488 | ** Returns: | |
489 | ** TRUE -- if this message should be queued up for the | |
490 | ** time being. | |
491 | ** FALSE -- if the load is low enough to send this message. | |
492 | ** | |
493 | ** Side Effects: | |
494 | ** none. | |
495 | */ | |
496 | ||
497 | bool | |
498 | shouldqueue(pri) | |
499 | long pri; | |
500 | { | |
2e3062fe EA |
501 | if (la < QueueLA) |
502 | return (FALSE); | |
503 | return (pri > (QueueFactor / (la - QueueLA + 1))); | |
504 | } | |
505 | \f/* | |
506 | ** SETPROCTITLE -- set process title for ps | |
507 | ** | |
508 | ** Parameters: | |
509 | ** fmt -- a printf style format string. | |
510 | ** a, b, c -- possible parameters to fmt. | |
511 | ** | |
512 | ** Returns: | |
513 | ** none. | |
514 | ** | |
515 | ** Side Effects: | |
516 | ** Clobbers argv of our main procedure so ps(1) will | |
517 | ** display the title. | |
518 | */ | |
519 | ||
520 | /*VARARGS1*/ | |
521 | setproctitle(fmt, a, b, c) | |
522 | char *fmt; | |
523 | { | |
524 | # ifdef SETPROCTITLE | |
525 | register char *p; | |
f5ca8c6e | 526 | register int i; |
2e3062fe EA |
527 | extern char **Argv; |
528 | extern char *LastArgv; | |
f5ca8c6e | 529 | char buf[MAXLINE]; |
2e3062fe | 530 | |
f5ca8c6e | 531 | (void) sprintf(buf, fmt, a, b, c); |
2e3062fe EA |
532 | |
533 | /* make ps print "(sendmail)" */ | |
f5ca8c6e | 534 | p = Argv[0]; |
2e3062fe EA |
535 | *p++ = '-'; |
536 | ||
f5ca8c6e EA |
537 | i = strlen(buf); |
538 | if (i > LastArgv - p - 2) | |
539 | { | |
540 | i = LastArgv - p - 2; | |
541 | buf[i] = '\0'; | |
542 | } | |
543 | (void) strcpy(p, buf); | |
544 | p += i; | |
2e3062fe EA |
545 | while (p < LastArgv) |
546 | *p++ = ' '; | |
547 | # endif SETPROCTITLE | |
548 | } | |
8fd13041 EA |
549 | \f/* |
550 | ** REAPCHILD -- pick up the body of my child, lest it become a zombie | |
551 | ** | |
552 | ** Parameters: | |
553 | ** none. | |
554 | ** | |
555 | ** Returns: | |
556 | ** none. | |
557 | ** | |
558 | ** Side Effects: | |
559 | ** Picks up extant zombies. | |
560 | */ | |
561 | ||
562 | # ifdef VMUNIX | |
563 | # include <sys/wait.h> | |
564 | # endif VMUNIX | |
565 | ||
0df908a9 | 566 | void |
8fd13041 EA |
567 | reapchild() |
568 | { | |
569 | # ifdef WNOHANG | |
570 | union wait status; | |
571 | ||
0df908a9 | 572 | while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0) |
8fd13041 EA |
573 | continue; |
574 | # else WNOHANG | |
575 | auto int status; | |
576 | ||
0df908a9 | 577 | while (wait((int *)&status) > 0) |
8fd13041 EA |
578 | continue; |
579 | # endif WNOHANG | |
580 | } |