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