]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: better "user" evaluation
authorKarel Zak <kzak@redhat.com>
Tue, 22 Feb 2011 23:21:54 +0000 (00:21 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 22 Feb 2011 23:21:54 +0000 (00:21 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/mount/src/context.c
shlibs/mount/src/context_mount.c
shlibs/mount/src/optstr.c

index f8db3cfd674b0869661507545afdd6a0dd12a238..0b1f70ef3bed8dda7924a6ac836eb6dc32d2f356 100644 (file)
@@ -861,7 +861,7 @@ int mnt_context_get_mflags(struct libmnt_context *cxt, unsigned long *flags)
 
        *flags = 0;
        if (!(cxt->flags & MNT_FL_MOUNTFLAGS_MERGED) && cxt->fs) {
-               const char *o = mnt_fs_get_vfs_options(cxt->fs);
+               const char *o = mnt_fs_get_options(cxt->fs);
                if (o)
                        rc = mnt_optstr_get_flags(o, flags,
                                    mnt_get_builtin_optmap(MNT_LINUX_MAP));
@@ -1665,11 +1665,50 @@ err:
        return rc;
 }
 
+int test_flags(struct libmnt_test *ts, int argc, char *argv[])
+{
+       int idx = 1, rc = 0;
+       struct libmnt_context *cxt;
+       const char *opt = NULL;
+       unsigned long flags = 0;
+
+       if (argc < 2)
+               return -EINVAL;
+
+       cxt = mnt_new_context();
+       if (!cxt)
+               return -ENOMEM;
+
+       if (!strcmp(argv[idx], "-o")) {
+               mnt_context_set_options(cxt, argv[idx + 1]);
+               idx += 2;
+       }
+
+       if (argc == idx + 1)
+               /* mount <mountpont>|<device> */
+               mnt_context_set_target(cxt, argv[idx++]);
+
+       rc = mnt_context_prepare_mount(cxt);
+       if (rc)
+               printf("failed to prepare mount %s\n", strerror(-rc));
+
+       opt = mnt_fs_get_options(cxt->fs);
+       if (opt)
+               fprintf(stdout, "options: %s\n", opt);
+
+       mnt_context_get_mflags(cxt, &flags);
+       fprintf(stdout, "flags: %08lx\n", flags);
+
+       mnt_free_context(cxt);
+       return rc;
+}
+
 int main(int argc, char *argv[])
 {
        struct libmnt_test tss[] = {
        { "--mount",  test_mount,  "[-o <opts>] [-t <type>] <spec>|<src> <target>" },
        { "--umount", test_umount, "[-t <type>] [-f][-l][-r] <src>|<target>" },
+       { "--flags", test_flags,   "[-o <opts>] <spec>" },
        { NULL }};
 
 
index 647e2614937162ad97c42f19f5afe95ac1a143c3..5b9c0b19559e49429756aa2ed95a601e7f7ef050 100644 (file)
@@ -185,11 +185,10 @@ static int evaluate_permissions(struct libmnt_context *cxt)
                        return -EPERM;
                }
 
-               if (u_flags & (MNT_MS_OWNER | MNT_MS_GROUP))
-                       cxt->mountflags |= MS_OWNERSECURE;
-
-               if (u_flags & (MNT_MS_USER | MNT_MS_USERS))
-                       cxt->mountflags |= MS_SECURE;
+               /*
+                * Note that MS_OWNERSECURE and MS_SECURE mount options
+                * are applied by mnt_optstr_get_flags() from mnt_context_merge_mflags()
+                */
 
                srcpath = mnt_fs_get_srcpath(cxt->fs);
                if (!srcpath)
index fd4a8610c58603e698a6ff971740b4d8c844f912..92abcdb1a150d517828b872517794b8ac1b61a8f 100644 (file)
@@ -585,27 +585,49 @@ int mnt_optstr_get_options(const char *optstr, char **subset,
 int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
                const struct libmnt_optmap *map)
 {
-       struct libmnt_optmap const *maps[1];
+       struct libmnt_optmap const *maps[2];
        char *name, *str = (char *) optstr;
        size_t namesz = 0;
+       int nmaps = 0;
 
        assert(optstr);
 
        if (!optstr || !flags || !map)
                return -EINVAL;
 
-       maps[0] = map;
+       maps[nmaps++] = map;
+
+       if (map == mnt_get_builtin_optmap(MNT_LINUX_MAP))
+               /*
+                * Add userspace map -- the "user" is interpreted as
+                *                      MS_NO{EXEC,SUID,DEV}.
+                */
+               maps[nmaps++] = mnt_get_builtin_optmap(MNT_USERSPACE_MAP);
 
        while(!mnt_optstr_next_option(&str, &name, &namesz, NULL, NULL)) {
                const struct libmnt_optmap *ent;
+               const struct libmnt_optmap *m;
 
-               if (mnt_optmap_get_entry(maps, 1, name, namesz, &ent)) {
-                       if (!ent->id)
-                               continue;
+               m = mnt_optmap_get_entry(maps, nmaps, name, namesz, &ent);
+               if (!m || !ent || !ent->id)
+                       continue;
+
+               if (m == map) {                         /* requested map */
                        if (ent->mask & MNT_INVERT)
                                *flags &= ~ent->id;
                        else
                                *flags |= ent->id;
+
+               } else if (nmaps == 2 && m == maps[1]) {
+                       /*
+                        * Special case -- translate "user" to MS_ options
+                        */
+                       if (ent->mask & MNT_INVERT)
+                               continue;
+                       if (ent->id & (MNT_MS_OWNER | MNT_MS_GROUP))
+                               *flags |= MS_OWNERSECURE;
+                       else if (ent->id & (MNT_MS_USER | MNT_MS_USERS))
+                               *flags |= MS_SECURE;
                }
        }