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