diff --git a/smb/kio_smb.h b/smb/kio_smb.h --- a/smb/kio_smb.h +++ b/smb/kio_smb.h @@ -278,6 +278,7 @@ void smbCopy(const QUrl& src, const QUrl &dest, int permissions, KIO::JobFlags flags); void smbCopyGet(const QUrl& src, const QUrl& dest, int permissions, KIO::JobFlags flags); void smbCopyPut(const QUrl& src, const QUrl& dest, int permissions, KIO::JobFlags flags); + bool workaroundEEXIST(const int errNum) const; void fileSystemFreeSpace(const QUrl &url); @@ -288,6 +289,8 @@ */ int m_openFd; SMBUrl m_openUrl; + + const bool m_enableEEXISTWorkaround; }; //========================================================================== diff --git a/smb/kio_smb.cpp b/smb/kio_smb.cpp --- a/smb/kio_smb.cpp +++ b/smb/kio_smb.cpp @@ -31,12 +31,41 @@ #include "kio_smb.h" #include "kio_smb_internal.h" #include +#include +#include Q_LOGGING_CATEGORY(KIO_SMB, "kio_smb") +bool checkEnableEEXISTWorkaround() +{ + /* There is an issue with some libsmbclient versions that return EEXIST + * return code from smbc_opendir() instead of EPERM when the user + * tries to access a resource that requires login authetification. + * We are working around the issue by treating EEXIST as a special case + * of "invalid/unavailable credentials" if we detect that we are using + * the affected versions of libsmbclient + * + * Upstream bug report: https://bugzilla.samba.org/show_bug.cgi?id=13050 + */ + static const QVector brokenVersions{ "4.7.0" }; + + const QString currentVerString = QString::fromLatin1(smbc_version()); + qCDebug(KIO_SMB) << "Using libsmbclient library version" << currentVerString; + + for (const QString &verString : brokenVersions) { + if (verString == currentVerString) { + qCDebug(KIO_SMB) << "Detected broken libsmbclient version" << verString; + return true; + } + } + + return false; +} + //=========================================================================== SMBSlave::SMBSlave(const QByteArray& pool, const QByteArray& app) - : SlaveBase( "smb", pool, app ), m_openFd(-1) + : SlaveBase( "smb", pool, app ), m_openFd(-1), + m_enableEEXISTWorkaround(checkEnableEEXISTWorkaround()) { m_initialized_smbc = false; diff --git a/smb/kio_smb_browse.cpp b/smb/kio_smb_browse.cpp --- a/smb/kio_smb_browse.cpp +++ b/smb/kio_smb_browse.cpp @@ -469,7 +469,7 @@ } else { - if (errNum == EPERM || errNum == EACCES) { + if (errNum == EPERM || errNum == EACCES || workaroundEEXIST(errNum)) { if (checkPassword(m_current_url)) { redirection( m_current_url ); finished(); @@ -518,3 +518,8 @@ finished(); } +bool SMBSlave::workaroundEEXIST(const int errNum) const +{ + return errNum == EEXIST && m_enableEEXISTWorkaround; +} +