File: spec_55.html

package info (click to toggle)
exim-html 3.20-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, sarge, woody
  • size: 2,868 kB
  • ctags: 4,188
  • sloc: makefile: 40; sh: 19
file content (596 lines) | stat: -rw-r--r-- 21,039 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.52
     from spec on 25 November 2000 -->

<TITLE>Exim Specification - 55. Security considerations</TITLE>
</HEAD>
<body bgcolor="#FFFFFF" text="#00005A" link="#FF6600" alink="#FF9933" vlink="#990000">
Go to the <A HREF="spec_1.html">first</A>, <A HREF="spec_54.html">previous</A>, <A HREF="spec_56.html">next</A>, <A HREF="spec_59.html">last</A> section, <A HREF="spec_toc.html">table of contents</A>.
<P><HR><P>


<H1><A NAME="SEC907" HREF="spec_toc.html#TOC907">55. Security considerations</A></H1>
<P>
<A NAME="IDX1990"></A>
This chapter discusses a number of issues concerned with security, some of
which are also covered in other parts of this manual.

</P>
<P>
For reasons that this author does not understand, some people have promoted
Exim as a `particularly secure' mailer. Perhaps it is because of the existence
of this chapter in the documentation. However, the intent of the chapter is
simply to describe the way Exim works in relation to certain security concerns,
not to make any specific claims about the effectiveness of its security as
compared with other MTAs.

</P>
<P>
What follows is a description of the way Exim is supposed to be. Best efforts
have been made to try to ensure that the code agrees with the theory, but an
absence of bugs can never be guaranteed. Any that are reported will get fixed as
soon as possible.

</P>

<P>



<H2><A NAME="SEC908" HREF="spec_toc.html#TOC908">55.1 Root privilege</A></H2>

<P>
<A NAME="IDX1991"></A>
<A NAME="IDX1992"></A>
The Exim binary is normally setuid to root. In some special cases (for example,
when the daemon is not in use and there are no conventional local deliveries),
it may be possible to run it setuid to some user other than root. However, root
privilege is usually required for two things:

</P>

<UL>

<LI>

To set up a socket connected to the standard SMTP port (25) when initialising
the listening daemon.
If Exim is run from <EM>inetd</EM>, this privileged action is not required.

<LI>

To be able to change uid and gid in order to read forward files and perform
local deliveries as the receiving user or as specified in the configuration.
</UL>

<P>
It is not necessary to be root to do any of the other things Exim does, such as
receiving messages and delivering them externally over SMTP, and it is
obviously more secure if Exim does not run as root except when necessary.

</P>
<P>
If no user is specified for Exim in either the compile-time or run time
configuration files, it runs as root all the time, except when performing
local deliveries. When an alternative user is specified (which is recommended),
it gives up root privilege when it can. Exactly how and when it does this
depends on whether the operating system supports the <EM>seteuid()</EM> or the
<EM>setresuid()</EM> function.

</P>
<P>
To avoid unnecessary complication, the discussion below talks about users, and
functions for setting the uid. It should be understood that in all cases there
is a corresponding group and gid, and that this is also changed whenever the
uid is changed.
<A NAME="IDX1993"></A>
<A NAME="IDX1994"></A>
The description is written in terms of <EM>seteuid()</EM>, since this is
more common than <EM>setresuid()</EM>. However, it is possible to specify at
compile time that an operating system has <EM>setresuid()</EM> and not <EM>seteuid()</EM>.

</P>
<P>
On systems without <EM>seteuid()</EM>, Exim uses <EM>setuid()</EM> to give up root privilege
at certain times, at the expense of having to re-invoke itself (using <EM>exec</EM>)
in order to regain privilege when necessary. If <EM>seteuid()</EM> is available, there
is a configuration choice as to which method is used for temporarily giving up
the privilege. Using <EM>setuid()</EM> is more secure, and is the default, but uses
more resources.

</P>
<P>
There are two instances in which Exim always uses <EM>setuid()</EM>:

</P>

<UL>

<LI>

Exim always uses <EM>setuid()</EM> to become a non-root user when running a local
delivery process. There are no exceptions. This applies whether or not an Exim
user is defined.

<LI>

Exim always uses <EM>setuid()</EM> to change to the Exim user (if one is defined)
before doing remote deliveries. These are the last things a delivery process
does, so it does not need to regain root privilege again.
</UL>

<P>
There are two instances in which Exim always uses <EM>seteuid()</EM> (provided it is
available in the operating system):

</P>

<UL>

<LI>

When reading a user's <TT>`.forward'</TT> file, Exim uses <EM>seteuid()</EM> to become that
user. This is necessary when the file is not publicly readable and is on a
remote NFS file system that is mounted without root privilege. If this is the
case on a system without <EM>seteuid()</EM>, the <TT>`.forward'</TT> file cannot be read.

<LI>

If any director or router has the <EM>require_files</EM> option set to check the
existence of a file as a specific user, <EM>seteuid()</EM> is used to become that
user for the duration of the check.
</UL>

<P>
For other operations, the <EM>security</EM> configuration option controls whether Exim
uses <EM>setuid()</EM> or <EM>seteuid()</EM> to change to its own uid.
It can be set to one of three strings:

</P>

<UL>

<LI>

<EM>seteuid</EM>: Exim uses <EM>seteuid()</EM> to give up root temporarily when it does not
need it, and to regain the privilege subsequently. This enables it to run with
a non-root effective uid most of the time, at very little cost, but offers less
security.

<LI>

<EM>setuid</EM>: Exim uses <EM>setuid()</EM> to give up root when it is receiving a locally
generated message, and after it has set up a listening socket when running as a
daemon. This means that, in order to deliver a message that it has received, it
has to re-invoke a fresh copy of itself to regain root privilege. During
delivery, it retains root except when actually transporting the message. In
particular, it runs the directors and routers as root. <EM>Setuid()</EM> is generally
reckoned to be more secure than <EM>seteuid()</EM> but running this way uses more
resources.

<LI>

<EM>setuid+seteuid</EM>: Exim uses <EM>setuid()</EM> as described immediately above, but in
addition, it uses <EM>seteuid()</EM> to give up root privilege temporarily when it
needs to regain it subsequently without losing a lot of state information, for
example, while running the directors and routers.
</UL>

<P>
On systems that do not support the <EM>seteuid()</EM> function, the only possible
value for the <EM>security</EM> option is `setuid', and this is the default on such
systems if an Exim user is defined. Otherwise the default is `setuid+seteuid'
-- the most secure setting.

</P>

<P>
<font color=green>


<H2><A NAME="SEC909" HREF="spec_toc.html#TOC909">55.2 Running Exim without privilege</A></H2>

<P>
<A NAME="IDX1995"></A>
<A NAME="IDX1996"></A>
Some installations require to run Exim in an unprivileged state almost all the
time, for added security. Support for this mode of operation is provided by the
setting

<PRE>
security = unprivileged
</PRE>

<P>
When this is done, all deliveries take place under the Exim user/group (which
must be defined), and there are restrictions on the features that can be used
in the configuration. There are two possibilities if you want to run Exim in
this way:

</P>

<UL>

<LI>

Keep it setuid to <EM>root</EM>, as in standard configurations. In this configuration,
except when starting the daemon, Exim gives up the root privilege and becomes
the Exim user/group as soon as it has started, using <EM>setuid()</EM> and <EM>setgid()</EM>.
This removes all privilege that might have been associated with the calling
user. In the case of the daemon, root privilege is retained until it has bound
its listening socket to the SMTP port, but then it gives it up in the same way.
The daemon can respond correctly to SIGHUP because the re-invocation regains
root privilege.

<LI>

Make Exim setuid/setgid to the Exim user and group. This means it cannot
start up the daemon unless it is called by a root process, and
consequently, the daemon cannot restart itself as a result of SIGHUP
because it is no longer a root process at that point. It is still useful
to set

<PRE>
security = unprivileged
</PRE>

in this case, because this setting stops Exim from trying to re-invoke itself
to do a delivery after a message has been received. Such a re-invocation is a
waste of time because it would have no effect.
</UL>

<P>
When using the second style (setuid to the Exim user), unless called by root
(in which case it behaves as first style), Exim is running with the real uid
and gid set to those of the calling process, and the effective uid/gid set to
Exim's values. Ideally, any association with the calling process' uid/gid
should be dropped, that is, the real uid/gid should be reset to the effective
values so as to discard any privileges that the caller may have. While some
operating systems have a function that permits this action for a non-root
effective uid, quite a number of them do not. Because of this lack of
standardization, Exim does not address this problem at this time. For this
reason, the first style is perhaps the better approach to take.

</P>
<P>
Because Exim no longer needs to re-exec itself when starting a delivery process
after receiving a message, using

<PRE>
security = unprivileged
</PRE>

<P>
is more efficient than either of

<PRE>
security = setuid
security = setuid+seteuid
</PRE>

<P>
However, to achieve this extra efficiency you have to submit to the following
restrictions:

</P>
<P>
You can deliver only as the Exim user/group. You should  explicitly use the
<EM>user</EM> and <EM>group</EM> options to override directors or transports that normally
deliver as the recipient. (This makes sure that configurations that work in
this mode function the same way in normal mode.) Any implicit or explicit
specification of another user causes an error.

</P>
<P>
Use of <TT>`.forward'</TT> files is severely restricted, such that it is usually
not worthwhile to include a <EM>forwardfile</EM> director in the configuration.

</P>
<P>
Users who wish to use <TT>`.forward'</TT> would have to make their home directory and
the file itself accessable to the Exim user. Pipe and append-to-file entries,
and their equivalents in Exim filters, cannot be used. While they could be
enabled in the Exim user's name, that would be insecure and not very useful.

</P>
<P>
Unless the user mailboxes are all owned by the Exim user (possible
in some POP3 or IMAP-only environments):

</P>

<UL>

<LI>

They must be owned by the Exim group and be writable by that group.
This implies you must set <EM>mode</EM> in the appendfile configuration,
as well as the mode of the mailbox files themselves.

<LI>

You must set <EM>no_check_owner</EM>, since most or all of the files will
not be owned by the Exim user.

<LI>

You must set <EM>file_must_exist</EM>, as Exim cannot set the owner correctly on a
newly created mailbox when unpriviledged. This also implies that new mailboxes
need to be created manually.
</UL>

<P>
There are no additional restrictions on message reception or external (SMTP)
delivery.
</font>

</P>



<H2><A NAME="SEC910" HREF="spec_toc.html#TOC910">55.3 Alternate configurations and macros</A></H2>

<P>
Exim can be run with an alternate configuration file by means of the -<EM>C</EM>
option, and macros for use in its configuration can be set on the command line
using the -<EM>D</EM> option. If the -<EM>C</EM> option specifies a file other than the one
whose name is built into the binary, or if there is any use of the -<EM>D</EM> option,
and the caller is not root or the Exim user, Exim immediately gives up its
privilege, and runs with the real and effective uid and gid set to those of the
caller.

</P>



<H2><A NAME="SEC911" HREF="spec_toc.html#TOC911">55.4 Reading forward files</A></H2>

<P>
<A NAME="IDX1997"></A>
When forward files are read from users' home directories and those home
directories are NFS mounted without root privilege, even a program running as
root cannot read a forward file that does not have world read access.

</P>
<P>
If the <EM>seteuid()</EM> function is being used as described in the previous section,
so that Exim is not root when running the directors, the <EM>forwardfile</EM>
director automatically uses <EM>seteuid()</EM> to become the local user when
attempting to read a <TT>`.forward'</TT> file in a user's home directory. If <EM>seteuid()</EM>
is not being used generally, but is available in the operating system, the
<EM>forwardfile</EM> director can be configured to make use of it when reading files
in home directories.

</P>
<P>
The <EM>forwardfile</EM> director does not necessarily have to read from users' home
directories as obtained from <EM>getpwnam()</EM>. It can be given a directory
explicitly, and a specific associated user and group. The above remarks are
applicable in this case also.

</P>
<P>
On systems that do not have <EM>seteuid()</EM>, the only way to support forward files
on NFS file systems that do not export root is to insist that the files be
world readable.

</P>
<P>
<A NAME="IDX1998"></A>
Forward files are permitted to contain :include: items unless forbidden by
setting <EM>forbid_include</EM> in the director. If <EM>seteuid()</EM> is being used to read
the forward file, any included files are read as the same user. Otherwise
Exim is running as root, and it insists that any included files are within the
same directory as the forward file, and that there are no
<A NAME="IDX1999"></A>
<A NAME="IDX2000"></A>
symbolic links below the directory. If no directory is specified (either
explicitly or by looking up a local user's home directory) then included files
are not permitted when <EM>seteuid()</EM> is not in use.

</P>
<P>
When the filtering option is enabled for forward files, users can construct
pipe commands that contain data from the incoming message by quoting variables
such as $<EM>sender_address</EM>. To prevent the contents of inserted data from
interfering with a command, the string expansion is done after the command
line is split up into separate arguments, and the command is run directly
instead of passing the command line to a shell.

</P>



<H2><A NAME="SEC912" HREF="spec_toc.html#TOC912">55.5 Delivering to local files</A></H2>

<P>
Full details of the checks applied by <EM>appendfile</EM> before it writes to a file
are given in chapter 15.

</P>



<H2><A NAME="SEC913" HREF="spec_toc.html#TOC913">55.6 IPv4 source routing</A></H2>

<P>
<A NAME="IDX2001"></A>
<A NAME="IDX2002"></A>
Many operating systems suppress IP source-routed packets in the kernel, but
some cannot be made to do this. Exim is configured by default to log incoming
IPv4 source-routed TCP calls, and then to drop the call. These actions can be
independently turned off. Alternatively, the IP options can be deleted instead
of dropping the call. Things are all different in IPv6. No special checking is
currently done.

</P>



<H2><A NAME="SEC914" HREF="spec_toc.html#TOC914">55.7 The VRFY, EXPN, and ETRN commands in SMTP</A></H2>

<P>
Support for these SMTP commands is disabled by default. The VRFY command
can be enabled by setting <EM>smtp_verify</EM>. The EXPN command can be enabled
for specific
hosts by setting <EM>smtp_expn_hosts</EM>,
and there is a similar option controlling ETRN.

</P>



<H2><A NAME="SEC915" HREF="spec_toc.html#TOC915">55.8 Privileged users</A></H2>

<P>
<A NAME="IDX2003"></A>
<A NAME="IDX2004"></A>
<A NAME="IDX2005"></A>
Exim recognises two sets of users with special privileges. Trusted users are
able to submit new messages to Exim locally, but supply their own sender
addresses and information about a sending host. For other users submitting
local messages, Exim sets up the sender address from the uid, and doesn't
permit a remote host to be specified.

</P>
<P>
However, an untrusted user is permitted to use the -<EM>f</EM> command line option in
the special form -<EM>f &#60;&#62;</EM> to indicate that a delivery failure for the message
should not cause an error report. This affects the message's envelope, but it
does not affect the <EM>Sender:</EM> header.

</P>
<P>
Trusted users are used to run processes that receive mail messages from some
other mail domain and pass them on to Exim for delivery either locally, or over
the Internet. Exim trusts a caller that is running as root, as the Exim user (if
defined), as any user listed in the <EM>trusted_users</EM> configuration option, or
under any group listed in the <EM>trusted_groups</EM> option.

</P>
<P>
Admin users are permitted to do things to the messages on Exim's queue. They
can freeze or thaw messages, cause them to be returned to their senders, remove
them entirely, or modify them in various ways. In addition, admin users can run
the Exim monitor and see all the information it is capable of providing, which
includes the contents of files on the spool.

</P>
<P>
By default, the use of the -<EM>M</EM> and -<EM>q</EM> options to cause Exim to attempt
delivery of messages on its queue is restricted to admin users. However, this
restriction can be relaxed by setting the <EM>no_prod_requires_admin</EM> option.

</P>

<P>
Exim recognises an admin user if the calling process is running as root or as
the Exim user (if defined) or if any of the groups associated with the calling
process is the Exim group (if defined). It is not necessary actually to be
running under the Exim group. However, if admin users who are not root or exim
are to access the contents of files on the spool via the Exim monitor (which
runs unprivileged), Exim must be built to allow group read access to its spool
files.

</P>



<H2><A NAME="SEC916" HREF="spec_toc.html#TOC916">55.9 Spool files</A></H2>

<P>
<A NAME="IDX2006"></A>
<A NAME="IDX2007"></A>
<A NAME="IDX2008"></A>
If a uid and gid are defined for Exim, the spool directory and everything
it contains will be owned by exim and have its group set to exim. The
mode for spool files is defined in the <TT>`Local/Makefile'</TT> configuration file, and
defaults to 0600. This should normally be changed to 0640 if a uid and gid are
defined for Exim, to allow access to spool files via the Exim monitor by other
members of the exim group.

</P>



<H2><A NAME="SEC917" HREF="spec_toc.html#TOC917">55.10 Use of argv[0]</A></H2>

<P>
Exim examines the last component of <EM>argv[0]</EM>, and if it matches one of a set
of specific strings, Exim assumes certain options. For example, calling Exim
with the last component of <EM>argv[0]</EM> set to `rsmtp' is exactly equivalent to
calling it with the option -<EM>bS</EM>. There are no security implications in this.

</P>



<H2><A NAME="SEC918" HREF="spec_toc.html#TOC918">55.11 Use of %f formatting</A></H2>

<P>
The only use made of `%f' by Exim is in formatting load average values. These
are actually stored in integer variables as 1000 times the load average.
Consequently, their range is limited and so therefore is the length of the
converted output.

</P>



<H2><A NAME="SEC919" HREF="spec_toc.html#TOC919">55.12 Embedded Exim path</A></H2>

<P>
Exim uses its own path name, which is embedded in the code, only when it needs
to re-exec in order to regain root privilege. Therefore it is not root when it
does so. If some bug allowed the path to get overwritten, it would lead to an
arbitrary program's being run as exim, not as root. If there's still paranoia
about this, two separate copies of the name could be kept, or a checksum could
be applied to the global data.

</P>



<H2><A NAME="SEC920" HREF="spec_toc.html#TOC920">55.13 Use of sprintf()</A></H2>

<P>
<A NAME="IDX2009"></A>
A large number of occurrences of `sprintf' in the code are actually calls to
<EM>string_sprintf()</EM>, a function which returns the result in malloc'd store. The
intermediate formatting is done into a large fixed buffer by a function that
runs through the format string itself, and checks the length of each conversion
before performing it, thus preventing buffer overruns.

</P>
<P>
The remaining uses of <EM>sprintf()</EM> happen in controlled circumstances where the
output buffer is known to be sufficiently long to contain the converted string.

</P>



<H2><A NAME="SEC921" HREF="spec_toc.html#TOC921">55.14 Use of debug_printf() and log_write()</A></H2>

<P>
Arbitrary strings are passed to both these functions, but they do their
formatting by calling the function <EM>string_vformat()</EM>, which runs through the
format string itself, and checks the length of each conversion.

</P>



<H2><A NAME="SEC922" HREF="spec_toc.html#TOC922">55.15 Use of strcat() and strcpy()</A></H2>

<P>
These are used only in cases where the output buffer is known to be large
enough to hold the result.

</P>

<P><HR><P>
Go to the <A HREF="spec_1.html">first</A>, <A HREF="spec_54.html">previous</A>, <A HREF="spec_56.html">next</A>, <A HREF="spec_59.html">last</A> section, <A HREF="spec_toc.html">table of contents</A>.
</BODY>
</HTML>