Search code examples
javaunixrootsudo

Standard input through sudo


I'm writing a Java program that calls other programs, and some of them need to be ran as root.

I thought about running the whole JAR as root but that sounds like a security risk, I'd rather run just some programs as root.

Currently, I create a ProcessBuilder and use its getStandardOutput method to instantiate a Writer, on the command sudo -S pacman <...>. (-S means ‘read from standard input’).

I then inject the password using that reader and flush it, so far so good.

However, when pacman expects input (for example when asking an interactive yes/no question), and I try to write to the Writer again, it fails with IOException because the stream is closed.

How can I get a Writer that can actually send characters to pacman and other programs ran as root?

This program is only expected to run on UNIX (Arch Linux, Debian, MacOS and maybe Window's WSL) so UNIX-specific solutions are fine, if possible I'd rather not use JNI because it requires to compile multiple times, but if that's the only solution it's fine. I'm also fine replacing sudo with something else as long as it's still ran as root.


Solution

  • If this is not a long-lived service, you could run sudo -v to have sudo cache the credentials and then invoke sudo in your Java program without needing to enter a password. This would work best if you invoked your Java program with something like:

    #!/bin/bash
    
    sudo -v
    java -jar ...