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