Commit a36b7979 authored by Michal Malý's avatar Michal Malý Committed by Nate Graham
Browse files

Workaround incorrectly returned EEXIST instead of EPERM regression introduced by libsmbclient 4.7

There appears to be an issue with libsmbclient 4.7 that returns nonsensical EEXIST error code when a user has not authenticated themselves to access password-protected shares. This patch attempts to work around the issue by treating EEXIST as another case of "invalid login credentials". The workaround tries to detect broken versions of libsmbclient and enables itself only when such a version is found.

See for upstream bug report.

BUG: 385708

Reviewers: ngraham, davidedmundson, elvisangelaccio, #frameworks

Reviewed By: ngraham, davidedmundson

Subscribers: cfeck, rdieter, graesslin, z3ntu

Differential Revision:
parent 7f17d87c
......@@ -31,12 +31,40 @@
#include "kio_smb.h"
#include "kio_smb_internal.h"
#include <QCoreApplication>
#include <QVersionNumber>
bool needsEEXISTWorkaround()
/* 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:
static const QVersionNumber firstBrokenVer{4, 7, 0};
static const QVersionNumber lastBrokenVer{9, 9, 9}; /* Adjust accordingly when this gets fixed upstream */
const QVersionNumber currentVer = QVersionNumber::fromString(smbc_version());
qCDebug(KIO_SMB) << "Using libsmbclient library version" << currentVer;
if (currentVer >= firstBrokenVer && currentVer <= lastBrokenVer) {
qCDebug(KIO_SMB) << "Detected broken libsmbclient version" << currentVer;
return true;
return false;
SMBSlave::SMBSlave(const QByteArray& pool, const QByteArray& app)
: SlaveBase( "smb", pool, app ), m_openFd(-1)
: SlaveBase( "smb", pool, app ),
m_initialized_smbc = false;
......@@ -278,6 +278,7 @@ private:
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 @@ private:
int m_openFd;
SMBUrl m_openUrl;
const bool m_enableEEXISTWorkaround; /* Enables a workaround for some broken libsmbclient versions */
......@@ -473,7 +473,7 @@ void SMBSlave::listDir( const QUrl& kurl )
if (errNum == EPERM || errNum == EACCES) {
if (errNum == EPERM || errNum == EACCES || workaroundEEXIST(errNum)) {
if (checkPassword(m_current_url)) {
redirection( m_current_url );
......@@ -522,3 +522,8 @@ void SMBSlave::fileSystemFreeSpace(const QUrl& url)
bool SMBSlave::workaroundEEXIST(const int errNum) const
return (errNum == EEXIST) && m_enableEEXISTWorkaround;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment