| 1 | /* |
| 2 | * SU-EXEC Wrapper |
| 3 | * Execute script under it's owner's privileges |
| 4 | * CopyLefted by: Harvie 2oo9 |
| 5 | */ |
| 6 | |
| 7 | #include <stdio.h> |
| 8 | #include <stdlib.h> |
| 9 | #include <unistd.h> |
| 10 | #include <sys/types.h> |
| 11 | #include <sys/stat.h> |
| 12 | #include <pwd.h> |
| 13 | #include <grp.h> |
| 14 | |
| 15 | #define INTERPRETER "/usr/bin/php-cgi" |
| 16 | //#define INTERPRETER "/usr/bin/perl" |
| 17 | |
| 18 | void auth_fail() { |
| 19 | puts("Error: Permission denied!\n"); |
| 20 | exit(-1); |
| 21 | } |
| 22 | |
| 23 | int main(int argc, char **argv, char **environ) { |
| 24 | if(argc != 2) { //Do not accept more than one argument |
| 25 | printf( |
| 26 | "SetUID wrapper for %s interpretter\n" |
| 27 | "Usage: %s script\n\n", |
| 28 | INTERPRETER, argv[0] |
| 29 | ); |
| 30 | return -1; |
| 31 | } |
| 32 | struct stat st; |
| 33 | if(!stat(argv[1], &st)) { |
| 34 | //Get user info |
| 35 | struct passwd *pw; |
| 36 | if(!(pw = getpwuid(st.st_uid))) auth_fail(); |
| 37 | //Change groups |
| 38 | if(initgroups(pw->pw_name, pw->pw_gid)) auth_fail(); |
| 39 | //Change UID a GID |
| 40 | if(setgid(pw->pw_gid)) auth_fail(); |
| 41 | if(setegid(pw->pw_gid)) auth_fail(); |
| 42 | if(setuid(pw->pw_uid)) auth_fail(); |
| 43 | if(seteuid(pw->pw_uid)) auth_fail(); |
| 44 | //Fail if still have root privileges |
| 45 | if(getuid() == 0 || getgid() == 0) auth_fail(); |
| 46 | //Launch binary |
| 47 | return(execve(INTERPRETER, argv, environ)); |
| 48 | } else { |
| 49 | printf("Error: Can't stat file: %s\n\n", argv[1]); |
| 50 | return -1; |
| 51 | } |
| 52 | } |