xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 2420)
1 # include <stdio.h>
2 # include <pwd.h>
3 # include "dlvrmail.h"
4 
5 /*
6 **  CONF.C -- Delivermail Configuration Tables.
7 **
8 **	Defines the configuration of this installation.
9 **
10 **	Compilation Flags:
11 **		HASARPA -- set if this machine has a connection to
12 **			the Arpanet.
13 **		HASUUCP -- set if this machine has a connection to
14 **			the UUCP network.
15 **		NETV6MAIL -- set if you want to use "v6mail" that
16 **			comes with the Berkeley network.  Normally
17 **			/bin/mail will work fine, but around Berkeley
18 **			we use v6mail because it is a "fixed target".
19 **			Also, only v6mail has the "/dev/mail" stuff
20 **			in it (for biff(1)).
21 **		V6 -- running on a version 6 system.  This determines
22 **			whether to define certain routines between
23 **			the two systems.  If you are running a funny
24 **			system, e.g., V6 with long tty names, this
25 **			should be checked carefully.
26 **		DUMBMAIL -- set if your /bin/mail doesn't have the
27 **			-d flag.
28 **
29 **	Configuration Variables:
30 **		ArpaHost -- the arpanet name of the host through
31 **			which arpanet mail will be sent.
32 **		MyLocName -- the name of the host on a local network.
33 **			This is used to disambiguate the contents of
34 **			ArpaHost among many hosts who may be sharing
35 **			a gateway.
36 **		DaemonName -- the name of this agent for use in
37 **			error messages, typically "~MAILER~DAEMON~"
38 **			at this host on the local net.
39 **		ArpaLocal -- a list of local names for this host on
40 **			the arpanet.  Only functional if HASARPA set.
41 **		UucpLocal -- ditto for the Arpanet.
42 **		BerkLocal -- ditto for the Berknet.
43 **		Mailer -- a table of mailers known to the system.
44 **			The fields are:
45 **			- the pathname of the mailer.
46 **			- a list of flags describing the properties
47 **			  of this mailer:
48 **			   M_FOPT -- if set, the mailer has a picky "-f"
49 **				option.  In this mode, the mailer will
50 **				only accept the "-f" option if the
51 **				sender is actually "root", "network",
52 **				and possibly (but not necessarily) if
53 **				the -f argument matches the real sender.
54 **				The effect is that if the "-f" option
55 **				is given to delivermail then it will be
56 **				passed through (as arguments 1 & 2) to
57 **				the mailer.
58 **			   M_ROPT -- identical to M_FOPT, except uses
59 **				-r instead.
60 **			   M_QUIET -- if set, don't print a message if
61 **				the mailer returns bad status.
62 **			   M_RESTR -- if set, this mailer is restricted
63 **				to use by "daemon"; otherwise, we do a
64 **				setuid(getuid()) before calling the
65 **				mailer.
66 **			   M_HDR -- if set, the mailer wants us to
67 **				insert a UNIX "From" line before
68 **				outputing.
69 **			   M_FHDR -- if set, the header that we
70 **				generate will be used literally, so
71 **				we must force it to be correct.  The
72 **				effect is that we generate a header
73 **				even if one exists.
74 **			   M_NOHOST -- if set, this mailer doesn't care
75 **				about the host part (e.g., the local
76 **				mailer).
77 **			   M_STRIPQ -- if set, strip quote (`"')
78 **				characters out of parameters as you
79 **				transliterate them into the argument
80 **				vector.  For example, the local mailer
81 **				is called directly, so these should be
82 **				stripped, but the program-mailer (i.e.,
83 **				csh) should leave them in.
84 **			- an exit status to use as the code for the
85 **			  error message print if the mailer returns
86 **			  something we don't understand.
87 **			- A list of names that are to be considered
88 **			  "local" (and hence are stripped off) for
89 **			  this mailer.
90 **			- An argument vector to be passed to the
91 **			  mailer with the following substitutions:
92 **			   $f - the from person name.
93 **			   $u - the target user name.
94 **			   $h - the target user host.
95 **			   $c - the hop count.
96 **			>>>>>>>>>> Entry zero must be for the local
97 **			>> NOTE >> mailer and entry one must be for
98 **			>>>>>>>>>> the shell.
99 **		ParseTab -- a table driving the parsing process.  Each
100 **			entry contains:
101 **			- a character that will trigger this entry.
102 **			- an index into the Mailer table.
103 **			- a word of flags, described in dlvrmail.h.
104 **			- an argument.  If we have P_MAP, it is the
105 **			  character to turn the trigger character into.
106 **			  If we have P_MOVE, it is the site to send it
107 **			  to, using the mailer specified above.
108 **			This table will almost certainly have to be
109 **			changed on your site if you have anything more
110 **			than the UUCP net.
111 */
112 
113 
114 
115 
116 static char SccsId[] = "@(#)conf.c	2.6	02/15/81";
117 
118 
119 bool	UseMsgId = FALSE;	/* don't put message id's in anywhere */
120 
121 # include <whoami.h>		/* definitions of machine id's at berkeley */
122 
123 # ifdef BERKELEY
124 
125 char	*ArpaHost = "Berkeley";	/* host name of gateway on Arpanet */
126 # define NETV6MAIL		/* use /usr/net/bin/v6mail for local delivery */
127 
128 # else BERKELEY
129 
130 char	*ArpaHost = "[unknown]";
131 char	*MyLocName = sysname;
132 # define HASUUCP		/* default to having UUCP net */
133 char	*UucpLocal[] = { sysname, NULL };
134 
135 # endif BERKELEY
136 
137 
138 /* Specific Configurations for Berkeley Machines */
139 
140 /* Berkeley people: mail changes to csvax:eric or they will be lost! */
141 
142 # ifdef ING70
143 static char	*BerkLocal[] = { "i", "ingres", "ing70", NULL };
144 char		*ArpaLocal = { "berkeley", "ucb", NULL };
145 char		*MyLocName = "Ing70";
146 char		*DaemonName = "Ing70:~MAILER~DAEMON~";
147 # define HASARPA
148 # define V6
149 # endif ING70
150 
151 # ifdef INGVAX
152 static char	*BerkLocal[] = { "j", "ingvax", NULL };
153 char		*MyLocName = "IngVax";
154 char		*DaemonName = "IngVax:~MAILER~DAEMON~";
155 # endif INGVAX
156 
157 # ifdef CSVAX
158 static char	*BerkLocal[] = { "v", "csvax", "vax", NULL };
159 static char	*UucpLocal[] = { "ucbvax", "ernie", NULL };
160 char		*MyLocName = "CSVAX";
161 char		*DaemonName = "CSVAX:~MAILER~DAEMON~";
162 # define HASUUCP
163 # endif CSVAX
164 
165 # ifdef ARPAVAX
166 static char	*BerkLocal[] = { "r", "arpavax", NULL };
167 char		*MyLocName = "ARPAVAX";
168 char		*DaemonName = "ARPAVAX:~MAILER~DAEMON~";
169 # endif ARPAVAX
170 
171 # ifdef CORY
172 static char	*BerkLocal[] = { "y", "cory", NULL };
173 char		*MyLocName = "Cory";
174 char		*DaemonName = "Cory:~MAILER~DAEMON~";
175 # endif CORY
176 
177 # ifdef ONYX
178 static char	*BerkLocal[[] = { "x", "onyx", NULL };
179 char		*MyLocName = "Onyx";
180 char		*DaemonName = "Onyx:~MAILER~DAEMON~";
181 # endif ONYX
182 
183 # ifdef IMAGE
184 /* untested */
185 static char	*BerkLocal[] = { "m", "image", NULL };
186 char		*MyLocName = "Image";
187 char		*DaemonName = "Image:~MAILER~DAEMON~";
188 # define V6
189 # endif IMAGE
190 
191 # ifdef ESVAX
192 static char	*BerkLocal[] = { "o", "esvax", NULL };
193 char		*MyLocName = "ESVAX";
194 char		*DaemonName = "ESVAX:~MAILER~DAEMON~";
195 # endif ESVAX
196 
197 # ifdef EECS40
198 /* untested */
199 static char	*BerkLocal[] = { "z", "eecs40", NULL };
200 char		*MyLocName = "EECS40";
201 char		*DaemonName = "EECS40:~MAILER~DAEMON~";
202 # define V6
203 # endif EECS40
204 
205 
206 # ifndef HASARPA
207 # define ArpaLocal	NULL
208 # endif HASARPA
209 
210 # ifndef HASUUCP
211 # define UucpLocal	NULL
212 # endif HASUUCP
213 
214 
215 struct mailer Mailer[] =
216 {
217 	/* local mail -- must be #0 */
218 	{
219 # ifdef NETV6MAIL
220 		"/usr/net/bin/v6mail",
221 # else
222 		"/bin/mail",
223 # endif
224 		M_ROPT|M_NOHOST|M_STRIPQ,	EX_NOUSER,	NULL,
225 		{ "...local%mail", "-d", "$u", NULL }
226 	},
227 	/* pipes through programs -- must be #1 */
228 	{
229 		"/bin/csh",
230 		M_HDR|M_FHDR|M_NOHOST,		EX_UNAVAILABLE,	NULL,
231 		{ "...prog%mail", "-fc", "$u", NULL }
232 	},
233 	/* local berkeley mail */
234 	{
235 		"/usr/net/bin/sendberkmail",
236 		M_FOPT|M_HDR|M_STRIPQ,		EX_UNAVAILABLE,	BerkLocal,
237 		{ "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL }
238 	},
239 	/* arpanet mail */
240 	{
241 		"/usr/lib/mailers/arpa",
242 		M_STRIPQ,			0,		ArpaLocal,
243 		{ "...arpa%mail", "$f", "$h", "$u", NULL }
244 	},
245 	/* uucp mail (cheat & use Bell's v7 mail) */
246 	{
247 		"/bin/mail",
248 		M_ROPT|M_STRIPQ,		EX_NOUSER,	UucpLocal,
249 # ifdef DUMBMAIL
250 		{ "...uucp%mail", "$h!$u", NULL }
251 # else
252 		{ "...uucp%mail", "-d", "$h!$u", NULL }
253 # endif DUMBMAIL
254 	},
255 };
256 
257 # define M_LOCAL	0
258 # define M_BERK		2
259 # define M_ARPA		3
260 # define M_UUCP		4
261 
262 
263 
264 # ifdef BERKELEY
265 struct parsetab ParseTab[] =
266 {
267 	':',	M_BERK,		P_ONE,				NULL,
268 # ifdef HASARPA
269 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
270 # else
271 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
272 # endif HASARPA
273 	'^',	-1,		P_MAP,				"!",
274 # ifdef HASUUCP
275 	'!',	M_UUCP,		0,				NULL,
276 # else
277 	'!',	M_BERK,		P_MOVE,				"csvax",
278 # endif HASUUCP
279 	'.',	-1,		P_MAP|P_ONE,			":",
280 	'\0',	M_LOCAL,	P_MOVE,				"",
281 };
282 # else BERKELEY
283 struct parsetab ParseTab[] =
284 {
285 # ifdef HASARPA
286 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
287 # endif HASARPA
288 # ifdef HASUUCP
289 	'^',	-1,		P_MAP,				"!",
290 	'!',	M_UUCP,		0,				NULL,
291 # endif HASUUCP
292 	'\0',	M_LOCAL,	P_MOVE,				"",
293 };
294 # endif BERKELEY
295 /*
296 **  GETNAME -- Get the current users login name.
297 **
298 **	This is in config.c because it is somewhat machine dependent.
299 **	Examine it carefully for your installation.
300 **
301 **	Algorithm:
302 **		See if the person is logged in.  If so, return
303 **			the name s/he is logged in as.
304 **		Look up the user id in /etc/passwd.  If found,
305 **			return that name.
306 **		Return NULL.
307 **
308 **	Parameters:
309 **		none
310 **
311 **	Returns:
312 **		The login name of this user.
313 **		NULL if this person is noone.
314 **
315 **	Side Effects:
316 **		none
317 **
318 **	Called By:
319 **		main
320 */
321 
322 char *
323 getname()
324 {
325 	register char *p;
326 	register struct passwd *w;
327 	extern char *getlogin();
328 	extern struct passwd *getpwuid();
329 	static char namebuf[9];
330 
331 	p = getlogin();
332 	if (p != NULL && p[0] != '\0')
333 		return (p);
334 # ifdef V6
335 	w = getpwuid(getuid() & 0377);
336 # else
337 	w = getpwuid(getuid());
338 # endif V6
339 	if (w != NULL)
340 	{
341 		strcpy(namebuf, w->pw_name);
342 		return (namebuf);
343 	}
344 	return (NULL);
345 }
346 
347 # ifdef V6
348 /*
349 **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
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 **
368 **	Called By:
369 **		savemail
370 */
371 
372 # include <sys/types.h>
373 # include <sys/stat.h>
374 
375 char *
376 ttypath()
377 {
378 	struct stat stbuf;
379 	register int i;
380 	static char pathn[] = "/dev/ttyx";
381 	extern int errno;
382 
383 	/* compute the pathname of the controlling tty */
384 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
385 	{
386 		errno = 0;
387 		return (NULL);
388 	}
389 	pathn[8] = i;
390 
391 	/* see if we have write permission */
392 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
393 	{
394 		errno = 0;
395 		return (NULL);
396 	}
397 
398 	/* see if the user is logged in */
399 	if (getlogin() == NULL)
400 		return (NULL);
401 
402 	/* looks good */
403 	return (pathn);
404 }
405 /*
406 **  FDOPEN -- Open a stdio file given an open file descriptor.
407 **
408 **	This is included here because it is standard in v7, but we
409 **	need it in v6.
410 **
411 **	Algorithm:
412 **		Open /dev/null to create a descriptor.
413 **		Close that descriptor.
414 **		Copy the existing fd into the descriptor.
415 **
416 **	Parameters:
417 **		fd -- the open file descriptor.
418 **		type -- "r", "w", or whatever.
419 **
420 **	Returns:
421 **		The file descriptor it creates.
422 **
423 **	Side Effects:
424 **		none
425 **
426 **	Called By:
427 **		deliver
428 **
429 **	Notes:
430 **		The mode of fd must match "type".
431 */
432 
433 FILE *
434 fdopen(fd, type)
435 	int fd;
436 	char *type;
437 {
438 	register FILE *f;
439 
440 	f = fopen("/dev/null", type);
441 	close(fileno(f));
442 	fileno(f) = fd;
443 	return (f);
444 }
445 /*
446 **  INDEX -- Return pointer to character in string
447 **
448 **	For V7 compatibility.
449 **
450 **	Parameters:
451 **		s -- a string to scan.
452 **		c -- a character to look for.
453 **
454 **	Returns:
455 **		If c is in s, returns the address of the first
456 **			instance of c in s.
457 **		NULL if c is not in s.
458 **
459 **	Side Effects:
460 **		none.
461 */
462 
463 index(s, c)
464 	register char *s;
465 	register char c;
466 {
467 	while (*s != '\0')
468 	{
469 		if (*s++ == c)
470 			return (--s);
471 	}
472 	return (NULL);
473 }
474 # endif V6
475 
476 # ifndef V6
477 /*
478 **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
479 **
480 **	Returns the pathname of the user's tty.  Returns NULL if
481 **	the user is not logged in or if s/he has write permission
482 **	denied.
483 **
484 **	Parameters:
485 **		none
486 **
487 **	Returns:
488 **		pathname of the user's tty.
489 **		NULL if not logged in or write permission denied.
490 **
491 **	Side Effects:
492 **		none.
493 **
494 **	WARNING:
495 **		Return value is in a local buffer.
496 **
497 **	Called By:
498 **		savemail
499 */
500 
501 # include <sys/types.h>
502 # include <sys/stat.h>
503 
504 char *
505 ttypath()
506 {
507 	struct stat stbuf;
508 	register char *pathn;
509 	extern int errno;
510 	extern char *ttyname();
511 
512 	/* compute the pathname of the controlling tty */
513 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
514 	{
515 		errno = 0;
516 		return (NULL);
517 	}
518 
519 	/* see if we have write permission */
520 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
521 	{
522 		errno = 0;
523 		return (NULL);
524 	}
525 
526 	/* see if the user is logged in */
527 	if (getlogin() == NULL)
528 		return (NULL);
529 
530 	/* looks good */
531 	return (pathn);
532 }
533 # endif V6
534