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