diff --git a/src/ioslaves/file/file.cpp b/src/ioslaves/file/file.cpp --- a/src/ioslaves/file/file.cpp +++ b/src/ioslaves/file/file.cpp @@ -1331,7 +1331,15 @@ } else { //qDebug() << "QFile::remove" << itemPath; if (!QFile::remove(itemPath)) { - error(KIO::ERR_CANNOT_DELETE, itemPath); + if (errno == EACCES || errno == EPERM) { + if (execWithRoot(QStringLiteral("del"), QStringLiteral("delete_file"), + itemPath, WARN_PRIVILEDGE_DEL)) { + continue; + } + error(KIO::ERR_ACCESS_DENIED, itemPath); + } else { + error(KIO::ERR_CANNOT_DELETE, itemPath); + } return false; } } @@ -1340,10 +1348,19 @@ Q_FOREACH (const QString &itemPath, dirsToDelete) { //qDebug() << "QDir::rmdir" << itemPath; if (!dir.rmdir(itemPath)) { - error(KIO::ERR_CANNOT_DELETE, itemPath); + if (errno == EACCES || errno == EPERM) { + if (execWithRoot(QStringLiteral("del"), QStringLiteral("delete_dir"), + itemPath, WARN_PRIVILEDGE_RMDIR)) { + continue; + } + error(KIO::ERR_ACCESS_DENIED, itemPath); + } else { + error(KIO::ERR_CANNOT_DELETE, itemPath); + } return false; } } + return true; } 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 @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -526,7 +527,12 @@ if (unlink(_path.data()) == -1) { if ((errno == EACCES) || (errno == EPERM)) { + if (execWithRoot(QStringLiteral("del"), QStringLiteral("delete_file"), _path, WARN_PRIVILEDGE_DEL)) { + finished(); + return; + } error(KIO::ERR_ACCESS_DENIED, path); + } else if (errno == EISDIR) { error(KIO::ERR_IS_DIRECTORY, path); } else { @@ -548,8 +554,10 @@ } if (QT_RMDIR(_path.data()) == -1) { if ((errno == EACCES) || (errno == EPERM)) { - error(KIO::ERR_ACCESS_DENIED, path); - return; + if (!execWithRoot(QStringLiteral("del"), QStringLiteral("delete_dir"), path, WARN_PRIVILEDGE_RMDIR)) { + error(KIO::ERR_ACCESS_DENIED, path); + return; + } } else { // qDebug() << "could not rmdir " << perror; error(KIO::ERR_CANNOT_RMDIR, path); @@ -558,6 +566,7 @@ } } + endPriviledgeOp(); finished(); } diff --git a/src/ioslaves/file/kauth/file.actions b/src/ioslaves/file/kauth/file.actions --- a/src/ioslaves/file/kauth/file.actions +++ b/src/ioslaves/file/kauth/file.actions @@ -0,0 +1,5 @@ +[org.kde.kio.file.del] +Name=Remove items as a privileged user. +Description=Remove items as a privileged user. +Policy=auth_admin +Persistence=session diff --git a/src/ioslaves/file/kauth/helper.h b/src/ioslaves/file/kauth/helper.h --- a/src/ioslaves/file/kauth/helper.h +++ b/src/ioslaves/file/kauth/helper.h @@ -29,6 +29,9 @@ class Helper : public QObject { Q_OBJECT + +public Q_SLOTS: + ActionReply del(const QVariantMap& args); }; #endif diff --git a/src/ioslaves/file/kauth/helper.cpp b/src/ioslaves/file/kauth/helper.cpp --- a/src/ioslaves/file/kauth/helper.cpp +++ b/src/ioslaves/file/kauth/helper.cpp @@ -19,5 +19,38 @@ ***/ #include "helper.h" +#include +#include + +#include +#include +#include +#include +#include + + +ActionReply Helper::del(const QVariantMap &args) +{ + ActionReply reply = ActionReply::SuccessReply(); + const QByteArray path = args["arguments"].toByteArray(); + const QString subAction = args["subaction"].toString(); + + if (subAction == "delete_file") { + unlink(path.constData()); + } else if(subAction == "delete_dir") { + QDir dir; + dir.rmdir(path.constData()); + } + if (errno) { + if (errno == EACCES || errno == EPERM) { + QVariantMap errorData; + errorData.insert(QStringLiteral("errormessage"), i18n("Access Denied!")); + errorData.insert(QStringLiteral("errorcode"), KIO::ERR_ACCESS_DENIED); + reply.setData(errorData); + } + } + + return reply; +} KAUTH_HELPER_MAIN("org.kde.kio.file", Helper)