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