Search code examples
cpermissionsexecrootdaemon

How to run an exec() function as root and non-interactive?


I am looking to fork() and exec with root privlages. It seems that privileges are not passed from the main thread once an exec function is called.

Now I have seen the post here that describes how to run a process as root, but when I try their solution..

char sudo[]="/usr/bin/sudo";
char pbin[]="/usr/local/bin/puppet";
execl(sudo,sudo,pbin,(char *)NULL);

The sudo command prompts for daemon's password. I am looking for non-interactive way to run the process as root. Is there anyway to do this short of removing Daemon's password?


Solution

  • To test the premise of your question that,

    "It seems that privileges are not passed from the main thread once an exec function is called."

    I wrote the following test code,

    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>
    
    int main() {
    //    printf("starting");
        char sudo[]="/usr/bin/sudo";
        char pbin[]="mkdir";
    
    //    printf("running test: %s %s",sudo,pbin);
        errno=0;
    
        if (fork() == 0) {
            int res = execl(sudo,sudo,pbin,"/bin/child",(char *)NULL);
    //        printf("res:%d", res);
        }
        else {
            sleep(2);
            int res = execl(sudo,sudo,pbin,"/bin/parent",(char *)NULL);
    //        printf("res:%d", res);
        }
    }
    

    And to my surprise, it worked without a problem, giving the following output:

    $ sudo rm /bin/parent -rf ; sudo rm -rf /bin/child/
    $ ls /bin/child/ -la
    ls: cannot access '/bin/child/': No such file or directory
    $ ls /bin/parent/ -la
    ls: cannot access '/bin/parent/': No such file or directory
    
    $ gcc main.c
    $ sudo ./a.out
    
    $ ls /bin/parent -la
    total 8 drwxr-xr-x 2 root root 4096 Mar  6 11:42 . 
    drwxr-xr-x 4 root root 4096 Mar  6 11:42 ..
    $ ls /bin/child -la 
    total 8 drwxr-xr-x 2 root root 4096 Mar  6 11:42 .
    drwxr-xr-x 4 root root 4096 Mar  6 11:42 ..
    

    As you can see there is a directory created by the parent process as well as the child process with root privileges.


    Which got me thinking that your problem is in fact something else, as you state:

    "The sudo command prompts for daemon's password. I am looking for non-interactive way to run the process as root. Is there anyway to do this short of removing Daemon's password?"

    What you really want is a password-less sudo, which can be obtained by running

    sudo visudo
    

    and then adding the line:

    ALL     ALL=(ALL) NOPASSWD: ALL
    

    making your sudoers file looking like this.

    #
    # This file MUST be edited with the 'visudo' command as root.
    #
    # Please consider adding local content in /etc/sudoers.d/ instead of
    # directly modifying this file.
    #
    # See the man page for details on how to write a sudoers file.
    #
    Defaults    env_reset
    Defaults    mail_badpass
    Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
    
    # Host alias specification
    
    # User alias specification
    
    # Cmnd alias specification
    
    # User privilege specification
    root    ALL=(ALL:ALL) ALL
    
    # Members of the admin group may gain root privileges
    %admin ALL=(ALL) ALL
    
    # Allow members of group sudo to execute any command
    %sudo   ALL=(ALL:ALL) ALL
    
    ALL ALL=(ALL) NOPASSWD: ALL
    # See sudoers(5) for more information on "#include" directives:
    
    #includedir /etc/sudoers.d