]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: don't use nosuid,noexec,nodev for cifs user=foo
authorKarel Zak <kzak@redhat.com>
Thu, 14 Jun 2012 12:19:26 +0000 (14:19 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 14 Jun 2012 12:19:26 +0000 (14:19 +0200)
   mount -t cifs //127.0.0.1/users /mnt/smb -o user=root,password=linux

is incorrectly translated to

   mount.cifs -o noexec,nosuid,nodev,user=root,password=linux ...

The command mount(8) should be sensitive to "user" (without "=<name>")
only. The correct cifs command line is:

   mount.cifs -o user=root,password=linux

Addresses: https://bugzilla.novell.com/show_bug.cgi?id=766157
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context_mount.c
libmount/src/optstr.c

index 6661394ffcdbb50809bd6ce8300df9b304090012..69b5bfc13d8f78cab79981592116320ab0724c6d 100644 (file)
@@ -53,6 +53,15 @@ static int fix_optstr(struct libmnt_context *cxt)
        if (cxt->mountflags & MS_PROPAGATION)
                cxt->mountflags &= (MS_PROPAGATION | MS_REC | MS_SILENT);
 
+       /*
+        * The "user" options is our business (so we can modify the option),
+        * but exception is command line for /sbin/mount.<type> helpers. Let's
+        * save the original user=<name> to call the helpers with unchanged
+        * "user" setting.
+        *
+        * Don't check for MNT_MS_USER in cxt->user_mountflags, the flag maybe
+        * removed by evaluate_permissions().
+        */
        if (!mnt_optstr_get_option(fs->user_optstr, "user", &val, &valsz)) {
                if (val) {
                        cxt->orig_user = strndup(val, valsz);
@@ -210,6 +219,10 @@ err:
 
 /*
  * this has to be called before fix_optstr()
+ *
+ * Note that user=<name> maybe be used by some filesystems as filesystem
+ * specific option (e.g. cifs). Yes, developers of such filesystems have
+ * allocated pretty hot place in hell...
  */
 static int evaluate_permissions(struct libmnt_context *cxt)
 {
@@ -247,10 +260,22 @@ static int evaluate_permissions(struct libmnt_context *cxt)
                }
 
                /*
-                * Note that MS_OWNERSECURE and MS_SECURE mount options
-                * are applied by mnt_optstr_get_flags() from mnt_context_merge_mflags()
+                * MS_OWNERSECURE and MS_SECURE mount options are already
+                * applied by mnt_optstr_get_flags() in mnt_context_merge_mflags()
+                * if "user" (but no user=<name> !) options is set.
+                *
+                * Let's ignore all user=<name> (if <name> is set) requests.
                 */
+               if (cxt->user_mountflags & MNT_MS_USER) {
+                       size_t valsz = 0;
 
+                       if (!mnt_optstr_get_option(cxt->fs->user_optstr,
+                                       "user", NULL, &valsz) && valsz) {
+
+                               DBG(CXT, mnt_debug_h(cxt, "perms: user=<name> detected, ignore"));
+                               cxt->user_mountflags &= ~MNT_MS_USER;
+                       }
+               }
 
                /*
                 * MS_OWNER: Allow owners to mount when fstab contains the
index ca1b2e2c7ff3a63dad4098d3fa6d2e725ab8ec49..c8beadad2ac79e8916031862972025c9012389b1 100644 (file)
@@ -586,7 +586,7 @@ int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
 {
        struct libmnt_optmap const *maps[2];
        char *name, *str = (char *) optstr;
-       size_t namesz = 0;
+       size_t namesz = 0, valsz = 0;
        int nmaps = 0;
 
        assert(optstr);
@@ -603,7 +603,7 @@ int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
                 */
                maps[nmaps++] = mnt_get_builtin_optmap(MNT_USERSPACE_MAP);
 
-       while(!mnt_optstr_next_option(&str, &name, &namesz, NULL, NULL)) {
+       while(!mnt_optstr_next_option(&str, &name, &namesz, NULL, &valsz)) {
                const struct libmnt_optmap *ent;
                const struct libmnt_optmap *m;
 
@@ -617,9 +617,10 @@ int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
                        else
                                *flags |= ent->id;
 
-               } else if (nmaps == 2 && m == maps[1]) {
+               } else if (nmaps == 2 && m == maps[1] && valsz == 0) {
                        /*
-                        * Special case -- translate "user" to MS_ options
+                        * Special case -- translate "user" (but no user=) to
+                        * MS_ options
                         */
                        if (ent->mask & MNT_INVERT)
                                continue;