Index: src/ioslaves/file/CMakeLists.txt =================================================================== --- src/ioslaves/file/CMakeLists.txt +++ src/ioslaves/file/CMakeLists.txt @@ -24,7 +24,7 @@ target_link_libraries(kio_file KF5::KIOCore KF5::I18n) if(UNIX) - target_link_libraries(kio_file Qt5::Network) + target_link_libraries(kio_file Qt5::Network KF5::Auth) endif() if (HAVE_VOLMGT AND CMAKE_SYSTEM_NAME MATCHES SunOS) @@ -37,3 +37,7 @@ set_target_properties(kio_file PROPERTIES OUTPUT_NAME "file") install(TARGETS kio_file DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kio) + +if (UNIX) + add_subdirectory(kauth) +endif() Index: src/ioslaves/file/kauth/CMakeLists.txt =================================================================== --- /dev/null +++ src/ioslaves/file/kauth/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(file_helper filehelper.cpp ../sharefd.cpp) +target_link_libraries(file_helper Qt5::Network KF5::Auth KF5::I18n KF5::KIOCore) + +install(TARGETS file_helper DESTINATION ${KAUTH_HELPER_INSTALL_DIR}) +kauth_install_helper_files(file_helper org.kde.kio.file root) +kauth_install_actions(org.kde.kio.file file.actions) Index: src/ioslaves/file/kauth/file.actions =================================================================== --- /dev/null +++ src/ioslaves/file/kauth/file.actions @@ -0,0 +1,5 @@ +[org.kde.kio.file.exec] +Name=Execute action as root. +Description=Root privileges are required to complete the action. +Policy=auth_admin +Persistence=session Index: src/ioslaves/file/kauth/filehelper.h =================================================================== --- /dev/null +++ src/ioslaves/file/kauth/filehelper.h @@ -0,0 +1,47 @@ +/*** + Copyright (C) 2017 by Chinmoy Ranjan Pradhan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +***/ + + +#ifndef HELPER_H +#define HELPER_H + +#include + +using namespace KAuth; + +/** + * This KAuth helper is responsible for performing file operations with + * root privileges. + * + * @since 5.37 + */ +class FileHelper : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + /** + * Execute action with root privileges. + * + **/ + ActionReply exec(const QVariantMap &args); +}; + +#endif Index: src/ioslaves/file/kauth/filehelper.cpp =================================================================== --- /dev/null +++ src/ioslaves/file/kauth/filehelper.cpp @@ -0,0 +1,136 @@ +/*** + Copyright (C) 2017 by Chinmoy Ranjan Pradhan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "filehelper.h" +#include "../sharefd.h" + +static void sendFileDescriptor(int fd) +{ + FdSender fdSender; + fdSender.connectToPath("org_kde_kio_file_helper_socket"); + if (fdSender.isConnected()) { + fdSender.sendFileDescriptor(fd); + return; + } + errno = -1; +} + +enum { + CHMOD = 1, + CHOWN, + DEL, + MKDIR, + OPEN, + OPENDIR, + RENAME, + RMDIR, + SYMLINK, + UTIME, +}; + +ActionReply FileHelper::exec(const QVariantMap &args) +{ + errno = 0; + + ActionReply reply; + QByteArray data = args["arguments"].toByteArray(); + QDataStream in(data); + int action; + QVariant arg1, arg2, arg3; + in >> action >> arg1 >> arg2 >> arg3; + + // the path of an existing or a new file/dir upon which the method will operate + const QByteArray path = arg1.toByteArray(); + + switch(action) { + case CHMOD: { + int mode = arg2.toInt(); + chmod(path.data(), mode); + break; + } + case CHOWN: { + int uid = arg2.toInt(); + int gid = arg3.toInt(); + chown(path.data(), uid, gid); + break; + } + case DEL: { + unlink(path.data()); + break; + } + case MKDIR: { + mkdir(path.data(), 0777); + break; + } + case OPEN: { + int oflags = arg2.toInt(); + int mode = arg3.toInt(); + int fd = open(path.data(), oflags, mode); + sendFileDescriptor(fd); + close(fd); + break; + } + case OPENDIR: { + DIR *dp = opendir(path.data()); + if (dp) { + int fd = dirfd(dp); + sendFileDescriptor(fd); + closedir(dp); + } + sendFileDescriptor(-1); + break; + } + case RENAME: { + const QByteArray newName = arg2.toByteArray(); + rename(path.data(), newName.data()); + break; + } + case RMDIR: { + rmdir(path.data()); + break; + } + case SYMLINK: { + const QByteArray target = arg2.toByteArray(); + symlink(target.data(), path.data()); + break; + } + case UTIME: { + utimbuf ut; + ut.actime = arg2.toULongLong(); + ut.modtime = arg3.toULongLong(); + utime(path.data(), &ut); + break; + } + }; + + if (errno) + reply.setError(errno); + + return reply; +} + + +KAUTH_HELPER_MAIN("org.kde.kio.file", FileHelper)