1#include <stdlib.h> 2#include <stdio.h> 3#include <errno.h> 4#include <sys/stat.h> 5#include <pwd.h> 6#include <unistd.h> 7#include <err.h> 8 9#include "dumpemacs.h" 10 11int decreasepriv(int debugflag); 12 13int runit(const char * const argv[], int dropprivs) 14{ 15 pid_t child; 16 int ret; 17 18 child = fork(); 19 if(child == 0) { 20 if(dropprivs && geteuid() == 0) { 21 ret = decreasepriv(0); 22 if(ret) 23 err(1, "failed to decrease privileges"); 24 25 } 26 27 ret = execve(argv[0], (char * const *) argv, 0); 28 if(ret) 29 err(1, "execve(%s) failed", argv[0]); 30 } else { 31 do { 32 int status = 0; 33 pid_t rch = waitpid(child, &status, 0); 34 if(rch == -1) 35 err(1, "waitpid(%d)", child); 36 37 if(WIFSTOPPED(status)) 38 continue; 39 40 if(WIFSIGNALED(status)) 41 errx(1, "child exited on signal %d", WTERMSIG(status)); 42 43 if(WIFEXITED(status)) { 44 if(WEXITSTATUS(status) == 0) 45 break; // success 46 else 47 errx(1, "child exited with status %d", WEXITSTATUS(status)); 48 } 49 50 } while(1); 51 } 52 53 return 0; 54} 55 56 57int decreasepriv(int debugflag) 58{ 59 struct passwd *nobody = NULL; 60 int ret; 61 62 nobody = getpwnam("nobody"); 63 if(nobody == NULL) 64 err(1, "getpwnam(nobody) failed"); 65 66 67 ret = initgroups(nobody->pw_name, nobody->pw_gid); 68 if(ret) 69 err(1, "initgroups() failed"); 70 71 ret = setgid(nobody->pw_gid); 72 if(ret) 73 err(1, "setgid() failed"); 74 75 ret = setuid(nobody->pw_uid); 76 if(ret) 77 err(1, "setuid() failed"); 78 79 80 // system("id"); 81 82 return 0; 83} 84