mount.cifs: don't leak passwords with verbose option
authorJeff Layton <jlayton@redhat.com>
Fri, 25 Sep 2009 11:07:40 +0000 (07:07 -0400)
committerKarolin Seeger <kseeger@samba.org>
Thu, 1 Oct 2009 12:29:22 +0000 (14:29 +0200)
When running mount.cifs with the --verbose option, it'll print out the
option string that it passes to the kernel...including the mount
password if there is one. Print a placeholder string instead to help
ensure that this info can't be used for nefarious purposes.

Also, the --verbose option printed the option string before it was
completely assembled anyway. This patch should also make sure that
the complete option string is printed out.

Finally, strndup passwords passed in on the command line to ensure that
they aren't shown by --verbose as well. Passwords used this way can
never be truly kept private from other users on the machine of course,
but it's simple enough to do it this way for completeness sake.

Reported-by: Ronald Volgers <r.c.volgers@student.utwente.nl>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Steve French <sfrench@us.ibm.com>
client/mount.cifs.c

index 0f41afff9cc6d4c59a30646dd8cfe4e6529f7d64..3baaad793713dbbe224348126cd57042f6d002f6 100644 (file)
@@ -512,9 +512,6 @@ static int parse_options(char ** optionsp, unsigned long * filesys_flags)
                return 1;
        data = *optionsp;
 
-       if(verboseflag)
-               fprintf(stderr, "parsing options: %s\n", data);
-
        /* BB fixme check for separator override BB */
 
        if (getuid()) {
@@ -605,14 +602,23 @@ static int parse_options(char ** optionsp, unsigned long * filesys_flags)
                                } else
                                        got_password = 1;
                        } else if (strnlen(value, MOUNT_PASSWD_SIZE) < MOUNT_PASSWD_SIZE) {
-                               if(got_password)
+                               if (got_password) {
                                        fprintf(stderr, "\nmount.cifs warning - password specified twice\n");
-                               got_password = 1;
+                               } else {
+                                       mountpassword = strndup(value, MOUNT_PASSWD_SIZE);
+                                       if (!mountpassword) {
+                                               fprintf(stderr, "mount.cifs error: %s", strerror(ENOMEM));
+                                               SAFE_FREE(out);
+                                               return 1;
+                                       }
+                                       got_password = 1;
+                               }
                        } else {
                                fprintf(stderr, "password too long\n");
                                SAFE_FREE(out);
                                return 1;
                        }
+                       goto nocopy;
                } else if (strncmp(data, "sec", 3) == 0) {
                        if (value) {
                                if (!strncmp(value, "none", 4) ||
@@ -1512,15 +1518,6 @@ mount_retry:
                        strlcat(options,domain_name,options_size);
                }
        }
-       if(mountpassword) {
-               /* Commas have to be doubled, or else they will
-               look like the parameter separator */
-/*             if(sep is not set)*/
-               if(retry == 0)
-                       check_for_comma(&mountpassword);
-               strlcat(options,",pass=",options_size);
-               strlcat(options,mountpassword,options_size);
-       }
 
        strlcat(options,",ver=",options_size);
        strlcat(options,MOUNT_CIFS_VERSION_MAJOR,options_size);
@@ -1533,8 +1530,6 @@ mount_retry:
                strlcat(options,",prefixpath=",options_size);
                strlcat(options,prefixpath,options_size); /* no need to cat the / */
        }
-       if(verboseflag)
-               fprintf(stderr, "\nmount.cifs kernel mount options %s \n",options);
 
        /* convert all '\\' to '/' in share portion so that /proc/mounts looks pretty */
        replace_char(dev_name, '\\', '/', strlen(share_name));
@@ -1576,6 +1571,25 @@ mount_retry:
                         addr6->sin6_scope_id);
        }
 
+       if(verboseflag)
+               fprintf(stderr, "\nmount.cifs kernel mount options: %s", options);
+
+       if (mountpassword) {
+               /*
+                * Commas have to be doubled, or else they will
+                * look like the parameter separator
+                */
+               if(retry == 0)
+                       check_for_comma(&mountpassword);
+               strlcat(options,",pass=",options_size);
+               strlcat(options,mountpassword,options_size);
+               if (verboseflag)
+                       fprintf(stderr, ",pass=********");
+       }
+
+       if (verboseflag)
+               fprintf(stderr, "\n");
+
        if (!fakemnt && mount(dev_name, mountpoint, "cifs", flags, options)) {
                switch (errno) {
                case ECONNREFUSED: