2 * Copyright (c) 1998-2000 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.
15 static char id[] = "@(#)$Id: safefile.c,v 8.81.4.7 2000/09/01 21:09:23 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 + 1];
64 dprintf("safefile(%s, uid=%d, gid=%d, flags=%lx, mode=%o):\n",
65 fn, (int) uid, (int) gid, flags, mode);
69 if (strlcpy(fbuf, fn, sizeof fbuf) >= sizeof fbuf)
72 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 setuid, 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 dprintf("\t%s\n", 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 dprintf("\t%s\n", 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;
209 if (stbuf.st_uid == uid)
212 else if (uid == 0 && stbuf.st_uid == TrustedUid)
218 if (stbuf.st_gid == gid)
221 # ifndef NO_GROUP_SET
222 else if (user != NULL && !DontInitGroups &&
224 gr->gr_gid == stbuf.st_gid) ||
225 (gr = getgrgid(stbuf.st_gid)) != NULL))
229 for (gp = gr->gr_mem; *gp != NULL; gp++)
230 if (strcmp(*gp, user) == 0)
235 # endif /* ! NO_GROUP_SET */
239 if ((stbuf.st_mode & md) != md)
244 dprintf("\t[final dir %s uid %d mode %lo] %s\n",
245 dir, (int) stbuf.st_uid, (u_long) stbuf.st_mode,
249 st->st_mode = ST_MODE_NOFILE;
254 if (bitset(SFF_NOSLINK, flags) && S_ISLNK(st->st_mode))
257 dprintf("\t[slink mode %lo]\tE_SM_NOSLINK\n",
258 (u_long) st->st_mode);
261 # endif /* S_ISLNK */
262 if (bitset(SFF_REGONLY, flags) && !S_ISREG(st->st_mode))
265 dprintf("\t[non-reg mode %lo]\tE_SM_REGONLY\n",
266 (u_long) st->st_mode);
269 if (bitset(SFF_NOGWFILES, flags) &&
270 bitset(S_IWGRP, st->st_mode))
273 dprintf("\t[write bits %lo]\tE_SM_GWFILE\n",
274 (u_long) st->st_mode);
277 if (bitset(SFF_NOWWFILES, flags) &&
278 bitset(S_IWOTH, st->st_mode))
281 dprintf("\t[write bits %lo]\tE_SM_WWFILE\n",
282 (u_long) st->st_mode);
285 if (bitset(SFF_NOGRFILES, flags) && bitset(S_IRGRP, st->st_mode))
288 dprintf("\t[read bits %lo]\tE_SM_GRFILE\n",
289 (u_long) st->st_mode);
292 if (bitset(SFF_NOWRFILES, flags) && bitset(S_IROTH, st->st_mode))
295 dprintf("\t[read bits %lo]\tE_SM_WRFILE\n",
296 (u_long) st->st_mode);
299 if (!bitset(SFF_EXECOK, flags) &&
300 bitset(S_IWUSR|S_IWGRP|S_IWOTH, mode) &&
301 bitset(S_IXUSR|S_IXGRP|S_IXOTH, st->st_mode))
304 dprintf("\t[exec bits %lo]\tE_SM_ISEXEC]\n",
305 (u_long) st->st_mode);
308 if (bitset(SFF_NOHLINK, flags) && st->st_nlink != 1)
311 dprintf("\t[link count %d]\tE_SM_NOHLINK\n",
316 if (uid == 0 && bitset(SFF_OPENASROOT, flags))
319 else if (uid == 0 && !bitset(SFF_ROOTOK, flags))
321 else if (st->st_uid == uid)
324 else if (uid == 0 && st->st_uid == TrustedUid)
330 if (st->st_gid == gid)
333 # ifndef NO_GROUP_SET
334 else if (user != NULL && !DontInitGroups &&
335 ((gr != NULL && gr->gr_gid == st->st_gid) ||
336 (gr = getgrgid(st->st_gid)) != NULL))
340 for (gp = gr->gr_mem; *gp != NULL; gp++)
341 if (strcmp(*gp, user) == 0)
346 # endif /* ! NO_GROUP_SET */
351 dprintf("\t[uid %d, nlink %d, stat %lo, mode %lo] ",
352 (int) st->st_uid, (int) st->st_nlink,
353 (u_long) st->st_mode, (u_long) mode);
354 if ((st->st_uid == uid || st->st_uid == 0 ||
355 st->st_uid == TrustedUid ||
356 !bitset(SFF_MUSTOWN, flags)) &&
357 (st->st_mode & mode) == mode)
364 dprintf("\tEACCES\n");
368 ** SAFEDIRPATH -- check to make sure a path to a directory is safe
370 ** Safe means not writable and owned by the right folks.
373 ** fn -- filename to check.
374 ** uid -- user id to compare against.
375 ** gid -- group id to compare against.
376 ** user -- user name to compare against (used for group
378 ** flags -- modifiers:
379 ** SFF_ROOTOK -- ok to use root permissions to open.
380 ** SFF_SAFEDIRPATH -- writable directories are considered
381 ** to be fatal errors.
382 ** level -- symlink recursive level.
383 ** offset -- offset into fn to start checking from.
386 ** 0 -- if the directory path is "safe".
387 ** else -- an error number associated with the path.
391 safedirpath(fn, uid, gid, user, flags, level, offset)
403 char *saveptr = NULL;
405 register struct group *gr = NULL;
406 char s[MAXLINKPATHLEN + 1];
409 /* make sure we aren't in a symlink loop */
410 if (level > MAXSYMLINKS)
413 /* special case root directory */
418 dprintf("safedirpath(%s, uid=%ld, gid=%ld, flags=%lx, level=%d, offset=%d):\n",
419 fn, (long) uid, (long) gid, flags, level, offset);
421 if (!bitnset(DBS_GROUPWRITABLEDIRPATHSAFE, DontBlameSendmail))
424 /* Make a modifiable copy of the filename */
425 if (strlcpy(s, fn, sizeof s) >= sizeof s)
431 /* put back character */
444 /* Special case for root directory */
458 /* Heuristic: . and .. have already been checked */
459 enddir = strrchr(s, '/');
460 if (enddir != NULL &&
461 (strcmp(enddir, "/..") == 0 ||
462 strcmp(enddir, "/.") == 0))
466 dprintf("\t[dir %s]\n", s);
469 ret = lstat(s, &stbuf);
470 # else /* HASLSTAT */
471 ret = stat(s, &stbuf);
472 # endif /* HASLSTAT */
480 /* Follow symlinks */
481 if (S_ISLNK(stbuf.st_mode))
484 char buf[MAXPATHLEN + 1];
486 memset(buf, '\0', sizeof buf);
487 if (readlink(s, buf, sizeof buf) < 0)
498 /* If path is the same, avoid rechecks */
499 while (s[offset] == buf[offset] &&
503 if (s[offset] == '\0' && buf[offset] == '\0')
505 /* strings match, symlink loop */
509 /* back off from the mismatch */
513 /* Make sure we are at a directory break */
518 while (buf[offset] != '/' &&
526 /* Include the trailing slash */
533 char fullbuf[MAXLINKPATHLEN + 1];
535 sptr = strrchr(s, '/');
539 offset = sptr + 1 - s;
541 strlen(buf) + 1) > sizeof fullbuf)
546 snprintf(fullbuf, sizeof fullbuf,
552 if (strlen(buf) + 1 > sizeof fullbuf)
557 (void) strlcpy(fullbuf, buf,
562 ret = safedirpath(target, uid, gid, user, flags,
567 /* Don't check permissions on the link file itself */
572 if ((uid == 0 || bitset(SFF_SAFEDIRPATH, flags)) &&
574 !(bitnset(DBS_TRUSTSTICKYBIT, DontBlameSendmail) &&
575 bitset(S_ISVTX, stbuf.st_mode)) &&
577 bitset(mode, stbuf.st_mode))
580 dprintf("\t[dir %s] mode %lo ",
581 s, (u_long) stbuf.st_mode);
582 if (bitset(SFF_SAFEDIRPATH, flags))
584 if (bitset(S_IWOTH, stbuf.st_mode))
593 dprintf("WARNING\n");
595 message("051 WARNING: %s writable directory %s",
596 bitset(S_IWOTH, stbuf.st_mode)
601 if (uid == 0 && !bitset(SFF_ROOTOK|SFF_OPENASROOT, flags))
603 if (bitset(S_IXOTH, stbuf.st_mode))
610 ** Let OS determine access to file if we are not
611 ** running as a privileged user. This allows ACLs
612 ** to work. Also, if opening as root, assume we can
613 ** scan the directory.
615 if (geteuid() != 0 || bitset(SFF_OPENASROOT, flags))
618 if (stbuf.st_uid == uid &&
619 bitset(S_IXUSR, stbuf.st_mode))
621 if (stbuf.st_gid == gid &&
622 bitset(S_IXGRP, stbuf.st_mode))
624 # ifndef NO_GROUP_SET
625 if (user != NULL && !DontInitGroups &&
626 ((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
627 (gr = getgrgid(stbuf.st_gid)) != NULL))
631 for (gp = gr->gr_mem; gp != NULL && *gp != NULL; gp++)
632 if (strcmp(*gp, user) == 0)
634 if (gp != NULL && *gp != NULL &&
635 bitset(S_IXGRP, stbuf.st_mode))
638 # endif /* ! NO_GROUP_SET */
639 if (!bitset(S_IXOTH, stbuf.st_mode))
646 dprintf("\t[dir %s] %s\n", fn,
647 ret == 0 ? "OK" : errstring(ret));
651 ** SAFEOPEN -- do a file open with extra checking
654 ** fn -- the file name to open.
655 ** omode -- the open-style mode flags.
656 ** cmode -- the create-style mode flags.
657 ** sff -- safefile flags.
664 # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
665 #endif /* ! O_ACCMODE */
668 safeopen(fn, omode, cmode, sff)
680 printf("safeopen: fn=%s, omode=%x, cmode=%x, sff=%lx\n",
681 fn, omode, cmode, sff);
683 if (bitset(O_CREAT, omode))
687 switch (omode & O_ACCMODE)
698 smode = S_IREAD|S_IWRITE;
705 if (bitset(SFF_OPENASROOT, sff))
706 rval = safefile(fn, RunAsUid, RunAsGid, RunAsUserName,
709 rval = safefile(fn, RealUid, RealGid, RealUserName,
716 if (stb.st_mode == ST_MODE_NOFILE && bitset(SFF_CREAT, sff))
717 omode |= O_CREAT | (bitset(SFF_NOTEXCL, sff) ? 0 : O_EXCL);
718 else if (bitset(SFF_CREAT, sff) && bitset(O_EXCL, omode))
720 /* The file exists so an exclusive create would fail */
725 fd = dfopen(fn, omode, cmode, sff);
728 if (filechanged(fn, fd, &stb))
730 syserr("554 5.3.0 cannot open: file %s changed after open", fn);
732 errno = E_SM_FILECHANGE;
738 ** SAFEFOPEN -- do a file open with extra checking
741 ** fn -- the file name to open.
742 ** omode -- the open-style mode flags.
743 ** cmode -- the create-style mode flags.
744 ** sff -- safefile flags.
751 safefopen(fn, omode, cmode, sff)
762 switch (omode & O_ACCMODE)
769 if (bitset(O_APPEND, omode))
776 if (bitset(O_TRUNC, omode))
778 else if (bitset(O_APPEND, omode))
785 syserr("554 5.3.5 safefopen: unknown omode %o", omode);
788 fd = safeopen(fn, omode, cmode, sff);
793 dprintf("safefopen: safeopen failed: %s\n",
798 fp = fdopen(fd, fmode);
805 dprintf("safefopen: fdopen(%s, %s) failed: omode=%x, sff=%lx, err=%s\n",
806 fn, fmode, omode, sff, errstring(errno));
813 ** FILECHANGED -- check to see if file changed after being opened
816 ** fn -- pathname of file to check.
817 ** fd -- file descriptor to check.
818 ** stb -- stat structure from before open.
821 ** TRUE -- if a problem was detected.
822 ** FALSE -- if this file is still the same.
826 filechanged(fn, fd, stb)
833 if (stb->st_mode == ST_MODE_NOFILE)
835 # if HASLSTAT && BOGUS_O_EXCL
836 /* only necessary if exclusive open follows symbolic links */
837 if (lstat(fn, stb) < 0 || stb->st_nlink != 1)
839 # else /* HASLSTAT && BOGUS_O_EXCL */
841 # endif /* HASLSTAT && BOGUS_O_EXCL */
843 if (fstat(fd, &sta) < 0)
846 if (sta.st_nlink != stb->st_nlink ||
847 sta.st_dev != stb->st_dev ||
848 sta.st_ino != stb->st_ino ||
849 # if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */
850 sta.st_gen != stb->st_gen ||
851 # endif /* HAS_ST_GEN && 0 */
852 sta.st_uid != stb->st_uid ||
853 sta.st_gid != stb->st_gid)
857 dprintf("File changed after opening:\n");
858 dprintf(" nlink = %ld/%ld\n",
859 (long) stb->st_nlink, (long) sta.st_nlink);
860 dprintf(" dev = %ld/%ld\n",
861 (long) stb->st_dev, (long) sta.st_dev);
862 if (sizeof sta.st_ino > sizeof (long))
864 dprintf(" ino = %s/",
865 quad_to_string(stb->st_ino));
867 quad_to_string(sta.st_ino));
870 dprintf(" ino = %lu/%lu\n",
871 (unsigned long) stb->st_ino,
872 (unsigned long) sta.st_ino);
874 dprintf(" gen = %ld/%ld\n",
875 (long) stb->st_gen, (long) sta.st_gen);
876 # endif /* HAS_ST_GEN */
877 dprintf(" uid = %ld/%ld\n",
878 (long) stb->st_uid, (long) sta.st_uid);
879 dprintf(" gid = %ld/%ld\n",
880 (long) stb->st_gid, (long) sta.st_gid);
888 ** DFOPEN -- determined file open
890 ** This routine has the semantics of open, except that it will
891 ** keep trying a few times to make this happen. The idea is that
892 ** on very loaded systems, we may run out of resources (inodes,
893 ** whatever), so this tries to get around it.
897 dfopen(filename, omode, cmode, sff)
907 for (tries = 0; tries < 10; tries++)
909 (void) sleep((unsigned) (10 * tries));
911 fd = open(filename, omode, cmode);
916 case ENFILE: /* system file table full */
917 case EINTR: /* interrupted syscall */
919 case ETXTBSY: /* Apollo: net file locked */
925 if (!bitset(SFF_NOLOCK, sff) &&
927 fstat(fd, &st) >= 0 &&
932 /* lock the file to avoid accidental conflicts */
933 if ((omode & O_ACCMODE) != O_RDONLY)
937 if (!lockfile(fd, filename, NULL, locktype))
939 int save_errno = errno;