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