Search code examples
linuxsystemd

how can I call "systemd-run" "--user" ... from execvp() (in c or c++) without requiring password


When I call systemd-run "--user" "--pipe" "echo" "hello" I get the expected output "hello" (plus some systemd unit info) without a password popup.

But when I run systemd-run using the exact same arguments from inside a C++ program via execvp() or execvpe() it launches a popup window with Authentication is required to start transient unit.

Example:

#include <unistd.h>

int main(int argc, char const* const argv[], char const* const envp[])
    {
        char const* argp[] =
            {
                "--user",
                "--pipe",
                "echo",
                "hello",
                nullptr,
            };
        
        //::execvp("systemd-run", const_cast<char**>(argp)); // alternative call, same result
        ::execvpe("systemd-run", const_cast<char**>(argp), const_cast<char**>(envp));
    }

Can I avoid this authentication popup requirement (while still using C++)? Preferably using a default systemd with no policy modification.


(I'm trying to make a quick tool to run a subcommand while preventing accidental file modification outside of specified directories, eg for a "safe" build).


Solution

  • The program is missing in argp, try this :

    #include <unistd.h>
    
    int main(int argc, char const* const argv[], char const* const envp[])
        {
            char const* argp[] =
                {
                    "systemd-run", // <=========== notice this.
                    "--user",
                    "--pipe",
                    "echo",
                    "hello",
                    nullptr,
                };
            
            //::execvp("systemd-run", const_cast<char**>(argp)); // alternative call, same result
            ::execvpe("systemd-run", const_cast<char**>(argp), const_cast<char**>(envp));
        }
    

    Your version is running this command: systemd-run --pipe echo hello, reason why it asks for password.