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