[TriLUG] Help with setuid C wrapper script

Ron Kelley rkelleyrtp at gmail.com
Sun Oct 10 09:03:49 EDT 2010


Greetings all,

I need to allow a non-root user to run a couple of system commands and would like to use a setuid C wrapper binary.  I have searched over the 'net and have found the following sample code.  Unfortunately, I get segmentation faults if no command arguments are passed in.   Since I am not a C programmer, I was hoping someone could help me fine-tune the utility.  

For some reason, this code requires the "-v" CLI argument.  I would prefer to just pass in the necessary arguments without the "-v".  In addition, if no arguments (or, unknown/invalid args) are passed in, I want the utility to exit immediately.  I want the ability to add additional commands in the future, so I need it to be flexible enough to parse the args instead of writing a single wrapper per external command.

Example:

#> wrapper my_command
<runs the "my_command" command>

#> wrapper another_command
<runs the "another_command" command>

#> wrapper 
<exits immediately>

#> wrapper -h
<exits immediately - no error output>


---------------------------------------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <strings.h>
#include <stdlib.h>

/********************************************
* Inspired by: 
* http://linuxshellaccount.blogspot.com/2007/12/securing-suid-programs-using-simple-c.html *
********************************************/

/* Define global variables */

int gid;

/* main(int argc, char **argv) - main process loop */

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

   /* Set uid, gid, euid and egid to root */

   setegid(0);
   seteuid(0);
   setgid(0);
   setuid(0);

   if ( strncmp(argv[1], "my_command", 11) == 0 ) {
      if (execl("/usr/local/bin/my_command", "my_command", "-v", NULL) < 0) {
         perror("Execl:");
      }
   } else if ( strncmp(argv[1], "another_command", 15) == 0 ) {
      if (execl("/usr/local/bin/another_command", "another_command", "-v", NULL) < 0) {
         perror("Execl:");
   }
   } else {
   exit (1);
   }
exit (0);
}
---------------------------------------------------------------------------------------------------------------------------------------





Thanks for any help,

-Ron



More information about the TriLUG mailing list