6

I develop a C code on Linux (Debian). Time to time, I need to execute some commands through system()

I wonder if it is possible to execute a command via system()as root. If it is not the case, is there any function to execute a command (or run a binary) as root that I can use on the C code?

Angs
  • 1,605
  • 2
  • 23
  • 47

3 Answers3

4

We met the situation before that we want to execute a root command by a normal user, here is our solution (using setuid/SUID):

assume that:

  • username: Tom
  • group: gTom
  • C program file: my_pro.c

Step 1: Write a C code tool: my_sudo.c

...
int main(int args, char *argv[]) {
    if (args < 2) 
        printf("Usage: my_sudo [cmd] [arg1 arg2 ...]");

    // cmd here is the shell cmd that you want execute in "my_pro"
    // you can check the shell cmd privilege here
    // example:  if (argv[1] != "yum") return; we just allow yum execute here

    char cmd[MAX_CMD];
    int i;
    for ( i = 2; i < args; i ++) {
    // concatenate the cmd, example: "yum install xxxxx"
        strcat(cmd, " ");
        strcat(cmd, argv[i]);
    }

    system(cmd);
} 

Step 2: Compile my_sudo.c to get a my_sudo executable file

   sudo chown root:gTom my_sudo   // user root && gTom group
   sudo chmod 4550 my_sudo        // use SUID to get root privilege

   #you will see my_sudo like this(ls -l)
   #-r-sr-x--- 1 root my_sudo 9028 Jul 19 10:09 my_sudo*

   #assume we put my_sudo to /usr/sbin/my_sudo

Step 3: In your C code

...
int main() {
    ...
    system("/usr/bin/mysudo yum install xxxxx");
    ...
}

#gcc && ls -l
#-rwxr--r--  1 Tom gTom 1895797 Jul 23 13:55 my_pro

Step 4: Execute./my_pro

You can execute the yum install without sudo.

perror
  • 7,071
  • 16
  • 58
  • 85
Yifan Wang
  • 504
  • 6
  • 13
  • 6
    ⚠ Ouch! you're concatenating the arguments as a shell command line! Then the user can do `mysudo 'arg;sh'` to get a `root` shell for instance. And you're not sanitizing the environment like `sudo` would. – Stephane Chazelas Jan 28 '15 at 16:08
1

If you are a user on your system that has sudo privileges to run commands as root, just pre-pend sudo to the command.

system("sudo yum install some-package");

If you want anybody to be able to do it, then you have to be administrator on your system, change the owner of the file to be root, and modify the permissions of your executable to run as root. By doing so, you do not need to modify your system() command string with sudo.

chmod +s my_program
chown root my_program

Realize that doing this may open you up to security problems, unless you have proven that your program has no security issues.

The file-system may be such to disallow you from setting the setuid bit on your program. If you need more information along these lines, you should consult SuperUser.

Community
  • 1
  • 1
jxh
  • 69,070
  • 8
  • 110
  • 193
  • if the program is started by a non-root user, would it be possible to get the root privilege by passing the root password through the C code? Then how? – Angs Jul 23 '13 at 23:29
  • If you are assuming the user has the root password, then they can just run the command as root themselves. – jxh Jul 23 '13 at 23:33
  • I know it is possible to run the executable program as root then the program will have the root privilege to call functions. But I wonder if it is possible to get the root privilege to execute a command by using a C or Posix function when the program is started as non-root. – Angs Jul 23 '13 at 23:42
  • If the program was not written to be a SUID-root program, simply making it SUID-root is likely to lead to major security problems. Few programs not written specifically with SUID-root status in mind are safe when made SUID-root (and those that are safe generally don't need to be SUID-root in the first place). – Jonathan Leffler Jul 23 '13 at 23:44
  • I have updated my answer on how to make your program run as root. Johnathan is correct, it is unsafe to do this unless because of the security risks. – jxh Jul 23 '13 at 23:48
  • I see that it would be a bad application or not recommended to do it so. But, what I really would like to learn is that if it is possible to do it by any means. Btw, if the program has already root privilege, I guess I would not need to append su or sudo. – Angs Jul 23 '13 at 23:57
  • @angs: That is right, you do not need to prepend `sudo` or `su` if the program is `setuid` as `root`. – jxh Jul 23 '13 at 23:57
  • @jxh: it is not what I asked for. If the program has already root privilege, then there would not be any issue to use system. What I asked is that is there any function to execute a command or a run a program as root (assuming that the program is started as non-root) – Angs Jul 24 '13 at 00:04
  • 1
    There is no **function** that can change the EUID from non-root to root — unless the program was originally started as root and therefore has a saved UID of root. See [`getuid()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html) and [`setuid()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html) and relatives for more information. Running the `sudo` program as a prefix to the command you want executed is about the only sane way to do it. (There are various more or less insane ways to do it, but programs run as root are liabilities, major liabilities). – Jonathan Leffler Jul 24 '13 at 00:08
  • As a f'rinstance: if you run a program that lets the user run `vim`, then you've granted the user `root`-shell privileges on the machine. This is typically frowned upon by those who administer root privileges. – Jonathan Leffler Jul 24 '13 at 00:09
  • @angs: If you want a "safe" solution, you have to review all the programs that you are going to call `system()` on as root. Then, you can create a new user on your system for the purpose of running this program. You can add this new user to the `sudo` list without need for password, but specify exactly which commands it is allowed to run. This list would match what your program will be calling `system()` on. Then prepend your `system()` commands with `sudo`, and set the `setuid` bit on the executable, and `chown` it to the new user. – jxh Jul 24 '13 at 00:15
  • @angs: Realize, this scheme is still a security hole waiting to happen, but it makes you think about the programs that will be running as root, and check that they are safe to run as root. – jxh Jul 24 '13 at 00:17
1

This is one of those bag-o-tricks things to keep in mind. There are security risks, so just be aware of who will use it. In the "system" command you can even execute external scripts...although that opens major security risks because while this binary has to have the permissions re-set every time it's compiled, a script can be changed endlessly and this binary will keep calling it.

#include <stdio.h>
#include <stdlib.h>

//Create as root
//gcc fixmusic.c -o fixmusic 
//chmod u+s fixmusic
//now run as non-root user and it should work despite limitations of user


int main(int argc, char *argv[] )
{

    setuid(0);

    char command[100];
    sprintf(command,"/usr/bin/chmod -R a+w /mnt/Local/Music");
    system(command);
    //This is just optional info if someone cat's the binary
    volatile const char comment [] = "INFO: Fixes music permissions";
    return 0;
}
Westrock
  • 169
  • 4
  • 14