What is the correct escaping for autofs mount credentials files?

I have configured autofs on CentOS using /etc/auto.mymount. Something like this:

mymount -fstype=cifs,rw,noperm,credentials=/etc/auto.creds.svc_account ://winserver.domain.local/SharedFolder

This has been working and still does for some mounts. However a password has been changed for an account which is used for connecting to a Windows server and this now contains all sorts of special characters. My credentials file /etc/auto.creds.svc_account looks a bit like this:

username=svc_account
password=AbCd@a;abc{`B"[C\\~/fg9w(G':4##abC}d3.H}v,2]f+c

Obviously I have changed the password above, but it does contain various non alpha-numeric characters that are in the real password.

Looking in /var/log/messages, I see the following:

Status code returned 0xc000006d NT_STATUS_LOGON_FAILURE
CIFS VFS: Send error in SessSetup = -13
CIFS VFS: cifs_mount failed w/return code = -13

Given that the only thing which has changed is the password, I'm guessing that that there are special characters in there which need to be escaped somehow.

Now I know that if I put that password into the command line, then commands will fall over due to the various special characters, which can be dealt with by preceding each of them with a backslash. For instance:

password=AbCd@a\;abc{\`B\"[C\\\\~/fg9w\(G\':4##abC}d3.H}v,2]f+c

But that didn't work, so clearly I'm missing something. Is anybody able to explain which characters need to be escaped in a credentials file and the correct way to escape them?


Solution 1:

I suppose the credentials file will be read by mount.cifs, like for other CIFS mounts. So I had a look at the mount.cifs.c source file in the current cifs-utils code, which should be for version 6.3. The code for reading the password does no unescaping, except that every comma is doubled in the password field of the parsed_mount_info struct, as is apparently necessary when assembling the parameters for the mount(2) call:

/*
 * CIFS has to "escape" commas in the password field so that they don't
 * end up getting confused for option delimiters. Copy password into pw
 * field, turning any commas into double commas.
 */
static int set_password(struct parsed_mount_info *parsed_info, const char *src)
{
    char *dst = parsed_info->password;
    unsigned int i = 0, j = 0;

    while (src[i]) {
        if (src[i] == ',')
            dst[j++] = ',';
        dst[j++] = src[i++];
        if (j > sizeof(parsed_info->password)) {
            fprintf(stderr, "Converted password too long!\n");
            return EX_USAGE;
        }
    }
    dst[j] = '\0';
    parsed_info->got_password = 1;
    return 0;
}

In case of a credentials file, src points to the position in the password line just behind the = sign. Everything between the = sign and the end of the line as read by fgets() is copied into the password field. (The newline is replaced by a null byte before copying.) But for every other way to set a password, like environment variables, options, or from stdin, the same routine is called, so if mounting the volume works from the command line, that comma doubling is not the culprit.

However, you might get into trouble if any line contains trailing whitespace or your credentials file has non-UNIX line endings. A trailing CR would be read as part of the password, as would other trailing whitespace. Similarly reading the password could fail if your password contains any non-ASCII characters, where the encoding of the file would be important.

TL,DR:

  • Nothing has to be escaped in the password
  • Check if mounting the CIFS volume works from the command line
  • Check for trailing whitespace in the password line
  • Check if your credentials file has UNIX format and no DOS line endings
  • Check for non-ASCII characters (like umlauts) in the password
  • Check if it works with a password without commas (it really shouldn't make a difference, but who knows)

Solution 2:

Do you possibly have any spaces in the file, perhaps between the = signs? a -13 error can be caused by spaces in the creds file, as per the following link. http://thinkinginsoftware.blogspot.com/2011/09/cifs-vfs-cifsmount-failed-return-code.html

My own thinking also wonders if this might be due to an encoding issue with the file itself. What does file -bi /etc/auto.creds.svc_account return? Perhaps there is a stray control character? What does opening the file with vim and running :set list show? Perhaps it wasn't an issue before because the encoding used only "blows up" on certain characters which were not present in the password until now. The easiest way to troubleshoot this would be to recreate the file and try again, or compare the old working password with the new one and determine what new special characters may have been introduced.