xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 8261)
1 # include <pwd.h>
2 # include "sendmail.h"
3 
4 /*
5 **  CONF.C -- Sendmail Configuration Tables.
6 **
7 **	Defines the configuration of this installation.
8 **
9 **	Compilation Flags:
10 **		V6 -- running on a version 6 system.  This determines
11 **			whether to define certain routines between
12 **			the two systems.  If you are running a funny
13 **			system, e.g., V6 with long tty names, this
14 **			should be checked carefully.
15 **
16 **	Configuration Variables:
17 **		HdrInfo -- a table describing well-known header fields.
18 **			Each entry has the field name and some flags,
19 **			which are described in sendmail.h.
20 **		StdTimezone -- name of local timezone in standard time
21 **			(V6 only).
22 **		DstTimezone -- name of local timezone in daylight savings
23 **			time (V6 only).
24 **
25 **	Notes:
26 **		I have tried to put almost all the reasonable
27 **		configuration information into the configuration
28 **		file read at runtime.  My intent is that anything
29 **		here is a function of the version of UNIX you
30 **		are running, or is really static -- for example
31 **		the headers are a superset of widely used
32 **		protocols.  If you find yourself playing with
33 **		this file too much, you may be making a mistake!
34 */
35 
36 
37 
38 
39 SCCSID(@(#)conf.c	3.58		09/26/82);
40 
41 
42 
43 /*
44 **  Header info table
45 **	Final (null) entry contains the flags used for any other field.
46 **
47 **	Not all of these are actually handled specially by sendmail
48 **	at this time.  They are included as placeholders, to let
49 **	you know that "someday" I intend to have sendmail do
50 **	something with them.
51 */
52 
53 struct hdrinfo	HdrInfo[] =
54 {
55 		/* date information */
56 	"posted-date",		0,			0,
57 	"date",			H_CHECK,		M_NEEDDATE,
58 	"resent-date",		0,			0,
59 	"received-date",	H_CHECK,		M_LOCAL,
60 		/* originator fields, most to least significant  */
61 	"resent-sender",	H_FROM,			0,
62 	"resent-from",		H_FROM,			0,
63 	"sender",		H_FROM,			0,
64 	"from",			H_FROM|H_CHECK,		M_NEEDFROM,
65 	"full-name",		H_ACHECK,		M_FULLNAME,
66 	"received-from",	H_CHECK,		M_LOCAL,
67 	"return-receipt-to",	H_FROM,			0,
68 	"errors-to",		H_FROM,			0,
69 		/* destination fields */
70 	"to",			H_RCPT,			0,
71 	"resent-to",		H_RCPT,			0,
72 	"cc",			H_RCPT,			0,
73 	"resent-cc",		H_RCPT,			0,
74 	"bcc",			H_RCPT,			0,
75 	"resent-bcc",		H_RCPT,			0,
76 		/* message identification and control */
77 	"message-id",		0,			0,
78 	"resent-message-id",	0,			0,
79 	"precedence",		0,			0,
80 	"message",		H_EOH,			0,
81 	"text",			H_EOH,			0,
82 		/* trace fields */
83 	"received",		H_TRACE|H_FORCE,	0,
84 	"via",			H_TRACE|H_FORCE,	0,
85 	"mail-from",		H_TRACE|H_FORCE,	0,
86 
87 	NULL,			0,			0,
88 };
89 
90 
91 /*
92 **  ARPANET error message numbers.
93 */
94 
95 char	Arpa_Info[] =		"050";	/* arbitrary info */
96 char	Arpa_TSyserr[] =	"451";	/* some (transient) system error */
97 char	Arpa_PSyserr[] =	"554";	/* some (permanent) system error */
98 char	Arpa_Usrerr[] =		"554";	/* some (fatal) user error */
99 
100 
101 
102 
103 
104 /*
105 **  Location of system files/databases/etc.
106 */
107 
108 char	*AliasFile =	"/usr/lib/aliases";	/* alias file */
109 char	*ConfFile =	"/usr/lib/sendmail.cf";	/* runtime configuration */
110 char	*StatFile =	"/usr/lib/sendmail.st";	/* statistics summary */
111 char	*HelpFile =	"/usr/lib/sendmail.hf";	/* help file */
112 # ifdef QUEUE
113 char	*QueueDir =	"/usr/spool/mqueue";	/* queue of saved mail */
114 # else QUEUE
115 char	*QueueDir =	"/tmp";			/* location of temp files */
116 # endif QUEUE
117 char	*XcriptFile =	"/tmp/mailxXXXXXX";	/* template for transcript */
118 
119 
120 /*
121 **  Other configuration.
122 */
123 
124 int	DefUid =	1;		/* the uid to execute mailers as */
125 int	DefGid =	1;		/* ditto for gid */
126 time_t	TimeOut =	3*24*60*60L;	/* default timeout for queue files */
127 int	ReadTimeout =	10*60;		/* timeout on external reads */
128 int	LogLevel =	9;		/* default logging level */
129 bool	SuperSafe =	TRUE;		/* always create qf file */
130 
131 
132 
133 /*
134 **  V6 system configuration.
135 */
136 
137 # ifdef V6
138 char	*StdTimezone =	"PST";		/* std time timezone */
139 char	*DstTimezone =	"PDT";		/* daylight time timezone */
140 # endif V6
141 
142 # ifdef V6
143 /*
144 **  TTYNAME -- return name of terminal.
145 **
146 **	Parameters:
147 **		fd -- file descriptor to check.
148 **
149 **	Returns:
150 **		pointer to full path of tty.
151 **		NULL if no tty.
152 **
153 **	Side Effects:
154 **		none.
155 */
156 
157 char *
158 ttyname(fd)
159 	int fd;
160 {
161 	register char tn;
162 	static char pathn[] = "/dev/ttyx";
163 
164 	/* compute the pathname of the controlling tty */
165 	if ((tn = ttyn(fd)) == NULL)
166 	{
167 		errno = 0;
168 		return (NULL);
169 	}
170 	pathn[8] = tn;
171 	return (pathn);
172 }
173 /*
174 **  FDOPEN -- Open a stdio file given an open file descriptor.
175 **
176 **	This is included here because it is standard in v7, but we
177 **	need it in v6.
178 **
179 **	Algorithm:
180 **		Open /dev/null to create a descriptor.
181 **		Close that descriptor.
182 **		Copy the existing fd into the descriptor.
183 **
184 **	Parameters:
185 **		fd -- the open file descriptor.
186 **		type -- "r", "w", or whatever.
187 **
188 **	Returns:
189 **		The file descriptor it creates.
190 **
191 **	Side Effects:
192 **		none
193 **
194 **	Called By:
195 **		deliver
196 **
197 **	Notes:
198 **		The mode of fd must match "type".
199 */
200 
201 FILE *
202 fdopen(fd, type)
203 	int fd;
204 	char *type;
205 {
206 	register FILE *f;
207 
208 	f = fopen("/dev/null", type);
209 	(void) close(fileno(f));
210 	fileno(f) = fd;
211 	return (f);
212 }
213 /*
214 **  INDEX -- Return pointer to character in string
215 **
216 **	For V7 compatibility.
217 **
218 **	Parameters:
219 **		s -- a string to scan.
220 **		c -- a character to look for.
221 **
222 **	Returns:
223 **		If c is in s, returns the address of the first
224 **			instance of c in s.
225 **		NULL if c is not in s.
226 **
227 **	Side Effects:
228 **		none.
229 */
230 
231 char *
232 index(s, c)
233 	register char *s;
234 	register char c;
235 {
236 	while (*s != '\0')
237 	{
238 		if (*s++ == c)
239 			return (--s);
240 	}
241 	return (NULL);
242 }
243 /*
244 **  UMASK -- fake the umask system call.
245 **
246 **	Since V6 always acts like the umask is zero, we will just
247 **	assume the same thing.
248 */
249 
250 /*ARGSUSED*/
251 umask(nmask)
252 {
253 	return (0);
254 }
255 
256 
257 /*
258 **  GETRUID -- get real user id.
259 */
260 
261 getruid()
262 {
263 	return (getuid() & 0377);
264 }
265 
266 
267 /*
268 **  GETRGID -- get real group id.
269 */
270 
271 getrgid()
272 {
273 	return (getgid() & 0377);
274 }
275 
276 
277 /*
278 **  GETEUID -- get effective user id.
279 */
280 
281 geteuid()
282 {
283 	return ((getuid() >> 8) & 0377);
284 }
285 
286 
287 /*
288 **  GETEGID -- get effective group id.
289 */
290 
291 getegid()
292 {
293 	return ((getgid() >> 8) & 0377);
294 }
295 
296 # endif V6
297 
298 # ifndef V6
299 
300 /*
301 **  GETRUID -- get real user id (V7)
302 */
303 
304 getruid()
305 {
306 	if (Mode == MD_DAEMON)
307 		return (RealUid);
308 	else
309 		return (getuid());
310 }
311 
312 
313 /*
314 **  GETRGID -- get real group id (V7).
315 */
316 
317 getrgid()
318 {
319 	if (Mode == MD_DAEMON)
320 		return (RealGid);
321 	else
322 		return (getgid());
323 }
324 
325 # endif V6
326 /*
327 **  TTYPATH -- Get the path of the user's tty
328 **
329 **	Returns the pathname of the user's tty.  Returns NULL if
330 **	the user is not logged in or if s/he has write permission
331 **	denied.
332 **
333 **	Parameters:
334 **		none
335 **
336 **	Returns:
337 **		pathname of the user's tty.
338 **		NULL if not logged in or write permission denied.
339 **
340 **	Side Effects:
341 **		none.
342 **
343 **	WARNING:
344 **		Return value is in a local buffer.
345 **
346 **	Called By:
347 **		savemail
348 */
349 
350 # include <sys/stat.h>
351 
352 char *
353 ttypath()
354 {
355 	struct stat stbuf;
356 	register char *pathn;
357 	extern char *ttyname();
358 	extern char *getlogin();
359 
360 	/* compute the pathname of the controlling tty */
361 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
362 	{
363 		errno = 0;
364 		return (NULL);
365 	}
366 
367 	/* see if we have write permission */
368 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
369 	{
370 		errno = 0;
371 		return (NULL);
372 	}
373 
374 	/* see if the user is logged in */
375 	if (getlogin() == NULL)
376 		return (NULL);
377 
378 	/* looks good */
379 	return (pathn);
380 }
381 /*
382 **  CHECKCOMPAT -- check for From and To person compatible.
383 **
384 **	This routine can be supplied on a per-installation basis
385 **	to determine whether a person is allowed to send a message.
386 **	This allows restriction of certain types of internet
387 **	forwarding or registration of users.
388 **
389 **	If the hosts are found to be incompatible, an error
390 **	message should be given using "usrerr" and FALSE should
391 **	be returned.
392 **
393 **	'NoReturn' can be set to suppress the return-to-sender
394 **	function; this should be done on huge messages.
395 **
396 **	Parameters:
397 **		to -- the person being sent to.
398 **
399 **	Returns:
400 **		TRUE -- ok to send.
401 **		FALSE -- not ok.
402 **
403 **	Side Effects:
404 **		none (unless you include the usrerr stuff)
405 */
406 
407 bool
408 checkcompat(to)
409 	register ADDRESS *to;
410 {
411 # ifdef ING70
412 	register STAB *s;
413 # endif ING70
414 
415 	if (to->q_mailer != LocalMailer && CurEnv->e_msgsize > 100000)
416 	{
417 		usrerr("Message exceeds 100000 bytes");
418 		NoReturn++;
419 		return (FALSE);
420 	}
421 # ifdef ING70
422 	s = stab("arpa", ST_MAILER, ST_FIND);
423 	if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && to->q_mailer == s->s_mailer)
424 	{
425 		usrerr("No ARPA mail through this machine: see your system administration");
426 		return (FALSE);
427 	}
428 # endif ING70
429 	return (TRUE);
430 }
431