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