xref: /original-bsd/usr.sbin/sendmail/src/conf.c (revision 6c57d260)
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.13	04/01/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 /* local berkeley mail */
139 static char	*BerkArgv[] =
140 {
141 	"...berk%mail",
142 	"-m",
143 	"$h",
144 	"-h",
145 	"$c",
146 	"-t",
147 	"$u",
148 	NULL
149 };
150 
151 static struct mailer	BerkMailer =
152 {
153 	"berk",		"/usr/net/bin/sendberkmail",
154 	M_FOPT|M_NEEDDATE|M_FULLNAME|M_STRIPQ,
155 	EX_UNAVAILABLE,	"$B:$f",	BerkArgv,	NULL,
156 };
157 
158 /* arpanet mail */
159 static char	*ArpaArgv[] =
160 {
161 	"...arpa%mail",
162 	"$f",
163 	"$h",
164 	"$u",
165 	NULL
166 };
167 
168 static struct mailer	ArpaMailer =
169 {
170 	"arpa",		"/usr/lib/mailers/arpa",
171 	M_STRIPQ|M_ARPAFMT|M_USR_UPPER,
172 	0,		"$f@$A",	ArpaArgv,	NULL,
173 };
174 
175 /* uucp mail (cheat & use Bell's v7 mail) */
176 static char	*UucpArgv[] =
177 {
178 	"...uucp%mail",
179 	"-",
180 	"$h!rmail",
181 	"($u)",
182 	NULL
183 };
184 
185 static struct mailer	UucpMailer =
186 {
187 	"uucp",		"/usr/bin/uux",
188 	M_ROPT|M_STRIPQ|M_NEEDDATE|M_FULLNAME|M_MUSER,
189 	EX_NOUSER,	"$U!$f",	UucpArgv,	NULL,
190 };
191 
192 struct mailer	*Mailer[] =
193 {
194 	&LocalMailer,		/* 0 -- must be 0 */
195 	&ProgMailer,		/* 1 -- must be 1 */
196 	&BerkMailer,		/* 2 */
197 	&ArpaMailer,		/* 3 */
198 	&UucpMailer,		/* 4 */
199 	NULL
200 };
201 
202 # define M_LOCAL	0
203 # define M_PROG		1
204 # define M_BERK		2
205 # define M_ARPA		3
206 # define M_UUCP		4
207 
208 
209 
210 
211 
212 /*
213 **  Header info table
214 **	Final (null) entry contains the flags used for any other field.
215 */
216 
217 struct hdrinfo	HdrInfo[] =
218 {
219 	"date",		H_CHECK,		M_NEEDDATE,
220 	"from",		H_CHECK,		M_NEEDFROM,
221 	"full-name",	H_ACHECK,		M_FULLNAME,
222 	"to",		0,			NULL,
223 	"cc",		0,			NULL,
224 	"subject",	0,			NULL,
225 	"message-id",	H_CHECK,		M_MSGID,
226 	"message",	H_EOH,			NULL,
227 	NULL,		0,			NULL,
228 };
229 
230 # ifdef V6
231 /*
232 **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
233 **
234 **	Returns the pathname of the user's tty.  Returns NULL if
235 **	the user is not logged in or if s/he has write permission
236 **	denied.
237 **
238 **	Parameters:
239 **		none
240 **
241 **	Returns:
242 **		pathname of the user's tty.
243 **		NULL if not logged in or write permission denied.
244 **
245 **	Side Effects:
246 **		none.
247 **
248 **	WARNING:
249 **		Return value is in a local buffer.
250 **
251 **	Called By:
252 **		savemail
253 */
254 
255 # include <sys/types.h>
256 # include <sys/stat.h>
257 
258 char *
259 ttypath()
260 {
261 	struct stat stbuf;
262 	register int i;
263 	static char pathn[] = "/dev/ttyx";
264 	extern int errno;
265 
266 	/* compute the pathname of the controlling tty */
267 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
268 	{
269 		errno = 0;
270 		return (NULL);
271 	}
272 	pathn[8] = i;
273 
274 	/* see if we have write permission */
275 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
276 	{
277 		errno = 0;
278 		return (NULL);
279 	}
280 
281 	/* see if the user is logged in */
282 	if (getlogin() == NULL)
283 		return (NULL);
284 
285 	/* looks good */
286 	return (pathn);
287 }
288 /*
289 **  FDOPEN -- Open a stdio file given an open file descriptor.
290 **
291 **	This is included here because it is standard in v7, but we
292 **	need it in v6.
293 **
294 **	Algorithm:
295 **		Open /dev/null to create a descriptor.
296 **		Close that descriptor.
297 **		Copy the existing fd into the descriptor.
298 **
299 **	Parameters:
300 **		fd -- the open file descriptor.
301 **		type -- "r", "w", or whatever.
302 **
303 **	Returns:
304 **		The file descriptor it creates.
305 **
306 **	Side Effects:
307 **		none
308 **
309 **	Called By:
310 **		deliver
311 **
312 **	Notes:
313 **		The mode of fd must match "type".
314 */
315 
316 FILE *
317 fdopen(fd, type)
318 	int fd;
319 	char *type;
320 {
321 	register FILE *f;
322 
323 	f = fopen("/dev/null", type);
324 	close(fileno(f));
325 	fileno(f) = fd;
326 	return (f);
327 }
328 /*
329 **  INDEX -- Return pointer to character in string
330 **
331 **	For V7 compatibility.
332 **
333 **	Parameters:
334 **		s -- a string to scan.
335 **		c -- a character to look for.
336 **
337 **	Returns:
338 **		If c is in s, returns the address of the first
339 **			instance of c in s.
340 **		NULL if c is not in s.
341 **
342 **	Side Effects:
343 **		none.
344 */
345 
346 index(s, c)
347 	register char *s;
348 	register char c;
349 {
350 	while (*s != '\0')
351 	{
352 		if (*s++ == c)
353 			return (--s);
354 	}
355 	return (NULL);
356 }
357 # endif V6
358 
359 # ifndef V6
360 /*
361 **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
362 **
363 **	Returns the pathname of the user's tty.  Returns NULL if
364 **	the user is not logged in or if s/he has write permission
365 **	denied.
366 **
367 **	Parameters:
368 **		none
369 **
370 **	Returns:
371 **		pathname of the user's tty.
372 **		NULL if not logged in or write permission denied.
373 **
374 **	Side Effects:
375 **		none.
376 **
377 **	WARNING:
378 **		Return value is in a local buffer.
379 **
380 **	Called By:
381 **		savemail
382 */
383 
384 # include <sys/types.h>
385 # include <sys/stat.h>
386 
387 char *
388 ttypath()
389 {
390 	struct stat stbuf;
391 	register char *pathn;
392 	extern int errno;
393 	extern char *ttyname();
394 
395 	/* compute the pathname of the controlling tty */
396 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
397 	{
398 		errno = 0;
399 		return (NULL);
400 	}
401 
402 	/* see if we have write permission */
403 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
404 	{
405 		errno = 0;
406 		return (NULL);
407 	}
408 
409 	/* see if the user is logged in */
410 	if (getlogin() == NULL)
411 		return (NULL);
412 
413 	/* looks good */
414 	return (pathn);
415 }
416 # endif V6
417 /*
418 **  CHECKCOMPAT -- check for From and To person compatible.
419 **
420 **	This routine can be supplied on a per-installation basis
421 **	to determine whether a person is allowed to send a message.
422 **	This allows restriction of certain types of internet
423 **	forwarding or registration of users.
424 **
425 **	If the hosts are found to be incompatible, an error
426 **	message should be given using "usrerr" and FALSE should
427 **	be returned.
428 **
429 **	Parameters:
430 **		to -- the person being sent to.
431 **
432 **	Returns:
433 **		TRUE -- ok to send.
434 **		FALSE -- not ok.
435 **
436 **	Side Effects:
437 **		none (unless you include the usrerr stuff)
438 */
439 
440 bool
441 checkcompat(to)
442 	register ADDRESS *to;
443 {
444 	return (TRUE);
445 }
446