[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