Calling KAuth action from another action problem.
-
Hi, can you please help me. I have the problem that when i call action from action sometimes it’s failed with error code 4. Can you please explain me the reason and tell me what i can do in this situation. I don’t want to change the arch of the app.
Here is some code. First action caller. Just button which calls action:#include "mainwindow.h" #include "./ui_mainwindow.h" #include <QDebug> #include <KAuth> #include <QPushButton> using namespace KAuth; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QObject::connect(ui->pushButton, &QPushButton::pressed, [=]() { qInfo() << "Clicked"; static const auto actionName = QStringLiteral("test.helper.change"); static const auto actionHelperId = QStringLiteral("test.helper"); KAuth::Action action(actionName); action.setHelperId(actionHelperId); action.setArguments({}); auto job = action.execute(); if (!job->exec()) { qInfo() << "Error 1 lvl action"; qInfo() << job->errorString(); qInfo() << job->errorText(); qInfo() << "Erorr:" << job->error(); qInfo() << "Action:" << job->action().name(); } else { qInfo() << "No erorr at 1 lvl action"; } }); } MainWindow::~MainWindow() { delete ui; }
First helper code:
#include <QObject> #include <KAuth> #include <QDebug> using namespace KAuth; class Helper : public QObject { Q_OBJECT public slots: KAuth::ActionReply change(const QVariantMap &args); }; KAuth::ActionReply Helper::change(const QVariantMap &args) { qInfo() << "First lvl action start"; static const auto actionName = QStringLiteral("kcm.policycomplexity.change"); static const auto actionHelperId = QStringLiteral("kcm.policycomplexity"); KAuth::Action action(actionName); action.setHelperId(actionHelperId); action.setArguments({}); auto job = action.execute(); if (!job->exec()) { qInfo() << "Error 2 lvl action"; return ActionReply::HelperErrorReply(); } qInfo() << "First lvl action end"; return ActionReply::SuccessReply(); } KAUTH_HELPER_MAIN("test.helper", Helper) #include "test_helper.moc"
Second helper code:
#include <QObject> #include <KAuth/ActionReply> #include <KAuth/HelperSupport> #include "config.h" #include <QDebug> namespace PasswordComplexityPolicy { class Helper : public QObject { Q_OBJECT public slots: KAuth::ActionReply change(const QVariantMap &args); }; namespace { KAuth::ActionReply errorReply(const QString &errorDesc) { auto reply = KAuth::ActionReply::HelperErrorReply(); reply.setErrorDescription(errorDesc); return reply; } } // namespace KAuth::ActionReply Helper::change(const QVariantMap &args) { qInfo() << "2 lvl action start"; qInfo() << "2 lvl action end"; return KAuth::ActionReply::SuccessReply(); } } KAUTH_HELPER_MAIN("kcm.policycomplexity", PasswordComplexityPolicy::Helper) #include "helper.moc"
-
Possible Causes:
Missing Permissions: The actionName might not have the required permissions for execution. If the action requires elevated privileges (e.g., root permissions), it may fail if the helper is not running with appropriate privileges.Incorrect Helper Setup: The action.setHelperId(actionHelperId) part in both the caller and helper code needs to be aligned properly. If there is a mismatch in the helper ID or incorrect registration of the helper, the action might fail to execute correctly.
Failure in the Helper: If the second-level action fails, it can propagate back to the first-level action and cause it to fail with error code 4. Specifically, the error could occur because the second-level action (kcm.policycomplexity.change) failed.
Action Parameters: There may be an issue with the arguments being passed to the actions. You are passing an empty map action.setArguments({}), which might not be what the helper expects.
Debugging Steps:
Check Helper Permissions: Ensure the action test.helper.change and kcm.policycomplexity.change are properly set up in the polkit (PolicyKit) configuration, and that the appropriate permissions are granted for the user executing the application.Ensure Helper Registration: Verify that the helper (test.helper and kcm.policycomplexity) is correctly registered and accessible. In your case, make sure both helpers are properly registered using KAUTH_HELPER_MAIN.
Verbose Logging in Helpers: Add more logging in the helpers to make sure that the second-level action (kcm.policycomplexity.change) is executing as expected.
cpp
Copy
Edit
KAuth::ActionReply Helper::change(const QVariantMap &args)
{
qInfo() << "2 lvl action start";
// Log the args to verify if correct arguments are passed
qInfo() << "Arguments received:" << args;qInfo() << "2 lvl action end"; return KAuth::ActionReply::SuccessReply();
}
Check Polkit Configuration: Ensure that polkit has the correct rules and that the actions are authorized for the user. You might need to modify the /etc/polkit-1/rules.d/ or /usr/share/polkit-1/actions/ files to allow these actions.Return Error Information: If the second-level action fails, ensure it returns a detailed error message using ActionReply::HelperErrorReply():
cpp
Copy
Edit
if (!job->exec()) {
qInfo() << "Error in second-level action";
return ActionReply::HelperErrorReply().setErrorDescription("Second-level action failed");
}
Improve Error Handling in the Main Action Caller: Make sure you're capturing detailed error information from the first-level action. This can give insights into where the failure occurs:cpp
Copy
Edit
if (!job->exec()) {
qInfo() << "Error at 1st level action";
qInfo() << "Error string:" << job->errorString();
qInfo() << "Error description:" << job->errorText();
qInfo() << "Error code:" << job->error();
qInfo() << "Action name:" << job->action().name();
}
What to Do Next:
Check Polkit Permissions: Ensure the action and helper have the necessary permissions to execute. You can do this by checking the corresponding polkit rule files and ensuring the action is allowed for your user.Verify Arguments: If the helpers expect certain arguments, make sure you're passing them correctly.
More Detailed Logging: Add additional logging in both the main action and helper to capture the flow and identify exactly where the failure occurs.
Helper Execution: If you are using root privileges, ensure that the helper is properly set up to be executed with elevated privileges.
Ensure Proper Action Execution: If the second-level action fails, the error is propagated back to the first-level action. Use ActionReply::HelperErrorReply() in case of errors in the second-level helper and make sure that the first-level action can catch and handle it.