2 * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
16 #include <sm/errstring.h>
18 SM_RCSID("@(#)$Id: safefile.c,v 8.128 2004/09/30 18:15:49 ca Exp $")
22 ** SAFEFILE -- return 0 if a file exists and is safe for a user.
25 ** fn -- filename to check.
26 ** uid -- user id to compare against.
27 ** gid -- group id to compare against.
28 ** user -- user name to compare against (used for group
30 ** flags -- modifiers:
31 ** SFF_MUSTOWN -- "uid" must own this file.
32 ** SFF_NOSLINK -- file cannot be a symbolic link.
33 ** mode -- mode bits that must match.
34 ** st -- if set, points to a stat structure that will
35 ** get the stat info for the file.
38 ** 0 if fn exists, is owned by uid, and matches mode.
39 ** An errno otherwise. The actual errno is cleared.
46 safefile(fn
, uid
, gid
, user
, flags
, mode
, st
)
56 register struct group
*gr
= NULL
;
61 char fbuf
[MAXPATHLEN
];
64 sm_dprintf("safefile(%s, uid=%d, gid=%d, flags=%lx, mode=%o):\n",
65 fn
, (int) uid
, (int) gid
, flags
, mode
);
67 if (sm_strlcpy(fbuf
, fn
, sizeof fbuf
) >= sizeof fbuf
)
70 sm_dprintf("\tpathname too long\n");
77 /* ignore SFF_SAFEDIRPATH if we are debugging */
78 if (RealUid
!= 0 && RunAsUid
== RealUid
)
79 flags
&= ~SFF_SAFEDIRPATH
;
81 /* first check to see if the file exists at all */
83 if ((bitset(SFF_NOSLINK
, flags
) ? lstat(fn
, st
)
87 # endif /* HASLSTAT */
91 else if (bitset(SFF_SETUIDOK
, flags
) &&
92 !bitset(S_IXUSR
|S_IXGRP
|S_IXOTH
, st
->st_mode
) &&
96 ** If final file is set-user-ID, run as the owner of that
97 ** file. Gotta be careful not to reveal anything too
101 # ifdef SUID_ROOT_FILES_OK
102 if (bitset(S_ISUID
, st
->st_mode
))
103 # else /* SUID_ROOT_FILES_OK */
104 if (bitset(S_ISUID
, st
->st_mode
) && st
->st_uid
!= 0 &&
105 st
->st_uid
!= TrustedUid
)
106 # endif /* SUID_ROOT_FILES_OK */
111 # ifdef SUID_ROOT_FILES_OK
112 if (bitset(S_ISGID
, st
->st_mode
))
113 # else /* SUID_ROOT_FILES_OK */
114 if (bitset(S_ISGID
, st
->st_mode
) && st
->st_gid
!= 0)
115 # endif /* SUID_ROOT_FILES_OK */
119 checkpath
= !bitset(SFF_NOPATHCHECK
, flags
) ||
120 (uid
== 0 && !bitset(SFF_ROOTOK
|SFF_OPENASROOT
, flags
));
121 if (bitset(SFF_NOWLINK
, flags
) && !bitset(SFF_SAFEDIRPATH
, flags
))
125 /* check the directory */
126 p
= strrchr(fn
, '/');
129 ret
= safedirpath(".", uid
, gid
, user
,
130 flags
|SFF_SAFEDIRPATH
, 0, 0);
135 ret
= safedirpath(fn
, uid
, gid
, user
,
136 flags
|SFF_SAFEDIRPATH
, 0, 0);
141 /* directory is safe */
147 /* Need lstat() information if called stat() before */
148 if (!bitset(SFF_NOSLINK
, flags
) && lstat(fn
, st
) < 0)
152 sm_dprintf("\t%s\n", sm_errstring(ret
));
155 # endif /* HASLSTAT */
156 /* directory is writable: disallow links */
165 p
= strrchr(fn
, '/');
168 ret
= safedirpath(".", uid
, gid
, user
, flags
, 0, 0);
173 ret
= safedirpath(fn
, uid
, gid
, user
, flags
, 0, 0);
181 ** If the target file doesn't exist, check the directory to
182 ** ensure that it is writable by this user.
187 int ret
= file_errno
;
191 sm_dprintf("\t%s\n", sm_errstring(ret
));
194 if (!bitset(SFF_CREAT
, flags
) || file_errno
!= ENOENT
)
197 /* check to see if legal to create the file */
198 p
= strrchr(dir
, '/');
205 if (stat(dir
, &stbuf
) >= 0)
207 int md
= S_IWRITE
|S_IEXEC
;
210 if (stbuf
.st_uid
== uid
)
213 else if (uid
== 0 && stbuf
.st_uid
== TrustedUid
)
219 if (stbuf
.st_gid
== gid
)
222 # ifndef NO_GROUP_SET
223 else if (user
!= NULL
&& !DontInitGroups
&&
225 gr
->gr_gid
== stbuf
.st_gid
) ||
226 (gr
= getgrgid(stbuf
.st_gid
)) != NULL
))
230 for (gp
= gr
->gr_mem
; *gp
!= NULL
; gp
++)
231 if (strcmp(*gp
, user
) == 0)
236 # endif /* ! NO_GROUP_SET */
240 if ((stbuf
.st_mode
& md
) != md
)
241 ret
= errno
= EACCES
;
246 sm_dprintf("\t[final dir %s uid %d mode %lo] %s\n",
247 dir
, (int) stbuf
.st_uid
,
248 (unsigned long) stbuf
.st_mode
,
252 st
->st_mode
= ST_MODE_NOFILE
;
257 if (bitset(SFF_NOSLINK
, flags
) && S_ISLNK(st
->st_mode
))
260 sm_dprintf("\t[slink mode %lo]\tE_SM_NOSLINK\n",
261 (unsigned long) st
->st_mode
);
264 # endif /* S_ISLNK */
265 if (bitset(SFF_REGONLY
, flags
) && !S_ISREG(st
->st_mode
))
268 sm_dprintf("\t[non-reg mode %lo]\tE_SM_REGONLY\n",
269 (unsigned long) st
->st_mode
);
272 if (bitset(SFF_NOGWFILES
, flags
) &&
273 bitset(S_IWGRP
, st
->st_mode
))
276 sm_dprintf("\t[write bits %lo]\tE_SM_GWFILE\n",
277 (unsigned long) st
->st_mode
);
280 if (bitset(SFF_NOWWFILES
, flags
) &&
281 bitset(S_IWOTH
, st
->st_mode
))
284 sm_dprintf("\t[write bits %lo]\tE_SM_WWFILE\n",
285 (unsigned long) st
->st_mode
);
288 if (bitset(SFF_NOGRFILES
, flags
) && bitset(S_IRGRP
, st
->st_mode
))
291 sm_dprintf("\t[read bits %lo]\tE_SM_GRFILE\n",
292 (unsigned long) st
->st_mode
);
295 if (bitset(SFF_NOWRFILES
, flags
) && bitset(S_IROTH
, st
->st_mode
))
298 sm_dprintf("\t[read bits %lo]\tE_SM_WRFILE\n",
299 (unsigned long) st
->st_mode
);
302 if (!bitset(SFF_EXECOK
, flags
) &&
303 bitset(S_IWUSR
|S_IWGRP
|S_IWOTH
, mode
) &&
304 bitset(S_IXUSR
|S_IXGRP
|S_IXOTH
, st
->st_mode
))
307 sm_dprintf("\t[exec bits %lo]\tE_SM_ISEXEC\n",
308 (unsigned long) st
->st_mode
);
311 if (bitset(SFF_NOHLINK
, flags
) && st
->st_nlink
!= 1)
314 sm_dprintf("\t[link count %d]\tE_SM_NOHLINK\n",
319 if (uid
== 0 && bitset(SFF_OPENASROOT
, flags
))
322 else if (uid
== 0 && !bitset(SFF_ROOTOK
, flags
))
324 else if (st
->st_uid
== uid
)
327 else if (uid
== 0 && st
->st_uid
== TrustedUid
)
333 if (st
->st_gid
== gid
)
336 # ifndef NO_GROUP_SET
337 else if (user
!= NULL
&& !DontInitGroups
&&
338 ((gr
!= NULL
&& gr
->gr_gid
== st
->st_gid
) ||
339 (gr
= getgrgid(st
->st_gid
)) != NULL
))
343 for (gp
= gr
->gr_mem
; *gp
!= NULL
; gp
++)
344 if (strcmp(*gp
, user
) == 0)
349 # endif /* ! NO_GROUP_SET */
354 sm_dprintf("\t[uid %d, nlink %d, stat %lo, mode %lo] ",
355 (int) st
->st_uid
, (int) st
->st_nlink
,
356 (unsigned long) st
->st_mode
, (unsigned long) mode
);
357 if ((st
->st_uid
== uid
|| st
->st_uid
== 0 ||
358 st
->st_uid
== TrustedUid
||
359 !bitset(SFF_MUSTOWN
, flags
)) &&
360 (st
->st_mode
& mode
) == mode
)
363 sm_dprintf("\tOK\n");
367 sm_dprintf("\tEACCES\n");
371 ** SAFEDIRPATH -- check to make sure a path to a directory is safe
373 ** Safe means not writable and owned by the right folks.
376 ** fn -- filename to check.
377 ** uid -- user id to compare against.
378 ** gid -- group id to compare against.
379 ** user -- user name to compare against (used for group
381 ** flags -- modifiers:
382 ** SFF_ROOTOK -- ok to use root permissions to open.
383 ** SFF_SAFEDIRPATH -- writable directories are considered
384 ** to be fatal errors.
385 ** level -- symlink recursive level.
386 ** offset -- offset into fn to start checking from.
389 ** 0 -- if the directory path is "safe".
390 ** else -- an error number associated with the path.
394 safedirpath(fn
, uid
, gid
, user
, flags
, level
, offset
)
406 char *saveptr
= NULL
;
408 register struct group
*gr
= NULL
;
409 char s
[MAXLINKPATHLEN
];
412 /* make sure we aren't in a symlink loop */
413 if (level
> MAXSYMLINKS
)
416 if (level
< 0 || offset
< 0 || offset
> strlen(fn
))
419 /* special case root directory */
424 sm_dprintf("safedirpath(%s, uid=%ld, gid=%ld, flags=%lx, level=%d, offset=%d):\n",
425 fn
, (long) uid
, (long) gid
, flags
, level
, offset
);
427 if (!bitnset(DBS_GROUPWRITABLEDIRPATHSAFE
, DontBlameSendmail
))
430 /* Make a modifiable copy of the filename */
431 if (sm_strlcpy(s
, fn
, sizeof s
) >= sizeof s
)
437 /* put back character */
450 /* Special case for root directory */
464 /* Heuristic: . and .. have already been checked */
465 enddir
= strrchr(s
, '/');
466 if (enddir
!= NULL
&&
467 (strcmp(enddir
, "/..") == 0 ||
468 strcmp(enddir
, "/.") == 0))
472 sm_dprintf("\t[dir %s]\n", s
);
475 ret
= lstat(s
, &stbuf
);
476 # else /* HASLSTAT */
477 ret
= stat(s
, &stbuf
);
478 # endif /* HASLSTAT */
486 /* Follow symlinks */
487 if (S_ISLNK(stbuf
.st_mode
))
491 char buf
[MAXPATHLEN
];
492 char fullbuf
[MAXLINKPATHLEN
];
494 memset(buf
, '\0', sizeof buf
);
495 linklen
= readlink(s
, buf
, sizeof buf
);
501 if (linklen
>= sizeof buf
)
503 /* file name too long for buffer */
504 ret
= errno
= EINVAL
;
513 /* If path is the same, avoid rechecks */
514 while (s
[offset
] == buf
[offset
] &&
518 if (s
[offset
] == '\0' && buf
[offset
] == '\0')
520 /* strings match, symlink loop */
524 /* back off from the mismatch */
528 /* Make sure we are at a directory break */
533 while (buf
[offset
] != '/' &&
541 /* Include the trailing slash */
549 sptr
= strrchr(s
, '/');
553 offset
= sptr
+ 1 - s
;
554 if (sm_strlcpyn(fullbuf
,
558 sm_strlcat(fullbuf
, buf
,
569 if (sm_strlcpy(fullbuf
, buf
,
579 ret
= safedirpath(target
, uid
, gid
, user
, flags
,
584 /* Don't check permissions on the link file itself */
589 if ((uid
== 0 || bitset(SFF_SAFEDIRPATH
, flags
)) &&
591 !(bitnset(DBS_TRUSTSTICKYBIT
, DontBlameSendmail
) &&
592 bitset(S_ISVTX
, stbuf
.st_mode
)) &&
594 bitset(mode
, stbuf
.st_mode
))
597 sm_dprintf("\t[dir %s] mode %lo ",
598 s
, (unsigned long) stbuf
.st_mode
);
599 if (bitset(SFF_SAFEDIRPATH
, flags
))
601 if (bitset(S_IWOTH
, stbuf
.st_mode
))
606 sm_dprintf("FATAL\n");
610 sm_dprintf("WARNING\n");
612 message("051 WARNING: %s writable directory %s",
613 bitset(S_IWOTH
, stbuf
.st_mode
)
618 if (uid
== 0 && !bitset(SFF_ROOTOK
|SFF_OPENASROOT
, flags
))
620 if (bitset(S_IXOTH
, stbuf
.st_mode
))
627 ** Let OS determine access to file if we are not
628 ** running as a privileged user. This allows ACLs
629 ** to work. Also, if opening as root, assume we can
630 ** scan the directory.
632 if (geteuid() != 0 || bitset(SFF_OPENASROOT
, flags
))
635 if (stbuf
.st_uid
== uid
&&
636 bitset(S_IXUSR
, stbuf
.st_mode
))
638 if (stbuf
.st_gid
== gid
&&
639 bitset(S_IXGRP
, stbuf
.st_mode
))
641 # ifndef NO_GROUP_SET
642 if (user
!= NULL
&& !DontInitGroups
&&
643 ((gr
!= NULL
&& gr
->gr_gid
== stbuf
.st_gid
) ||
644 (gr
= getgrgid(stbuf
.st_gid
)) != NULL
))
648 for (gp
= gr
->gr_mem
; gp
!= NULL
&& *gp
!= NULL
; gp
++)
649 if (strcmp(*gp
, user
) == 0)
651 if (gp
!= NULL
&& *gp
!= NULL
&&
652 bitset(S_IXGRP
, stbuf
.st_mode
))
655 # endif /* ! NO_GROUP_SET */
656 if (!bitset(S_IXOTH
, stbuf
.st_mode
))
663 sm_dprintf("\t[dir %s] %s\n", fn
,
664 ret
== 0 ? "OK" : sm_errstring(ret
));
668 ** SAFEOPEN -- do a file open with extra checking
671 ** fn -- the file name to open.
672 ** omode -- the open-style mode flags.
673 ** cmode -- the create-style mode flags.
674 ** sff -- safefile flags.
681 safeopen(fn
, omode
, cmode
, sff
)
689 #endif /* !NOFTRUNCATE */
696 sm_dprintf("safeopen: fn=%s, omode=%x, cmode=%x, sff=%lx\n",
697 fn
, omode
, cmode
, sff
);
699 if (bitset(O_CREAT
, omode
))
703 switch (omode
& O_ACCMODE
)
714 smode
= S_IREAD
|S_IWRITE
;
721 if (bitset(SFF_OPENASROOT
, sff
))
722 rval
= safefile(fn
, RunAsUid
, RunAsGid
, RunAsUserName
,
725 rval
= safefile(fn
, RealUid
, RealGid
, RealUserName
,
732 if (stb
.st_mode
== ST_MODE_NOFILE
&& bitset(SFF_CREAT
, sff
))
733 omode
|= O_CREAT
| (bitset(SFF_NOTEXCL
, sff
) ? 0 : O_EXCL
);
734 else if (bitset(SFF_CREAT
, sff
) && bitset(O_EXCL
, omode
))
736 /* The file exists so an exclusive create would fail */
742 truncate
= bitset(O_TRUNC
, omode
);
745 #endif /* !NOFTRUNCATE */
747 fd
= dfopen(fn
, omode
, cmode
, sff
);
750 if (filechanged(fn
, fd
, &stb
))
752 syserr("554 5.3.0 cannot open: file %s changed after open", fn
);
754 errno
= E_SM_FILECHANGE
;
760 ftruncate(fd
, (off_t
) 0) < 0)
765 syserr("554 5.3.0 cannot open: file %s could not be truncated",
771 #endif /* !NOFTRUNCATE */
776 ** SAFEFOPEN -- do a file open with extra checking
779 ** fn -- the file name to open.
780 ** omode -- the open-style mode flags.
781 ** cmode -- the create-style mode flags.
782 ** sff -- safefile flags.
789 safefopen(fn
, omode
, cmode
, sff
)
800 switch (omode
& O_ACCMODE
)
803 fmode
= SM_IO_RDONLY
;
807 if (bitset(O_APPEND
, omode
))
808 fmode
= SM_IO_APPEND
;
810 fmode
= SM_IO_WRONLY
;
814 if (bitset(O_TRUNC
, omode
))
815 fmode
= SM_IO_RDWRTR
;
816 else if (bitset(O_APPEND
, omode
))
817 fmode
= SM_IO_APPENDRW
;
823 syserr("554 5.3.5 safefopen: unknown omode %o", omode
);
826 fd
= safeopen(fn
, omode
, cmode
, sff
);
831 sm_dprintf("safefopen: safeopen failed: %s\n",
832 sm_errstring(errno
));
836 fp
= sm_io_open(SmFtStdiofd
, SM_TIME_DEFAULT
,
837 (void *) &fd
, fmode
, NULL
);
844 sm_dprintf("safefopen: fdopen(%s, %d) failed: omode=%x, sff=%lx, err=%s\n",
845 fn
, fmode
, omode
, sff
, sm_errstring(errno
));
852 ** FILECHANGED -- check to see if file changed after being opened
855 ** fn -- pathname of file to check.
856 ** fd -- file descriptor to check.
857 ** stb -- stat structure from before open.
860 ** true -- if a problem was detected.
861 ** false -- if this file is still the same.
865 filechanged(fn
, fd
, stb
)
872 if (stb
->st_mode
== ST_MODE_NOFILE
)
874 # if HASLSTAT && BOGUS_O_EXCL
875 /* only necessary if exclusive open follows symbolic links */
876 if (lstat(fn
, stb
) < 0 || stb
->st_nlink
!= 1)
878 # else /* HASLSTAT && BOGUS_O_EXCL */
880 # endif /* HASLSTAT && BOGUS_O_EXCL */
882 if (fstat(fd
, &sta
) < 0)
885 if (sta
.st_nlink
!= stb
->st_nlink
||
886 sta
.st_dev
!= stb
->st_dev
||
887 sta
.st_ino
!= stb
->st_ino
||
888 # if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */
889 sta
.st_gen
!= stb
->st_gen
||
890 # endif /* HAS_ST_GEN && 0 */
891 sta
.st_uid
!= stb
->st_uid
||
892 sta
.st_gid
!= stb
->st_gid
)
896 sm_dprintf("File changed after opening:\n");
897 sm_dprintf(" nlink = %ld/%ld\n",
898 (long) stb
->st_nlink
, (long) sta
.st_nlink
);
899 sm_dprintf(" dev = %ld/%ld\n",
900 (long) stb
->st_dev
, (long) sta
.st_dev
);
901 sm_dprintf(" ino = %llu/%llu\n",
902 (ULONGLONG_T
) stb
->st_ino
,
903 (ULONGLONG_T
) sta
.st_ino
);
905 sm_dprintf(" gen = %ld/%ld\n",
906 (long) stb
->st_gen
, (long) sta
.st_gen
);
907 # endif /* HAS_ST_GEN */
908 sm_dprintf(" uid = %ld/%ld\n",
909 (long) stb
->st_uid
, (long) sta
.st_uid
);
910 sm_dprintf(" gid = %ld/%ld\n",
911 (long) stb
->st_gid
, (long) sta
.st_gid
);
919 ** DFOPEN -- determined file open
921 ** This routine has the semantics of open, except that it will
922 ** keep trying a few times to make this happen. The idea is that
923 ** on very loaded systems, we may run out of resources (inodes,
924 ** whatever), so this tries to get around it.
928 dfopen(filename
, omode
, cmode
, sff
)
938 for (tries
= 0; tries
< 10; tries
++)
940 (void) sleep((unsigned) (10 * tries
));
942 fd
= open(filename
, omode
, cmode
);
947 case ENFILE
: /* system file table full */
948 case EINTR
: /* interrupted syscall */
950 case ETXTBSY
: /* Apollo: net file locked */
956 if (!bitset(SFF_NOLOCK
, sff
) &&
958 fstat(fd
, &st
) >= 0 &&
963 /* lock the file to avoid accidental conflicts */
964 if ((omode
& O_ACCMODE
) != O_RDONLY
)
968 if (bitset(SFF_NBLOCK
, sff
))
971 if (!lockfile(fd
, filename
, NULL
, locktype
))
973 int save_errno
= errno
;