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