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