// 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; });