su in a non-interactive shell

Today I faced a problem which lead to a new insight for me.
I lost some private key to a particular server and was no longer able to login because password based authentication was disabled.
However I was still able to upload and run some scripts with a non-root user.

So the first idea to get ssh access again was to upload a script with something like

echo rootpassword | su -c „add new key to authorized keys“ – root

Unfortunately it turned out that su does only work within interactive shells and i got some message like:
’su must be run from terminal‘

After a quick search I found a solution on stackoverflow:
http://stackoverflow.com/questions/36944634/su-command-in-docker-returns-must-be-run-from-terminal/38741297#38741297

sh -c „sleep 1; echo ROOT_PASSWORD“ | script -qc „su -c ‚add new key to authorized keys‘ – root“ | tail -n +2

This solution work by using ’script‘ command from the ‚bsdutiles‘ package that setup a pty (a terminal). The ’sleep‘ command is there to prevent sending the password before the ’su‘ command is ready to read it. The ‚tail‘ command remove the „Password:“ input line issued by ’su‘.

Beware that the ‚ROOT_PASSWORD‘ could be see in many ways (history, ps, /proc/, etc…). Start the command with a space to at least avoid history recording.