cifsmount: retry with older protocol versions on failure

* An old server might not support the (cifs.ko) default protocol version
* Crypto modules required for new(er) protocol versions might be missing
  in initramfs

Related: #40554
This commit is contained in:
Alexey Sheplyakov 2021-08-24 15:29:38 +04:00
parent 08639c8faf
commit d1d376a30f

44
mount.c
View File

@ -181,12 +181,26 @@ out:
} }
#ifdef ENABLE_CIFS #ifdef ENABLE_CIFS
static int cifsmount(char *dev, char *location) static int cifsmount3(char *dev, char *location, const char *extra_opts)
{ {
char spec[PATH_MAX + 19], *sep, *ptr = dev; char spec[PATH_MAX + 19], *sep, *ptr = dev;
struct sockaddr_in saddr; struct sockaddr_in saddr;
pid_t pid; pid_t pid;
int n, status, ret = -1; int n, status, ret = -1;
const char *default_opts = "guest";
char *opts = NULL;
if (extra_opts) {
if (asprintf(&opts, "%s,%s", default_opts, extra_opts) < 0) {
log_message("%s: error: asprintf", __func__);
return -1;
}
} else {
opts = strdup(default_opts);
if (!opts) {
log_message("%s: error: strdup", __func__);
return -1;
}
}
while (*ptr == '/') ptr++; while (*ptr == '/') ptr++;
@ -211,14 +225,15 @@ static int cifsmount(char *dev, char *location)
strcat(spec, inet_ntoa(saddr.sin_addr)); strcat(spec, inet_ntoa(saddr.sin_addr));
n = strlen(spec); n = strlen(spec);
strncpy(spec + n, sep, sizeof(spec) - n); strncpy(spec + n, sep, sizeof(spec) - n);
log_message("cifsmount %s %s", spec, location);
log_message("/sbin/mount.cifs %s %s --verbose -o %s", spec, location, opts);
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
log_message("%s: error: fork: %s", __func__, strerror(errno)); log_message("%s: error: fork: %s", __func__, strerror(errno));
goto out; goto out;
} else if (pid == 0) { } else if (pid == 0) {
char * argv[] = {"/sbin/mount.cifs", spec, location, "-oguest", NULL}; char * argv[] = {"/sbin/mount.cifs", spec, location, "--verbose", "-o", opts, NULL};
redirect2log(STDOUT_FILENO); redirect2log(STDOUT_FILENO);
redirect2log(STDERR_FILENO); redirect2log(STDERR_FILENO);
redirect2null(STDIN_FILENO); redirect2null(STDIN_FILENO);
@ -232,8 +247,31 @@ static int cifsmount(char *dev, char *location)
ret = (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1; ret = (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1;
} }
out: out:
free(opts);
return ret; return ret;
} }
static int cifsmount(char *dev, char *location)
{
int rc = 0;
static const char *fallbacks[] = {
"vers=2.1,sec=none",
"vers=2.0,sec=none",
"vers=1.0,sec=none",
NULL
};
const char **opts = NULL;
log_message("%s: attempting to mount %s with default protocol version", __func__, dev);
rc = cifsmount3(dev, location, NULL);
for (opts = fallbacks; rc < 0 && *opts; opts++) {
log_message("%s: failed, retrying with %s", __func__, *opts);
rc = cifsmount3(dev, location, *opts);
}
if (rc < 0) {
log_message("%s: sorry, nothing worked", __func__);
}
return rc;
}
#endif #endif
#endif #endif