summaryrefslogtreecommitdiffstats
path: root/sbin/mksnap_ffs
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2003-11-04 07:04:01 +0000
committermckusick <mckusick@FreeBSD.org>2003-11-04 07:04:01 +0000
commit62316cd3c75adb18d0c06d927916dc6d2cc4c436 (patch)
treef6bfe3d437c05a336e51c9bf10634a75d8a7fc38 /sbin/mksnap_ffs
parentf8f0614f005da6850b4d7277d796a42e4023c7ba (diff)
downloadFreeBSD-src-62316cd3c75adb18d0c06d927916dc6d2cc4c436.zip
FreeBSD-src-62316cd3c75adb18d0c06d927916dc6d2cc4c436.tar.gz
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.
Diffstat (limited to 'sbin/mksnap_ffs')
-rw-r--r--sbin/mksnap_ffs/mksnap_ffs.c34
1 files changed, 33 insertions, 1 deletions
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 <errno.h>
#include <fcntl.h>
#include <grp.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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)
OpenPOWER on IntegriCloud