From d1d376a30f13b340d9e81e1a8964b44693e55c19 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Tue, 24 Aug 2021 15:29:38 +0400 Subject: [PATCH] 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 --- mount.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/mount.c b/mount.c index e2edd7f..0404672 100644 --- a/mount.c +++ b/mount.c @@ -181,12 +181,26 @@ out: } #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; struct sockaddr_in saddr; pid_t pid; 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++; @@ -211,14 +225,15 @@ static int cifsmount(char *dev, char *location) strcat(spec, inet_ntoa(saddr.sin_addr)); n = strlen(spec); 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(); if (pid < 0) { log_message("%s: error: fork: %s", __func__, strerror(errno)); goto out; } 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(STDERR_FILENO); redirect2null(STDIN_FILENO); @@ -232,8 +247,31 @@ static int cifsmount(char *dev, char *location) ret = (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1; } out: + free(opts); 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