xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 4078)
1 # include <stdio.h>
2 # include <pwd.h>
3 # include "sendmail.h"
4 
5 /*
6 **  CONF.C -- Sendmail Configuration Tables.
7 **
8 **	Defines the configuration of this installation.
9 **
10 **	Compilation Flags:
11 **		NETV6MAIL -- set if you want to use "v6mail" that
12 **			comes with the Berkeley network.  Normally
13 **			/bin/mail will work fine, but around Berkeley
14 **			we use v6mail because it is a "fixed target".
15 **			Also, only v6mail has the "/dev/mail" stuff
16 **			in it (for biff(1)).
17 **		V6 -- running on a version 6 system.  This determines
18 **			whether to define certain routines between
19 **			the two systems.  If you are running a funny
20 **			system, e.g., V6 with long tty names, this
21 **			should be checked carefully.
22 **
23 **	Configuration Variables:
24 **		Mailer -- a table of mailers known to the system.
25 **			This should be fairly static.  The fields are:
26 **			- the pathname of the mailer.
27 **			- a list of flags describing the properties
28 **			  of this mailer:
29 **			   M_FOPT -- if set, the mailer has a picky "-f"
30 **				option.  In this mode, the mailer will
31 **				only accept the "-f" option if the
32 **				sender is actually "root", "network",
33 **				and possibly (but not necessarily) if
34 **				the -f argument matches the real sender.
35 **				The effect is that if the "-f" option
36 **				is given to sendmail then it will be
37 **				passed through (as arguments 1 & 2) to
38 **				the mailer.
39 **			   M_ROPT -- identical to M_FOPT, except uses
40 **				-r instead.
41 **			   M_QUIET -- if set, don't print a message if
42 **				the mailer returns bad status.
43 **			   M_RESTR -- if set, this mailer is restricted
44 **				to use by "daemon"; otherwise, we do a
45 **				setuid(getuid()) before calling the
46 **				mailer.
47 **			   M_NHDR -- if set, the mailer doesn't want us
48 **				to insert a UNIX "From" line before
49 **				outputing.
50 **			   M_NOHOST -- if set, this mailer doesn't care
51 **				about the host part (e.g., the local
52 **				mailer).
53 **			   M_STRIPQ -- if set, strip quote (`"')
54 **				characters out of parameters as you
55 **				transliterate them into the argument
56 **				vector.  For example, the local mailer
57 **				is called directly, so these should be
58 **				stripped, but the program-mailer (i.e.,
59 **				csh) should leave them in.
60 **			   M_NEEDDATE -- this mailer requires a Date:
61 **				field in the message.
62 **			   M_NEEDFROM -- this mailer requires a From:
63 **				field in the message.
64 **			   M_MSGID -- this mailer requires a Message-Id
65 **				field in the message.
66 **			   M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID.
67 **			- an exit status to use as the code for the
68 **			  error message print if the mailer returns
69 **			  something we don't understand.
70 **			- A list of names that are to be considered
71 **			  "local" (and hence are stripped off) for
72 **			  this mailer.
73 **			- An argument vector to be passed to the
74 **			  mailer; this is macro substituted.
75 **			>>>>>>>>>> Entry zero must be for the local
76 **			>> NOTE >> mailer and entry one must be for
77 **			>>>>>>>>>> the shell.
78 **		HdrInfo -- a table describing well-known header fields.
79 **			Each entry has the field name and some flags,
80 **			which can be:
81 **			- H_EOH -- this field is equivalent to a blank
82 **			  line; i.e., it signifies end of header.
83 **			- H_DELETE -- delete this field.
84 **			There is also a field pointing to a pointer
85 **			that should be set to point to this header.
86 */
87 
88 
89 
90 
91 static char SccsId[] = "@(#)conf.c	3.14	08/09/81";
92 
93 
94 # include <whoami.h>		/* definitions of machine id's at berkeley */
95 
96 # ifdef BERKELEY
97 # define NETV6MAIL		/* use /usr/net/bin/v6mail for local delivery */
98 # endif BERKELEY
99 
100 
101 
102 /* local mail -- must be #0 */
103 static char	*LocalArgv[] =
104 {
105 	"...local%mail",
106 	"-d",
107 	"$u",
108 	NULL
109 };
110 
111 static struct mailer	LocalMailer =
112 {
113 # ifdef NETV6MAIL
114 	"local",	"/usr/net/bin/v6mail",
115 # else
116 	"local",	"/bin/mail",
117 # endif
118 	M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT|M_MUSER|M_NHDR,
119 	EX_NOUSER,	"$f",		LocalArgv,	NULL,
120 };
121 
122 /* pipes through programs -- must be #1 -- also used for files */
123 static char	*ProgArgv[] =
124 {
125 	"...prog%mail",
126 	"-fc",
127 	"$u",
128 	NULL
129 };
130 
131 static struct mailer	ProgMailer =
132 {
133 	"prog",		"/bin/csh",
134 	M_NOHOST|M_ARPAFMT,
135 	EX_UNAVAILABLE, "$f",		ProgArgv,	NULL,
136 };
137 
138 /* user-private mailers -- must be #2 */
139 static char	*PrivArgv[] =
140 {
141 	"...priv%mail",
142 	"$u",
143 	NULL
144 };
145 
146 static struct mailer	PrivMailer =
147 {
148 	"priv",		NULL,
149 	M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT,
150 	EX_UNAVAILABLE,	"$f",		PrivArgv,	NULL,
151 };
152 
153 /* local berkeley mail */
154 static char	*BerkArgv[] =
155 {
156 	"...berk%mail",
157 	"-m",
158 	"$h",
159 	"-h",
160 	"$c",
161 	"-t",
162 	"$u",
163 	NULL
164 };
165 
166 static struct mailer	BerkMailer =
167 {
168 	"berk",		"/usr/net/bin/sendberkmail",
169 	M_FOPT|M_NEEDDATE|M_FULLNAME|M_STRIPQ,
170 	EX_UNAVAILABLE,	"$B:$f",	BerkArgv,	NULL,
171 };
172 
173 /* arpanet mail */
174 static char	*ArpaArgv[] =
175 {
176 	"...arpa%mail",
177 	"$f",
178 	"$h",
179 	"$u",
180 	NULL
181 };
182 
183 static struct mailer	ArpaMailer =
184 {
185 	"arpa",		"/usr/lib/mailers/arpa",
186 	M_STRIPQ|M_ARPAFMT|M_USR_UPPER,
187 	0,		"$f@$A",	ArpaArgv,	NULL,
188 };
189 
190 /* uucp mail (cheat & use Bell's v7 mail) */
191 static char	*UucpArgv[] =
192 {
193 	"...uucp%mail",
194 	"-",
195 	"$h!rmail",
196 	"($u)",
197 	NULL
198 };
199 
200 static struct mailer	UucpMailer =
201 {
202 	"uucp",		"/usr/bin/uux",
203 	M_ROPT|M_STRIPQ|M_NEEDDATE|M_FULLNAME|M_MUSER,
204 	EX_NOUSER,	"$U!$f",	UucpArgv,	NULL,
205 };
206 
207 struct mailer	*Mailer[] =
208 {
209 	&LocalMailer,		/* 0 -- must be 0 */
210 	&ProgMailer,		/* 1 -- must be 1 */
211 	&PrivMailer,		/* 2 -- must be 2 */
212 	&BerkMailer,		/* 3 */
213 	&ArpaMailer,		/* 4 */
214 	&UucpMailer,		/* 5 */
215 	NULL
216 };
217 
218 /* offsets for arbitrary mailers */
219 # define M_BERK		2	/* berknet */
220 # define M_ARPA		3	/* arpanet */
221 # define M_UUCP		4	/* UUCPnet */
222 
223 
224 
225 
226 
227 /*
228 **  Header info table
229 **	Final (null) entry contains the flags used for any other field.
230 */
231 
232 struct hdrinfo	HdrInfo[] =
233 {
234 	"date",		H_CHECK,		M_NEEDDATE,
235 	"from",		H_CHECK,		M_NEEDFROM,
236 	"full-name",	H_ACHECK,		M_FULLNAME,
237 	"to",		0,			NULL,
238 	"cc",		0,			NULL,
239 	"subject",	0,			NULL,
240 	"message-id",	H_CHECK,		M_MSGID,
241 	"message",	H_EOH,			NULL,
242 	NULL,		0,			NULL,
243 };
244 
245 # ifdef V6
246 /*
247 **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
248 **
249 **	Returns the pathname of the user's tty.  Returns NULL if
250 **	the user is not logged in or if s/he has write permission
251 **	denied.
252 **
253 **	Parameters:
254 **		none
255 **
256 **	Returns:
257 **		pathname of the user's tty.
258 **		NULL if not logged in or write permission denied.
259 **
260 **	Side Effects:
261 **		none.
262 **
263 **	WARNING:
264 **		Return value is in a local buffer.
265 **
266 **	Called By:
267 **		savemail
268 */
269 
270 # include <sys/types.h>
271 # include <sys/stat.h>
272 
273 char *
274 ttypath()
275 {
276 	struct stat stbuf;
277 	register int i;
278 	static char pathn[] = "/dev/ttyx";
279 	extern int errno;
280 
281 	/* compute the pathname of the controlling tty */
282 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
283 	{
284 		errno = 0;
285 		return (NULL);
286 	}
287 	pathn[8] = i;
288 
289 	/* see if we have write permission */
290 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
291 	{
292 		errno = 0;
293 		return (NULL);
294 	}
295 
296 	/* see if the user is logged in */
297 	if (getlogin() == NULL)
298 		return (NULL);
299 
300 	/* looks good */
301 	return (pathn);
302 }
303 /*
304 **  FDOPEN -- Open a stdio file given an open file descriptor.
305 **
306 **	This is included here because it is standard in v7, but we
307 **	need it in v6.
308 **
309 **	Algorithm:
310 **		Open /dev/null to create a descriptor.
311 **		Close that descriptor.
312 **		Copy the existing fd into the descriptor.
313 **
314 **	Parameters:
315 **		fd -- the open file descriptor.
316 **		type -- "r", "w", or whatever.
317 **
318 **	Returns:
319 **		The file descriptor it creates.
320 **
321 **	Side Effects:
322 **		none
323 **
324 **	Called By:
325 **		deliver
326 **
327 **	Notes:
328 **		The mode of fd must match "type".
329 */
330 
331 FILE *
332 fdopen(fd, type)
333 	int fd;
334 	char *type;
335 {
336 	register FILE *f;
337 
338 	f = fopen("/dev/null", type);
339 	close(fileno(f));
340 	fileno(f) = fd;
341 	return (f);
342 }
343 /*
344 **  INDEX -- Return pointer to character in string
345 **
346 **	For V7 compatibility.
347 **
348 **	Parameters:
349 **		s -- a string to scan.
350 **		c -- a character to look for.
351 **
352 **	Returns:
353 **		If c is in s, returns the address of the first
354 **			instance of c in s.
355 **		NULL if c is not in s.
356 **
357 **	Side Effects:
358 **		none.
359 */
360 
361 index(s, c)
362 	register char *s;
363 	register char c;
364 {
365 	while (*s != '\0')
366 	{
367 		if (*s++ == c)
368 			return (--s);
369 	}
370 	return (NULL);
371 }
372 # endif V6
373 
374 # ifndef V6
375 /*
376 **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
377 **
378 **	Returns the pathname of the user's tty.  Returns NULL if
379 **	the user is not logged in or if s/he has write permission
380 **	denied.
381 **
382 **	Parameters:
383 **		none
384 **
385 **	Returns:
386 **		pathname of the user's tty.
387 **		NULL if not logged in or write permission denied.
388 **
389 **	Side Effects:
390 **		none.
391 **
392 **	WARNING:
393 **		Return value is in a local buffer.
394 **
395 **	Called By:
396 **		savemail
397 */
398 
399 # include <sys/types.h>
400 # include <sys/stat.h>
401 
402 char *
403 ttypath()
404 {
405 	struct stat stbuf;
406 	register char *pathn;
407 	extern int errno;
408 	extern char *ttyname();
409 
410 	/* compute the pathname of the controlling tty */
411 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
412 	{
413 		errno = 0;
414 		return (NULL);
415 	}
416 
417 	/* see if we have write permission */
418 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
419 	{
420 		errno = 0;
421 		return (NULL);
422 	}
423 
424 	/* see if the user is logged in */
425 	if (getlogin() == NULL)
426 		return (NULL);
427 
428 	/* looks good */
429 	return (pathn);
430 }
431 # endif V6
432 /*
433 **  CHECKCOMPAT -- check for From and To person compatible.
434 **
435 **	This routine can be supplied on a per-installation basis
436 **	to determine whether a person is allowed to send a message.
437 **	This allows restriction of certain types of internet
438 **	forwarding or registration of users.
439 **
440 **	If the hosts are found to be incompatible, an error
441 **	message should be given using "usrerr" and FALSE should
442 **	be returned.
443 **
444 **	Parameters:
445 **		to -- the person being sent to.
446 **
447 **	Returns:
448 **		TRUE -- ok to send.
449 **		FALSE -- not ok.
450 **
451 **	Side Effects:
452 **		none (unless you include the usrerr stuff)
453 */
454 
455 bool
456 checkcompat(to)
457 	register ADDRESS *to;
458 {
459 	return (TRUE);
460 }
461