Skip to content

Commit

Permalink
[nemo-qml-plugin-filemanager] Delegate file operations to nonprivileg…
Browse files Browse the repository at this point in the history
…ed process. Contributes to MER#1617

Since we can't be sure that the calling process will have the CAP_SETGID
capability, use a separate daemon to apply nonprivileged file system
operations, invoked via D-Bus.
  • Loading branch information
matthewvogt committed Jul 15, 2016
1 parent 5c3343c commit 467720e
Show file tree
Hide file tree
Showing 10 changed files with 725 additions and 542 deletions.
7 changes: 5 additions & 2 deletions src/daemon/daemon.pro
Expand Up @@ -17,14 +17,17 @@ system(qdbusxml2cpp -c FileOperationsAdaptor -a fileoperationsadaptor.h:fileoper

HEADERS =\
fileoperationsadaptor.h \
fileoperationsservice.h
fileoperationsservice.h \
fileoperations.h

SOURCES =\
fileoperationsadaptor.cpp \
fileoperationsservice.cpp \
fileoperations.cpp \
main.cpp

INCLUDEPATH += ../plugin
INCLUDEPATH += ../plugin ../shared
VPATH += ../shared

SERVICE_FILE = ../../dbus/org.nemomobile.FileOperations.service
INTERFACE_FILE = ../../dbus/org.nemomobile.FileOperations.xml
Expand Down
39 changes: 35 additions & 4 deletions src/daemon/fileoperationsservice.cpp
Expand Up @@ -32,8 +32,7 @@

#include "fileoperationsservice.h"
#include "fileoperationsadaptor.h"

#include "fileengine.h"
#include "fileoperations.h"

namespace {

Expand Down Expand Up @@ -329,8 +328,40 @@ void FileOperationsService::processRequests()

void FileOperationsService::processOperation(OperationRequest *request, OperationResponse *response)
{
Q_UNUSED(request)
Q_UNUSED(response)
FileOperations::ContinueFunc continueFn = [response]() { return response->continueOperation(); };
FileOperations::PathResultFunc pathResultFn = [response](const QString &path, bool success) {
if (success) {
response->successPaths.append(path);
} else {
response->failedPaths.append(path);
}
};

switch (request->type) {
case OperationRequest::Copy:
response->error = FileOperations::copyFiles(request->paths, request->destination, pathResultFn, continueFn);
break;

case OperationRequest::Move:
response->error = FileOperations::moveFiles(request->paths, request->destination, pathResultFn, continueFn);
break;

case OperationRequest::Delete:
response->error = FileOperations::deleteFiles(request->paths, pathResultFn, continueFn);
break;

case OperationRequest::Mkdir:
response->error = FileOperations::createDirectory(request->paths.first(), request->destination, pathResultFn);
break;

case OperationRequest::Rename:
response->error = FileOperations::renameFile(request->paths.first(), request->destination, pathResultFn);
break;

case OperationRequest::SetPermissions:
response->error = FileOperations::chmodFile(request->paths.first(), static_cast<QFileDevice::Permissions>(request->mask), pathResultFn);
break;
}
}

void FileOperationsService::timerEvent(QTimerEvent *event)
Expand Down
22 changes: 11 additions & 11 deletions src/plugin/fileengine.cpp
Expand Up @@ -76,9 +76,9 @@ bool FileEngine::busy() const
return m_fileWorker->isRunning();
}

void FileEngine::deleteFiles(QStringList fileNames, QString asUser)
void FileEngine::deleteFiles(QStringList fileNames, bool nonprivileged)
{
m_fileWorker->startDeleteFiles(fileNames, asUser);
m_fileWorker->startDeleteFiles(fileNames, nonprivileged);
}

void FileEngine::cutFiles(QStringList fileNames)
Expand Down Expand Up @@ -108,7 +108,7 @@ void FileEngine::copyFiles(QStringList fileNames)
}
}

void FileEngine::pasteFiles(QString destDirectory, QString asUser)
void FileEngine::pasteFiles(QString destDirectory, bool nonprivileged)
{
if (m_clipboardFiles.isEmpty()) {
qmlInfo(this) << "Paste called with empty clipboard.";
Expand Down Expand Up @@ -149,11 +149,11 @@ void FileEngine::pasteFiles(QString destDirectory, QString asUser)
emit clipboardCountChanged();

if (m_clipboardContainsCopy) {
m_fileWorker->startCopyFiles(files, destDirectory, asUser);
m_fileWorker->startCopyFiles(files, destDirectory, nonprivileged);
return;
}

m_fileWorker->startMoveFiles(files, destDirectory, asUser);
m_fileWorker->startMoveFiles(files, destDirectory, nonprivileged);
}

void FileEngine::cancel()
Expand All @@ -170,21 +170,21 @@ bool FileEngine::exists(QString fileName)
return QFile::exists(fileName);
}

bool FileEngine::mkdir(QString path, QString name, QString asUser)
bool FileEngine::mkdir(QString path, QString name, bool nonprivileged)
{
if (!m_fileWorker->mkdir(path, name, asUser)) {
if (!m_fileWorker->mkdir(path, name, nonprivileged)) {
emit error(ErrorFolderCreationFailed, name);
return false;
}
return true;
}

bool FileEngine::rename(QString fullOldFileName, QString newName, QString asUser)
bool FileEngine::rename(QString fullOldFileName, QString newName, bool nonprivileged)
{
QFileInfo fileInfo(fullOldFileName);
QDir dir = fileInfo.absoluteDir();
QString fullNewFileName = dir.absoluteFilePath(newName);
if (!m_fileWorker->rename(fullOldFileName, fullNewFileName, asUser)) {
if (!m_fileWorker->rename(fullOldFileName, fullNewFileName, nonprivileged)) {
emit error(ErrorRenameFailed, fileInfo.fileName());
return false;
}
Expand All @@ -194,7 +194,7 @@ bool FileEngine::rename(QString fullOldFileName, QString newName, QString asUser
bool FileEngine::chmod(QString path,
bool ownerRead, bool ownerWrite, bool ownerExecute,
bool groupRead, bool groupWrite, bool groupExecute,
bool othersRead, bool othersWrite, bool othersExecute, QString asUser)
bool othersRead, bool othersWrite, bool othersExecute, bool nonprivileged)
{
QFileDevice::Permissions p;
if (ownerRead) p |= QFileDevice::ReadOwner;
Expand All @@ -206,7 +206,7 @@ bool FileEngine::chmod(QString path,
if (othersRead) p |= QFileDevice::ReadOther;
if (othersWrite) p |= QFileDevice::WriteOther;
if (othersExecute) p |= QFileDevice::ExeOther;
if (!m_fileWorker->setPermissions(path, p, asUser)) {
if (!m_fileWorker->setPermissions(path, p, nonprivileged)) {
emit error(ErrorChmodFailed, path);
return false;
}
Expand Down
11 changes: 5 additions & 6 deletions src/plugin/fileengine.h
Expand Up @@ -68,7 +68,6 @@ class FileEngine : public QObject
ErrorFolderCopyFailed,
ErrorFolderCreationFailed,
ErrorChmodFailed,
ErrorUserChangeFailed
};

enum Mode {
Expand All @@ -87,22 +86,22 @@ class FileEngine : public QObject
// methods accessible from QML

// asynch methods send signals when done or error occurs
Q_INVOKABLE void deleteFiles(QStringList fileNames, QString asUser = QString());
Q_INVOKABLE void deleteFiles(QStringList fileNames, bool nonprivileged = false);
Q_INVOKABLE void cutFiles(QStringList fileNames);
Q_INVOKABLE void copyFiles(QStringList fileNames);
Q_INVOKABLE void pasteFiles(QString destDirectory, QString asUser = QString());
Q_INVOKABLE void pasteFiles(QString destDirectory, bool nonprivileged = false);

// cancel asynch methods
Q_INVOKABLE void cancel();

// synchronous methods
Q_INVOKABLE bool exists(QString fileName);
Q_INVOKABLE bool mkdir(QString path, QString name, QString asUser = QString());
Q_INVOKABLE bool rename(QString fullOldFileName, QString newName, QString asUser = QString());
Q_INVOKABLE bool mkdir(QString path, QString name, bool nonprivileged = false);
Q_INVOKABLE bool rename(QString fullOldFileName, QString newName, bool nonprivileged = false);
Q_INVOKABLE bool chmod(QString path,
bool ownerRead, bool ownerWrite, bool ownerExecute,
bool groupRead, bool groupWrite, bool groupExecute,
bool othersRead, bool othersWrite, bool othersExecute, QString asUser = QString());
bool othersRead, bool othersWrite, bool othersExecute, bool nonprivileged = false);


signals:
Expand Down

0 comments on commit 467720e

Please sign in to comment.