xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 2355)
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.5	02/07/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 IMAGE
178 /* untested */
179 static char	*BerkLocal[] = { "m", "image", NULL };
180 char		*MyLocName = "Image";
181 char		*DaemonName = "Image:~MAILER~DAEMON~";
182 # define V6
183 # endif IMAGE
184 
185 # ifdef ESVAX
186 static char	*BerkLocal[] = { "o", "esvax", NULL };
187 char		*MyLocName = "ESVAX";
188 char		*DaemonName = "ESVAX:~MAILER~DAEMON~";
189 # endif ESVAX
190 
191 # ifdef EECS40
192 /* untested */
193 static char	*BerkLocal[] = { "z", "eecs40", NULL };
194 char		*MyLocName = "EECS40";
195 char		*DaemonName = "EECS40:~MAILER~DAEMON~";
196 # define V6
197 # endif EECS40
198 
199 
200 # ifndef HASARPA
201 # define ArpaLocal	NULL
202 # endif HASARPA
203 
204 # ifndef HASUUCP
205 # define UucpLocal	NULL
206 # endif HASUUCP
207 
208 
209 struct mailer Mailer[] =
210 {
211 	/* local mail -- must be #0 */
212 	{
213 # ifdef NETV6MAIL
214 		"/usr/net/bin/v6mail",
215 # else
216 		"/bin/mail",
217 # endif
218 		M_ROPT|M_NOHOST|M_STRIPQ,	EX_NOUSER,	NULL,
219 		{ "...local%mail", "-d", "$u", NULL }
220 	},
221 	/* pipes through programs -- must be #1 */
222 	{
223 		"/bin/csh",
224 		M_HDR|M_FHDR|M_NOHOST,		EX_UNAVAILABLE,	NULL,
225 		{ "...prog%mail", "-fc", "$u", NULL }
226 	},
227 	/* local berkeley mail */
228 	{
229 		"/usr/net/bin/sendberkmail",
230 		M_FOPT|M_HDR|M_STRIPQ,		EX_UNAVAILABLE,	BerkLocal,
231 		{ "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL }
232 	},
233 	/* arpanet mail */
234 	{
235 		"/usr/lib/mailers/arpa",
236 		M_STRIPQ,			0,		ArpaLocal,
237 		{ "...arpa%mail", "$f", "$h", "$u", NULL }
238 	},
239 	/* uucp mail (cheat & use Bell's v7 mail) */
240 	{
241 		"/bin/mail",
242 		M_ROPT|M_STRIPQ,		EX_NOUSER,	UucpLocal,
243 # ifdef DUMBMAIL
244 		{ "...uucp%mail", "$h!$u", NULL }
245 # else
246 		{ "...uucp%mail", "-d", "$h!$u", NULL }
247 # endif DUMBMAIL
248 	},
249 };
250 
251 # define M_LOCAL	0
252 # define M_BERK		2
253 # define M_ARPA		3
254 # define M_UUCP		4
255 
256 
257 
258 # ifdef BERKELEY
259 struct parsetab ParseTab[] =
260 {
261 	':',	M_BERK,		P_ONE,				NULL,
262 # ifdef HASARPA
263 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
264 # else
265 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
266 # endif HASARPA
267 	'^',	-1,		P_MAP,				"!",
268 # ifdef HASUUCP
269 	'!',	M_UUCP,		0,				NULL,
270 # else
271 	'!',	M_BERK,		P_MOVE,				"csvax",
272 # endif HASUUCP
273 	'.',	-1,		P_MAP|P_ONE,			":",
274 	'\0',	M_LOCAL,	P_MOVE,				"",
275 };
276 # else BERKELEY
277 struct parsetab ParseTab[] =
278 {
279 # ifdef HASARPA
280 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
281 # endif HASARPA
282 # ifdef HASUUCP
283 	'^',	-1,		P_MAP,				"!",
284 	'!',	M_UUCP,		0,				NULL,
285 # endif HASUUCP
286 	'\0',	M_LOCAL,	P_MOVE,				"",
287 };
288 # endif BERKELEY
289 /*
290 **  GETNAME -- Get the current users login name.
291 **
292 **	This is in config.c because it is somewhat machine dependent.
293 **	Examine it carefully for your installation.
294 **
295 **	Algorithm:
296 **		See if the person is logged in.  If so, return
297 **			the name s/he is logged in as.
298 **		Look up the user id in /etc/passwd.  If found,
299 **			return that name.
300 **		Return NULL.
301 **
302 **	Parameters:
303 **		none
304 **
305 **	Returns:
306 **		The login name of this user.
307 **		NULL if this person is noone.
308 **
309 **	Side Effects:
310 **		none
311 **
312 **	Called By:
313 **		main
314 */
315 
316 char *
317 getname()
318 {
319 	register char *p;
320 	register struct passwd *w;
321 	extern char *getlogin();
322 	extern struct passwd *getpwuid();
323 	static char namebuf[9];
324 
325 	p = getlogin();
326 	if (p != NULL && p[0] != '\0')
327 		return (p);
328 # ifdef V6
329 	w = getpwuid(getuid() & 0377);
330 # else
331 	w = getpwuid(getuid());
332 # endif V6
333 	if (w != NULL)
334 	{
335 		strcpy(namebuf, w->pw_name);
336 		return (namebuf);
337 	}
338 	return (NULL);
339 }
340 
341 # ifdef V6
342 /*
343 **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
344 **
345 **	Returns the pathname of the user's tty.  Returns NULL if
346 **	the user is not logged in or if s/he has write permission
347 **	denied.
348 **
349 **	Parameters:
350 **		none
351 **
352 **	Returns:
353 **		pathname of the user's tty.
354 **		NULL if not logged in or write permission denied.
355 **
356 **	Side Effects:
357 **		none.
358 **
359 **	WARNING:
360 **		Return value is in a local buffer.
361 **
362 **	Called By:
363 **		savemail
364 */
365 
366 # include <sys/types.h>
367 # include <sys/stat.h>
368 
369 char *
370 ttypath()
371 {
372 	struct stat stbuf;
373 	register int i;
374 	static char pathn[] = "/dev/ttyx";
375 	extern int errno;
376 
377 	/* compute the pathname of the controlling tty */
378 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
379 	{
380 		errno = 0;
381 		return (NULL);
382 	}
383 	pathn[8] = i;
384 
385 	/* see if we have write permission */
386 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
387 	{
388 		errno = 0;
389 		return (NULL);
390 	}
391 
392 	/* see if the user is logged in */
393 	if (getlogin() == NULL)
394 		return (NULL);
395 
396 	/* looks good */
397 	return (pathn);
398 }
399 /*
400 **  FDOPEN -- Open a stdio file given an open file descriptor.
401 **
402 **	This is included here because it is standard in v7, but we
403 **	need it in v6.
404 **
405 **	Algorithm:
406 **		Open /dev/null to create a descriptor.
407 **		Close that descriptor.
408 **		Copy the existing fd into the descriptor.
409 **
410 **	Parameters:
411 **		fd -- the open file descriptor.
412 **		type -- "r", "w", or whatever.
413 **
414 **	Returns:
415 **		The file descriptor it creates.
416 **
417 **	Side Effects:
418 **		none
419 **
420 **	Called By:
421 **		deliver
422 **
423 **	Notes:
424 **		The mode of fd must match "type".
425 */
426 
427 FILE *
428 fdopen(fd, type)
429 	int fd;
430 	char *type;
431 {
432 	register FILE *f;
433 
434 	f = fopen("/dev/null", type);
435 	close(fileno(f));
436 	fileno(f) = fd;
437 	return (f);
438 }
439 /*
440 **  INDEX -- Return pointer to character in string
441 **
442 **	For V7 compatibility.
443 **
444 **	Parameters:
445 **		s -- a string to scan.
446 **		c -- a character to look for.
447 **
448 **	Returns:
449 **		If c is in s, returns the address of the first
450 **			instance of c in s.
451 **		NULL if c is not in s.
452 **
453 **	Side Effects:
454 **		none.
455 */
456 
457 index(s, c)
458 	register char *s;
459 	register char c;
460 {
461 	while (*s != '\0')
462 	{
463 		if (*s++ == c)
464 			return (--s);
465 	}
466 	return (NULL);
467 }
468 # endif V6
469 
470 # ifndef V6
471 /*
472 **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
473 **
474 **	Returns the pathname of the user's tty.  Returns NULL if
475 **	the user is not logged in or if s/he has write permission
476 **	denied.
477 **
478 **	Parameters:
479 **		none
480 **
481 **	Returns:
482 **		pathname of the user's tty.
483 **		NULL if not logged in or write permission denied.
484 **
485 **	Side Effects:
486 **		none.
487 **
488 **	WARNING:
489 **		Return value is in a local buffer.
490 **
491 **	Called By:
492 **		savemail
493 */
494 
495 # include <sys/types.h>
496 # include <sys/stat.h>
497 
498 char *
499 ttypath()
500 {
501 	struct stat stbuf;
502 	register char *pathn;
503 	extern int errno;
504 	extern char *ttyname();
505 
506 	/* compute the pathname of the controlling tty */
507 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
508 	{
509 		errno = 0;
510 		return (NULL);
511 	}
512 
513 	/* see if we have write permission */
514 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
515 	{
516 		errno = 0;
517 		return (NULL);
518 	}
519 
520 	/* see if the user is logged in */
521 	if (getlogin() == NULL)
522 		return (NULL);
523 
524 	/* looks good */
525 	return (pathn);
526 }
527 # endif V6
528