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