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