Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dnfdaemon: Allow configuration overrides for root #1235

Merged
merged 1 commit into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dnf5daemon-server/dbus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ const char * const SIGNAL_TRANSACTION_FINISHED = "transaction_finished";
const char * const POLKIT_REPOCONF_WRITE = "org.rpm.dnf.v0.rpm.RepoConf.write";
const char * const POLKIT_EXECUTE_RPM_TRANSACTION = "org.rpm.dnf.v0.rpm.execute_transaction";
const char * const POLKIT_CONFIRM_KEY_IMPORT = "org.rpm.dnf.v0.rpm.Repo.confirm_key";
const char * const POLKIT_CONFIG_OVERRIDE = "org.rpm.dnf.v0.base.Config.override";

// errors
const char * const ERROR = "org.rpm.dnf.v0.Error";
Expand Down
10 changes: 10 additions & 0 deletions dnf5daemon-server/polkit/org.rpm.dnf.v0.policy
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,14 @@
<allow_active>auth_admin</allow_active>
</defaults>
</action>

<action id="org.rpm.dnf.v0.base.Config.override">
<description>Override libdnf5 configuration options</description>
<message>Authentication is required to override libdnf5 configuration options.</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
</policyconfig>
21 changes: 16 additions & 5 deletions dnf5daemon-server/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include <chrono>
#include <iostream>
#include <optional>
#include <string>

// config options that regular user can override for their session.
static const std::unordered_set<std::string> ALLOWED_MAIN_CONF_OVERRIDES = {
"allow_downgrade",
"allow_vendor_change",
Expand Down Expand Up @@ -88,6 +90,7 @@ Session::Session(
std::map<std::string, std::string> default_overrides{};
auto conf_overrides = session_configuration_value<std::map<std::string, std::string>>("config", default_overrides);
auto opt_binds = config.opt_binds();
std::optional<bool> am_i_root;
for (auto & opt : conf_overrides) {
auto key = opt.first;
auto value = opt.second;
Expand All @@ -96,8 +99,16 @@ Session::Session(
if (ALLOWED_MAIN_CONF_OVERRIDES.find(key) != ALLOWED_MAIN_CONF_OVERRIDES.end()) {
bind->second.new_string(libdnf5::Option::Priority::RUNTIME, value);
} else {
base->get_logger()->warning("Config option {} not allowed.", key);
continue;
if (!am_i_root.has_value()) {
// check the authorization lazily only once really needed
am_i_root = check_authorization(dnfdaemon::POLKIT_CONFIG_OVERRIDE, sender, false);
}
// restricted config options override is allowed only for root
if (am_i_root.value()) {
bind->second.new_string(libdnf5::Option::Priority::RUNTIME, value);
} else {
base->get_logger()->warning("Config option {} not allowed.", key);
}
}
} else {
base->get_logger()->warning("Unknown config option: {}", key);
Expand Down Expand Up @@ -231,21 +242,21 @@ bool Session::read_all_repos() {
return retval;
}

bool Session::check_authorization(const std::string & actionid, const std::string & sender) {
bool Session::check_authorization(
const std::string & actionid, const std::string & sender, bool allow_user_interaction) {
// create proxy for PolicyKit1 object
const std::string destination_name = "org.freedesktop.PolicyKit1";
const std::string object_path = "/org/freedesktop/PolicyKit1/Authority";
const std::string interface_name = "org.freedesktop.PolicyKit1.Authority";
// allow polkit to ask user to enter root password
const uint ALLOW_USER_INTERACTION = 1;
auto polkit_proxy = sdbus::createProxy(connection, destination_name, object_path);
polkit_proxy->finishRegistration();

// call CheckAuthorization method
sdbus::Struct<bool, bool, std::map<std::string, std::string>> auth_result;
sdbus::Struct<std::string, dnfdaemon::KeyValueMap> subject{"system-bus-name", {{"name", sender}}};
std::map<std::string, std::string> details{};
uint flags = ALLOW_USER_INTERACTION;
uint flags = allow_user_interaction ? 1 : 0;
std::string cancelation_id = "";
polkit_proxy->callMethod("CheckAuthorization")
.onInterface(interface_name)
Expand Down
3 changes: 2 additions & 1 deletion dnf5daemon-server/session.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ class Session {
};
std::string get_sender() const { return sender; };

bool check_authorization(const std::string & actionid, const std::string & sender);
bool check_authorization(
const std::string & actionid, const std::string & sender, bool allow_user_interaction = true);
void fill_sack();
bool read_all_repos();
std::optional<std::string> session_locale;
Expand Down
Loading