The procedure described here (which may itself be an imperfect copy of this Ask Ubuntu answer) performed the miracle. I'm copying it here, and adding some more explanations.
Procedure
Open two SSH sessions to the target server.
In the first session, get the PID of bash by running:
echo $$
In the second session, start the authentication agent with:
pkttyagent --process 29824
Use the pid obtained from step 1.
Back in the first session, run:
pkexec chown root:root /etc/sudoers /etc/sudoers.d -R
Enter the password in the second session password promt.
Explanation
Similar to sudo
, pkexec
allows an authorized user to execute a program as another user, typically root
. It uses polkit for authentication; in particular, the org.freedesktop.policykit.exec
action is used.
This action is defined in /usr/share/polkit-1/actions/org.freedesktop.policykit.policy
:
<action id="org.freedesktop.policykit.exec">
<description>Run programs as another user</description>
<message>Authentication is required to run a program as another user</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
auth_admin
means that an administrative user is allowed to perform this action. Who qualifies as an administrative user?
On this particular system (Ubuntu 16.04), that is configured in /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
:
[Configuration]
AdminIdentities=unix-group:sudo;unix-group:admin
So any user in the group sudo
or admin
can use pkexec
.
On a newer system (Arch Linux), it's in /usr/share/polkit-1/rules.d/50-default.rules
:
polkit.addAdminRule(function(action, subject) {
return ["unix-group:wheel"];
});
So here, everyone in the wheel
group is an administrative user.
In the pkexec
manual page, it states that if no authentication agent is found for the current session, pkexec
uses its own textual authentication agent, which appears to be pkttyagent
. Indeed, if you run pkexec
without first starting the pkttyagent
process, you are prompted for a password in the same shell but it fails after entering the password:
polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie
This appears to be an old bug in polkit that doesn't seem to be getting any traction. More discussion.
The trick of using two shells is merely a workaround for this issue.
sudoers
file. I check in another CLI that I can stillsudo ls
to avoid getting locked-out. If thesudoers
file is broken, I'm still editing it in another process and can fix the error.visudo
instead, it does all that for you./etc/sudoers.d/
by a script I was working on. I had to move the root volume to another EC2 instance to rescue myself. 🤦visudo
does not protect against broken automation. Nor against disk corruption -- as turned out to be the case in my situation, but even that was hard to figure out without root access :)