非常抱歉讨论略长,这也是我在StackOverflow上的第一个发布贴,请原谅我的不熟悉。
我通常使用C++/Qt Widget或C++/QML与Linux一起使用。这次,我需要使用root权限创建或写入文件,并使用以下URL(PolKit-Qt-1)创建和测试自己的C++/Qt Widget软件。
https://api.kde.org/polkit-qt-1/html/
我正在使用polkit-qt-gui-1创建软件(C++/Qt),以便在按下按钮时创建并以root权限编写文件。
然而,由于无法以root身份创建或编写文件,因此会产生权限错误,但是已经作为执行用户创建或编写文件。
也许有一些配置文件中存在错误,或者源代码存在缺失或错误的部分。
我想在按下按钮时使用root权限创建或写入文件。如何使用C ++ / Qt和PolKit-Qt-1创建或写入具有root权限的文件?
感谢您的合作。
下面是我的源代码。 polkit-1的操作文件也在下面。
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
PolkitQt1::Gui::ActionButton *bt = new PolkitQt1::Gui::ActionButton(ui->pushButton, "org.qt.policykit.examples.write", this);
bt->setText("Run with administrative privileges");
bt->setVisible(true, PolkitQt1::Gui::Action::No | PolkitQt1::Gui::Action::Auth | PolkitQt1::Gui::Action::Yes);
bt->setEnabled(true, PolkitQt1::Gui::Action::No | PolkitQt1::Gui::Action::Auth | PolkitQt1::Gui::Action::Yes);
connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction()));
connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate()));
connect(bt, SIGNAL(authorized()), this, SLOT(onBtnClicked()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::activateAction()
{
PolkitQt1::Gui::Action *action = qobject_cast<PolkitQt1::Gui::Action *>(sender());
action->activate();
}
void MainWindow::onBtnClicked()
{
PolkitQt1::Gui::Action *action = qobject_cast<PolkitQt1::Gui::Action *>(sender());
qDebug() << "pretending to be the mechanism for action:" << action->actionId();
PolkitQt1::UnixProcessSubject subject(static_cast<uint>(QCoreApplication::applicationPid()));
PolkitQt1::Authority::Result result = PolkitQt1::Authority::instance()->checkAuthorizationSync(action->actionId(), subject, PolkitQt1::Authority::AllowUserInteraction);
if (result == PolkitQt1::Authority::Yes)
{
// Write /opt/sample.txt file with root privilege.
writeTextFile("/opt/sample.txt", "foo bar");
}
else
{
return;
}
return;
}
void MainWindow::writeTextFile(QString FileName, QString strOutputData)
{
QFileInfo FileInfo(FileName);
QFile File(FileName);
if(!File.open(QIODevice::WriteOnly))
{
QString strErrMsg = "File(" + FileInfo.fileName() + ") Open Error: " + File.errorString();
qDebug() << strErrMsg;
return;
}
QTextStream OutStream(&File);
OutStream << strOutputData;
File.close();
return;
}
mainwindow.h:
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtWidgets>
#include <QDBusContext>
#include <QDBusMessage>
#include <QDBusConnection>
#include <polkit-qt5-1/polkitqt1-gui-action.h>
#include <polkit-qt5-1/polkitqt1-gui-actionbutton.h>
#include <polkit-qt5-1/polkitqt1-gui-actionbuttons.h>
#include <polkit-qt5-1/polkitqt1-authority.h>
#include <dbus/dbus.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow, protected QDBusContext
{
Q_OBJECT
private:
void writeTextFile(QString FileName, QString strOutputData);
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private Q_SLOTS:
void activateAction();
void onBtnClicked();
};
#endif // MAINWINDOW_H
/usr/share/polkit-1/actions/org.qt.policykit.examples.policy:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE policyconfig PUBLIC '-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN' 'http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd'>
<policyconfig>
<vendor>KDE</vendor>
<vendor_url>http://www.kde.org</vendor_url>
<action id="org.qt.policykit.examples.write">
<description>Write</description>
<message>Prevents PolKit-Qt-1 example from writing</message>
<defaults>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>