summaryrefslogtreecommitdiffstats
path: root/fuse/mount_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'fuse/mount_util.c')
-rw-r--r--fuse/mount_util.c125
1 files changed, 56 insertions, 69 deletions
diff --git a/fuse/mount_util.c b/fuse/mount_util.c
index de1bd6714..bfd801fff 100644
--- a/fuse/mount_util.c
+++ b/fuse/mount_util.c
@@ -11,18 +11,22 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <mntent.h>
+#include <paths.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <sys/param.h>
-#include <paths.h>
-
+#ifdef __NetBSD__
+#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0)
+#define mtab_needs_update(mnt) 0
+#else
static int mtab_needs_update(const char *mnt)
{
int res;
@@ -45,19 +49,31 @@ static int mtab_needs_update(const char *mnt)
if (errno == ENOENT)
return 0;
} else {
+ uid_t ruid;
+ int err;
+
if (S_ISLNK(stbuf.st_mode))
return 0;
+ ruid = getuid();
+ if (ruid != 0)
+ setreuid(0, -1);
+
res = access(_PATH_MOUNTED, W_OK);
- if (res == -1 && errno == EROFS)
+ err = (res == -1) ? errno : 0;
+ if (ruid != 0)
+ setreuid(ruid, -1);
+
+ if (err == EROFS)
return 0;
}
return 1;
}
+#endif /* __NetBSD__ */
-static int add_mount_legacy(const char *progname, const char *fsname,
- const char *mnt, const char *type, const char *opts)
+static int add_mount(const char *progname, const char *fsname,
+ const char *mnt, const char *type, const char *opts)
{
int res;
int status;
@@ -78,31 +94,10 @@ static int add_mount_legacy(const char *progname, const char *fsname,
goto out_restore;
}
if (res == 0) {
- char templ[] = "/tmp/fusermountXXXXXX";
- char *tmp;
-
sigprocmask(SIG_SETMASK, &oldmask, NULL);
setuid(geteuid());
-
- /*
- * hide in a directory, where mount isn't able to resolve
- * fsname as a valid path
- */
- tmp = mkdtemp(templ);
- if (!tmp) {
- fprintf(stderr,
- "%s: failed to create temporary directory\n",
- progname);
- exit(1);
- }
- if (chdir(tmp)) {
- fprintf(stderr, "%s: failed to chdir to %s: %s\n",
- progname, tmp, strerror(errno));
- exit(1);
- }
- rmdir(tmp);
- execl("/bin/mount", "/bin/mount", "-i", "-f", "-t", type,
- "-o", opts, fsname, mnt, NULL);
+ execl("/bin/mount", "/bin/mount", "--no-canonicalize", "-i",
+ "-f", "-t", type, "-o", opts, fsname, mnt, NULL);
fprintf(stderr, "%s: failed to execute /bin/mount: %s\n",
progname, strerror(errno));
exit(1);
@@ -120,9 +115,17 @@ static int add_mount_legacy(const char *progname, const char *fsname,
return res;
}
-static int add_mount(const char *progname, const char *fsname,
+int fuse_mnt_add_mount(const char *progname, const char *fsname,
const char *mnt, const char *type, const char *opts)
{
+ if (!mtab_needs_update(mnt))
+ return 0;
+
+ return add_mount(progname, fsname, mnt, type, opts);
+}
+
+static int exec_umount(const char *progname, const char *rel_mnt, int lazy)
+{
int res;
int status;
sigset_t blockmask;
@@ -142,19 +145,11 @@ static int add_mount(const char *progname, const char *fsname,
goto out_restore;
}
if (res == 0) {
- /*
- * Hide output, because old versions don't support
- * --no-canonicalize
- */
- int fd = open("/dev/null", O_RDONLY);
- dup2(fd, 1);
- dup2(fd, 2);
-
sigprocmask(SIG_SETMASK, &oldmask, NULL);
setuid(geteuid());
- execl("/bin/mount", "/bin/mount", "--no-canonicalize", "-i",
- "-f", "-t", type, "-o", opts, fsname, mnt, NULL);
- fprintf(stderr, "%s: failed to execute /bin/mount: %s\n",
+ execl("/bin/umount", "/bin/umount", "-i", rel_mnt,
+ lazy ? "-l" : NULL, NULL);
+ fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
progname, strerror(errno));
exit(1);
}
@@ -162,31 +157,33 @@ static int add_mount(const char *progname, const char *fsname,
if (res == -1)
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
- if (status != 0)
+ if (status != 0) {
res = -1;
+ }
out_restore:
sigprocmask(SIG_SETMASK, &oldmask, NULL);
-
return res;
+
}
-int fuse_mnt_add_mount(const char *progname, const char *fsname,
- const char *mnt, const char *type, const char *opts)
+int fuse_mnt_umount(const char *progname, const char *abs_mnt,
+ const char *rel_mnt, int lazy)
{
int res;
- if (!mtab_needs_update(mnt))
- return 0;
-
- res = add_mount(progname, fsname, mnt, type, opts);
- if (res == -1)
- res = add_mount_legacy(progname, fsname, mnt, type, opts);
+ if (!mtab_needs_update(abs_mnt)) {
+ res = umount2(rel_mnt, lazy ? 2 : 0);
+ if (res == -1)
+ fprintf(stderr, "%s: failed to unmount %s: %s\n",
+ progname, abs_mnt, strerror(errno));
+ return res;
+ }
- return res;
+ return exec_umount(progname, rel_mnt, lazy);
}
-static int exec_umount(const char *progname, const char *rel_mnt, int lazy)
+static int remove_mount(const char *progname, const char *mnt)
{
int res;
int status;
@@ -209,8 +206,8 @@ static int exec_umount(const char *progname, const char *rel_mnt, int lazy)
if (res == 0) {
sigprocmask(SIG_SETMASK, &oldmask, NULL);
setuid(geteuid());
- execl("/bin/umount", "/bin/umount", "-i", rel_mnt,
- lazy ? "-l" : NULL, NULL);
+ execl("/bin/umount", "/bin/umount", "--no-canonicalize", "-i",
+ "--fake", mnt, NULL);
fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
progname, strerror(errno));
exit(1);
@@ -219,30 +216,20 @@ static int exec_umount(const char *progname, const char *rel_mnt, int lazy)
if (res == -1)
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
- if (status != 0) {
+ if (status != 0)
res = -1;
- }
out_restore:
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return res;
-
}
-int fuse_mnt_umount(const char *progname, const char *abs_mnt,
- const char *rel_mnt, int lazy)
+int fuse_mnt_remove_mount(const char *progname, const char *mnt)
{
- int res;
-
- if (!mtab_needs_update(abs_mnt)) {
- res = umount2(rel_mnt, lazy ? 2 : 0);
- if (res == -1)
- fprintf(stderr, "%s: failed to unmount %s: %s\n",
- progname, abs_mnt, strerror(errno));
- return res;
- }
+ if (!mtab_needs_update(mnt))
+ return 0;
- return exec_umount(progname, rel_mnt, lazy);
+ return remove_mount(progname, mnt);
}
char *fuse_mnt_resolve_path(const char *progname, const char *orig)