|
Lines 177-182
Link Here
|
| 177 |
int nread; |
177 |
int nread; |
| 178 |
WAITTYPE status; |
178 |
WAITTYPE status; |
| 179 |
int c, preserve_mail = 0; |
179 |
int c, preserve_mail = 0; |
|
|
180 |
uid_t real_gid, priv_gid; |
| 181 |
|
| 182 |
real_gid = getgid(); |
| 183 |
priv_gid = getegid(); |
| 180 |
|
184 |
|
| 181 |
#ifndef MAIL_USE_SYSTEM_LOCK |
185 |
#ifndef MAIL_USE_SYSTEM_LOCK |
| 182 |
struct stat st; |
186 |
struct stat st; |
|
Lines 248-272
Link Here
|
| 248 |
if (*outname == 0) |
252 |
if (*outname == 0) |
| 249 |
fatal ("Destination file name is empty", 0, 0); |
253 |
fatal ("Destination file name is empty", 0, 0); |
| 250 |
|
254 |
|
| 251 |
/* Check access to output file. */ |
|
|
| 252 |
if (access (outname, F_OK) == 0 && access (outname, W_OK) != 0) |
| 253 |
pfatal_with_name (outname); |
| 254 |
|
| 255 |
/* Also check that outname's directory is writable to the real uid. */ |
| 256 |
{ |
| 257 |
char *buf = (char *) xmalloc (strlen (outname) + 1); |
| 258 |
char *p; |
| 259 |
strcpy (buf, outname); |
| 260 |
p = buf + strlen (buf); |
| 261 |
while (p > buf && !IS_DIRECTORY_SEP (p[-1])) |
| 262 |
*--p = 0; |
| 263 |
if (p == buf) |
| 264 |
*p++ = '.'; |
| 265 |
if (access (buf, W_OK) != 0) |
| 266 |
pfatal_with_name (buf); |
| 267 |
free (buf); |
| 268 |
} |
| 269 |
|
| 270 |
#ifdef MAIL_USE_POP |
255 |
#ifdef MAIL_USE_POP |
| 271 |
if (!strncmp (inname, "po:", 3)) |
256 |
if (!strncmp (inname, "po:", 3)) |
| 272 |
{ |
257 |
{ |
|
Lines 278-292
Link Here
|
| 278 |
exit (status); |
263 |
exit (status); |
| 279 |
} |
264 |
} |
| 280 |
|
265 |
|
| 281 |
setuid (getuid ()); |
266 |
if ( setuid (getuid ()) < 0 ) |
|
|
267 |
fatal ("Failed to drop privileges", 0, 0); |
| 268 |
|
| 282 |
#endif /* MAIL_USE_POP */ |
269 |
#endif /* MAIL_USE_POP */ |
| 283 |
|
270 |
|
| 284 |
#ifndef DISABLE_DIRECT_ACCESS |
271 |
#ifndef DISABLE_DIRECT_ACCESS |
| 285 |
|
|
|
| 286 |
/* Check access to input file. */ |
| 287 |
if (access (inname, R_OK | W_OK) != 0) |
| 288 |
pfatal_with_name (inname); |
| 289 |
|
| 290 |
#ifndef MAIL_USE_MMDF |
272 |
#ifndef MAIL_USE_MMDF |
| 291 |
#ifndef MAIL_USE_SYSTEM_LOCK |
273 |
#ifndef MAIL_USE_SYSTEM_LOCK |
| 292 |
#ifdef MAIL_USE_MAILLOCK |
274 |
#ifdef MAIL_USE_MAILLOCK |
|
Lines 373-379
Link Here
|
| 373 |
long touched_lock, now; |
355 |
long touched_lock, now; |
| 374 |
#endif |
356 |
#endif |
| 375 |
|
357 |
|
| 376 |
setuid (getuid ()); |
358 |
if ( setuid (getuid ()) < 0 || setegid (real_gid) < 0 ) |
|
|
359 |
fatal("Failed to drop privileges", 0, 0); |
| 377 |
|
360 |
|
| 378 |
#ifndef MAIL_USE_MMDF |
361 |
#ifndef MAIL_USE_MMDF |
| 379 |
#ifdef MAIL_USE_SYSTEM_LOCK |
362 |
#ifdef MAIL_USE_SYSTEM_LOCK |
|
Lines 399-404
Link Here
|
| 399 |
if (outdesc < 0) |
382 |
if (outdesc < 0) |
| 400 |
pfatal_with_name (outname); |
383 |
pfatal_with_name (outname); |
| 401 |
|
384 |
|
|
|
385 |
if ( setegid(priv_gid) < 0 ) |
| 386 |
fatal("Failed to regain privileges", 0, 0); |
| 387 |
|
| 402 |
/* This label exists so we can retry locking |
388 |
/* This label exists so we can retry locking |
| 403 |
after a delay, if it got EAGAIN or EBUSY. */ |
389 |
after a delay, if it got EAGAIN or EBUSY. */ |
| 404 |
retry_lock: |
390 |
retry_lock: |
|
Lines 499-504
Link Here
|
| 499 |
/* Check to make sure no errors before we zap the inbox. */ |
485 |
/* Check to make sure no errors before we zap the inbox. */ |
| 500 |
if (close (outdesc) != 0) |
486 |
if (close (outdesc) != 0) |
| 501 |
pfatal_and_delete (outname); |
487 |
pfatal_and_delete (outname); |
|
|
488 |
|
| 489 |
/* Prevent symlink attacks truncating other users' mailboxes */ |
| 490 |
if ( setegid (real_gid) < 0 ) |
| 491 |
fatal("Failed to drop privileges", 0, 0); |
| 502 |
|
492 |
|
| 503 |
#ifdef MAIL_USE_SYSTEM_LOCK |
493 |
#ifdef MAIL_USE_SYSTEM_LOCK |
| 504 |
if (! preserve_mail) |
494 |
if (! preserve_mail) |
|
Lines 506-512
Link Here
|
| 506 |
#if defined (STRIDE) || defined (XENIX) |
496 |
#if defined (STRIDE) || defined (XENIX) |
| 507 |
/* Stride, xenix have file locking, but no ftruncate. |
497 |
/* Stride, xenix have file locking, but no ftruncate. |
| 508 |
This mess will do. */ |
498 |
This mess will do. */ |
| 509 |
close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666)); |
499 |
int indesc2 = open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666); |
|
|
500 |
if ( indesc2 < 0 ) |
| 501 |
pfatal_with_name (inname) |
| 502 |
|
| 503 |
close (indesc2); |
| 504 |
|
| 510 |
#else |
505 |
#else |
| 511 |
ftruncate (indesc, 0L); |
506 |
ftruncate (indesc, 0L); |
| 512 |
#endif /* STRIDE or XENIX */ |
507 |
#endif /* STRIDE or XENIX */ |
|
Lines 532-537
Link Here
|
| 532 |
creat (inname, 0600); |
527 |
creat (inname, 0600); |
| 533 |
} |
528 |
} |
| 534 |
#endif /* not MAIL_USE_SYSTEM_LOCK */ |
529 |
#endif /* not MAIL_USE_SYSTEM_LOCK */ |
|
|
530 |
|
| 531 |
/* End of mailbox truncation */ |
| 532 |
if ( setegid(priv_gid) < 0 ) |
| 533 |
fatal("Failed to regain privileges", 0, 0); |
| 535 |
|
534 |
|
| 536 |
#ifdef MAIL_USE_MAILLOCK |
535 |
#ifdef MAIL_USE_MAILLOCK |
| 537 |
/* This has to occur in the child, i.e., in the process that |
536 |
/* This has to occur in the child, i.e., in the process that |