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