Three-pillar fix from Hamilton review: Code quality — validate_signature() for D-Bus spec compliance, MCDBUS_TIMEOUT env var, replace 13 error-as-success returns with ToolError, monotonic clock deadline on tree walks, sanitize D-Bus error messages, fix resource connection leak via module-level BusManager, hasattr guards in conftest. Elicitation — ctx.elicit() confirmation for system bus call_method and all set_property calls, graceful degradation when client lacks elicitation support, MCDBUS_REQUIRE_ELICITATION for hard-fail mode. Permission docs — four-layer guide (systemd sandboxing, dbus-broker policy, polkit rules, xdg-dbus-proxy) with ready-to-deploy example configs validated against xmllint, bash -n, and systemd-analyze.
89 lines
2.9 KiB
Plaintext
89 lines
2.9 KiB
Plaintext
// polkit rules for mcdbus
|
|
//
|
|
// Drop into /etc/polkit-1/rules.d/50-mcdbus.rules and restart polkit:
|
|
// sudo systemctl restart polkit.service
|
|
//
|
|
// Users in the "mcdbus" group get read-only access to common system
|
|
// services. Everything else falls through to system defaults (which
|
|
// typically require admin authentication or deny).
|
|
//
|
|
// Create the group:
|
|
// sudo groupadd mcdbus
|
|
// sudo usermod -aG mcdbus youruser
|
|
//
|
|
// Test with:
|
|
// pkcheck --action-id org.freedesktop.systemd1.manage-units \
|
|
// --process $$ --allow-user-interaction
|
|
//
|
|
// List all actions:
|
|
// pkaction | grep -E 'systemd|NetworkManager|UPower|udisks'
|
|
|
|
polkit.addRule(function(action, subject) {
|
|
|
|
// Only apply to users in the mcdbus group
|
|
if (!subject.isInGroup("mcdbus")) {
|
|
return polkit.Result.NOT_HANDLED;
|
|
}
|
|
|
|
// Read-only systemd operations
|
|
// ListUnits, GetUnit, GetUnitProperties -- these do not change state.
|
|
var systemdReadActions = [
|
|
"org.freedesktop.systemd1.manage-units",
|
|
"org.freedesktop.systemd1.reload-daemon"
|
|
];
|
|
|
|
// NetworkManager: allow reading connection and device info
|
|
var nmReadActions = [
|
|
"org.freedesktop.NetworkManager.network-control",
|
|
"org.freedesktop.NetworkManager.settings.modify.system"
|
|
];
|
|
|
|
// UPower: allow reading battery status
|
|
var upowerActions = [
|
|
"org.freedesktop.upower.get-history",
|
|
"org.freedesktop.upower.get-statistics"
|
|
];
|
|
|
|
// UDisks2: allow reading disk info but not mounting/formatting
|
|
var udisksReadActions = [
|
|
"org.freedesktop.udisks2.ata-smart-selftest"
|
|
];
|
|
|
|
// Allow read-only systemd access
|
|
// NOTE: systemd1.manage-units covers both read and write operations.
|
|
// If you only want list/status (no start/stop/restart), you need
|
|
// Layer 2 (D-Bus bus policy) to restrict which methods can be called.
|
|
// polkit alone cannot distinguish between "list units" and "stop unit"
|
|
// under the same action ID.
|
|
if (systemdReadActions.indexOf(action.id) >= 0) {
|
|
// Only allow for local, active sessions
|
|
if (subject.local && subject.active) {
|
|
return polkit.Result.YES;
|
|
}
|
|
}
|
|
|
|
// Allow NetworkManager reads for local sessions
|
|
if (nmReadActions.indexOf(action.id) >= 0) {
|
|
if (subject.local && subject.active) {
|
|
return polkit.Result.YES;
|
|
}
|
|
}
|
|
|
|
// Allow UPower reads
|
|
if (upowerActions.indexOf(action.id) >= 0) {
|
|
return polkit.Result.YES;
|
|
}
|
|
|
|
// Allow UDisks2 reads
|
|
if (udisksReadActions.indexOf(action.id) >= 0) {
|
|
if (subject.local && subject.active) {
|
|
return polkit.Result.YES;
|
|
}
|
|
}
|
|
|
|
// Everything else: fall through to system defaults.
|
|
// Do NOT return polkit.Result.NO here -- that would override rules
|
|
// with lower priority numbers. NOT_HANDLED lets the chain continue.
|
|
return polkit.Result.NOT_HANDLED;
|
|
});
|