execute_program.c revision 28f60197b93b45422a73e5d1a6aa581584d6c4a5
1#include <stdio.h> 2#include <sys/types.h> 3#include <sys/stat.h> 4#include <unistd.h> 5#include <errno.h> 6#include <string.h> 7#include <pwd.h> 8#include <grp.h> 9 10#include "ltrace.h" 11#include "options.h" 12#include "output.h" 13#include "sysdep.h" 14 15static void change_uid(struct process * proc); 16 17void execute_program(struct process * sp, char **argv) 18{ 19 int pid; 20 21 if (opt_d) { 22 output_line(0, "Executing `%s'...", sp->filename); 23 } 24 25 pid = fork(); 26 if (pid<0) { 27 perror("fork"); 28 exit(1); 29 } else if (!pid) { /* child */ 30 trace_me(); 31 change_uid(sp); 32 execvp(sp->filename, argv); 33 fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, strerror(errno)); 34 exit(1); 35 } 36 37 if (opt_d) { 38 output_line(0, "PID=%d", pid); 39 } 40 41 sp->pid = pid; 42 43 return; 44} 45 46static void change_uid(struct process * proc) 47{ 48 uid_t run_uid, run_euid; 49 gid_t run_gid, run_egid; 50 51 if (opt_u) { 52 struct passwd *pent; 53 54 if (getuid() != 0 || geteuid() != 0) { 55 fprintf(stderr, "you must be root to use the -u option\n"); 56 exit(1); 57 } 58 if ((pent = getpwnam(opt_u)) == NULL) { 59 fprintf(stderr, "cannot find user `%s'\n", opt_u); 60 exit(1); 61 } 62 run_uid = pent->pw_uid; 63 run_gid = pent->pw_gid; 64 65 if (initgroups(opt_u, run_gid) < 0) { 66 perror("initgroups"); 67 exit(1); 68 } 69 } else { 70 run_uid = getuid(); 71 run_gid = getgid(); 72 } 73 if (opt_u || !geteuid()) { 74 struct stat statbuf; 75 run_euid = run_uid; 76 run_egid = run_gid; 77 78 if (!stat(proc->filename, &statbuf)) { 79 if (statbuf.st_mode & S_ISUID) { 80 run_euid = statbuf.st_uid; 81 } 82 if (statbuf.st_mode & S_ISGID) { 83 run_euid = statbuf.st_gid; 84 } 85 } 86 if (setregid(run_gid, run_egid) < 0) { 87 perror("setregid"); 88 exit(1); 89 } 90 if (setreuid(run_uid, run_euid) < 0) { 91 perror("setreuid"); 92 exit(1); 93 } 94 } 95} 96