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