X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fnfsumount.c;h=e101105268d3bdd9bd42a49ca3649b3b17250383;hp=077219d6ae87e223669492c642e55bfc9d481b5e;hb=4bc447f758ee4d64706b990ac68cb766dbff113c;hpb=1e42be20a3283994d0ffd6c5f80c36fab5a887a8 diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c index 077219d..e101105 100644 --- a/utils/mount/nfsumount.c +++ b/utils/mount/nfsumount.c @@ -17,12 +17,14 @@ * */ +#include #include #include #include #include #include #include +#include #include "xcommon.h" #include "fstab.h" @@ -147,7 +149,7 @@ int del_mtab(const char *spec, const char *node) res = mount(spec, node, NULL, MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL); if (res == 0) { - nfs_mntent_t remnt; + struct mntent remnt; fprintf(stderr, _("umount: %s busy - remounted read-only\n"), spec); @@ -188,7 +190,7 @@ int del_mtab(const char *spec, const char *node) /* * Returns 1 if everything went well, else 0. */ -int _nfsumount(const char *spec, const char *opts) +int _nfsumount(const char *spec, char *opts) { char *hostname; char *dirname; @@ -250,7 +252,7 @@ int _nfsumount(const char *spec, const char *opts) goto out_bad; return nfs_call_umount(&mnt_server, &dirname); out_bad: - printf("%s: %s: not found or not mounted\n", progname, spec); + fprintf(stderr, "%s: %s: not found or not mounted\n", progname, spec); return 0; } @@ -311,6 +313,10 @@ int nfsumount(int argc, char *argv[]) return 0; } } + if (optind != argc) { + umount_usage(); + return 0; + } if (spec == NULL || (*spec != '/' && strchr(spec,':') == NULL)) { printf(_("umount: %s: not found\n"), spec); @@ -324,16 +330,53 @@ int nfsumount(int argc, char *argv[]) if (!mc && verbose) printf(_("Could not find %s in mtab\n"), spec); + if (mc && strcmp(mc->m.mnt_type, "nfs") != 0 && + strcmp(mc->m.mnt_type, "nfs4") != 0) { + fprintf(stderr, "umount.nfs: %s on %s it not an nfs filesystem\n", + mc->m.mnt_fsname, mc->m.mnt_dir); + exit(1); + } + + if (getuid() != 0) { + /* only permitted if "user=" or "users" is in mount options */ + if (!mc) { + only_root: + fprintf(stderr,"%s: You are not permitted to unmount %s\n", + progname, spec); + return 0; + } + if (hasmntopt(&mc->m, "users") == NULL) { + char *opt = hasmntopt(&mc->m, "user"); + struct passwd *pw; + char *comma; + int len; + if (!opt) + goto only_root; + if (opt[5] != '=') + goto only_root; + comma = strchr(opt, ','); + if (comma) + len = comma - (opt + 5); + else + len = strlen(opt+5); + pw = getpwuid(getuid()); + if (pw == NULL || strlen(pw->pw_name) != len + || strncmp(pw->pw_name, opt+5, len) != 0) + goto only_root; + } + } + + ret = 0; if (mc) { - ret = _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts); + if (!lazy) + ret = _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts); if(ret) ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir); - } else { - if (*spec != '/') + } else if (*spec != '/') { + if (!lazy) ret = _nfsumount(spec, "tcp,v3"); - else - ret = del_mtab(NULL, spec); - } + } else + ret = del_mtab(NULL, spec); return(ret); }