From 62316cd3c75adb18d0c06d927916dc6d2cc4c436 Mon Sep 17 00:00:00 2001 From: mckusick Date: Tue, 4 Nov 2003 07:04:01 +0000 Subject: Check that the user running mksnap_ffs has permission to create and remove a snapshot file from the directory in which they have requested to have it made. If they do not have write permission in the directory or the directory is sticky and not owned by the user, then they will not be able to remove the snapshot when they are done with it. --- sbin/mksnap_ffs/mksnap_ffs.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/sbin/mksnap_ffs/mksnap_ffs.c b/sbin/mksnap_ffs/mksnap_ffs.c index 58e73dc..13186b4 100644 --- a/sbin/mksnap_ffs/mksnap_ffs.c +++ b/sbin/mksnap_ffs/mksnap_ffs.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,7 @@ void usage(void); int main(int argc, char **argv) { - const char *dir; + char *dir, *cp, path[PATH_MAX]; struct ufs_args args; struct group *grp; struct stat stbuf; @@ -66,6 +67,37 @@ main(int argc, char **argv) dir = argv[1]; args.fspec = argv[2]; + /* + * Check that the user running this program has permission + * to create and remove a snapshot file from the directory + * in which they have requested to have it made. If the + * directory is sticky and not owned by the user, then they + * will not be able to remove the snapshot when they are + * done with it. + */ + if (strlen(args.fspec) >= PATH_MAX) + errx(1, "pathname too long %s", args.fspec); + cp = strrchr(args.fspec, '/'); + if (cp == NULL) { + strlcpy(path, ".", PATH_MAX); + } else if (cp == args.fspec) { + strlcpy(path, "/", PATH_MAX); + } else { + strlcpy(path, args.fspec, cp - args.fspec + 1); + } + if (stat(path, &stbuf) < 0) + err(1, "%s", path); + if (!S_ISDIR(stbuf.st_mode)) + errx(1, "%s: Not a directory", path); + if (access(path, W_OK) < 0) + err(1, "Lack write permission in %s", path); + if ((stbuf.st_mode & S_ISTXT) && stbuf.st_uid != getuid()) + errx(1, "Lack write permission in %s: Sticky bit set", path); + + /* + * Having verified access to the directory in which the + * snapshot is to be built, proceed with creating it. + */ if ((grp = getgrnam("operator")) == NULL) errx(1, "Cannot retrieve operator gid"); if (mount("ffs", dir, MNT_UPDATE | MNT_SNAPSHOT, &args) < 0) -- cgit v1.1