diff --git a/src/core/global.h b/src/core/global.h --- a/src/core/global.h +++ b/src/core/global.h @@ -248,6 +248,7 @@ ERR_CANNOT_CREATE_SLAVE = KJob::UserDefinedError + 73, ///< used by Slave::createSlave, @since 5.30 ERR_FILE_TOO_LARGE_FOR_FAT32 = KJob::UserDefinedError + 74, ///< @since 5.54 ERR_OWNER_DIED = KJob::UserDefinedError + 75, ///< Value used between kuiserver and views when the job owner disappears unexpectedly. It should not be emitted by slaves. @since 5.54 + ERR_PRIVILEGE_NOT_REQUIRED = KJob::UserDefinedError + 76, ///< used by file ioslave, @since 5.60 }; /** diff --git a/src/core/job_error.cpp b/src/core/job_error.cpp --- a/src/core/job_error.cpp +++ b/src/core/job_error.cpp @@ -252,6 +252,9 @@ case KIO::ERR_FILE_TOO_LARGE_FOR_FAT32: result = xi18nc("@info", "Cannot transfer %1 because it is too large. The destination filesystem only supports files up to 4GiB", errorText); break; + case KIO::ERR_PRIVILEGE_NOT_REQUIRED: + result = i18n("Privilege escalation is not necessary because \n'%1' is owned by the current user.\nPlease retry after changing permissions.", errorText); + break; default: result = i18n("Unknown error code %1\n%2\nPlease send a full bug report at https://bugs.kde.org.", errorCode, errorText); break; diff --git a/src/ioslaves/file/file_unix.cpp b/src/ioslaves/file/file_unix.cpp --- a/src/ioslaves/file/file_unix.cpp +++ b/src/ioslaves/file/file_unix.cpp @@ -886,6 +886,19 @@ return PrivilegeOperationReturnValue::failure(errcode); } + const QUrl targetUrl = QUrl::fromLocalFile(args.first().toString()); // target is always the first item. + const bool useParent = action != CHOWN && action != CHMOD && action != UTIME; + const QString targetPath = useParent ? targetUrl.adjusted(QUrl::RemoveFilename).toLocalFile() : targetUrl.toLocalFile(); + bool userIsOwner = QFileInfo(targetPath).ownerId() == getuid(); + if (action == RENAME) { // for rename check src and dest owner + QString dest = QUrl(args[1].toString()).toLocalFile(); + userIsOwner = userIsOwner && QFileInfo(dest).ownerId() == getuid(); + } + if (userIsOwner) { + error(KIO::ERR_PRIVILEGE_NOT_REQUIRED, targetPath); + return PrivilegeOperationReturnValue::canceled(); + } + QByteArray helperArgs; QDataStream out(&helperArgs, QIODevice::WriteOnly); out << action;