diff options
author | Juan Cespedes <cespedes@debian.org> | 1998-03-10 00:08:41 +0100 |
---|---|---|
committer | Juan Cespedes <cespedes@debian.org> | 1998-03-10 00:08:41 +0100 |
commit | e188705c4f1c5c8e377c2438114a99acaeaf8a3a (patch) | |
tree | c64b320ce52c94d39000a23c989fccd32bef8554 /execute_program.c | |
parent | 5e01f654d83a95f2acffa86df57a4c2db9b0cae9 (diff) | |
download | ltrace-e188705c4f1c5c8e377c2438114a99acaeaf8a3a.tar.gz |
Version 0.2.1
* Added -u option (run command as other username)
* Updated manual page a bit
Diffstat (limited to 'execute_program.c')
-rw-r--r-- | execute_program.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/execute_program.c b/execute_program.c index 02d6471..d451f7b 100644 --- a/execute_program.c +++ b/execute_program.c @@ -1,13 +1,19 @@ #include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <string.h> +#include <pwd.h> +#include <grp.h> #include "ltrace.h" #include "options.h" #include "output.h" #include "sysdep.h" +static void change_uid(struct process * proc); + void execute_program(struct process * sp, char **argv) { int pid; @@ -21,6 +27,7 @@ void execute_program(struct process * sp, char **argv) perror("fork"); exit(1); } else if (!pid) { /* child */ + change_uid(sp); trace_me(); execvp(sp->filename, argv); fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, strerror(errno)); @@ -35,3 +42,54 @@ void execute_program(struct process * sp, char **argv) return; } + +static void change_uid(struct process * proc) +{ + uid_t run_uid, run_euid; + gid_t run_gid, run_egid; + + if (opt_u) { + struct passwd *pent; + + if (getuid() != 0 || geteuid() != 0) { + fprintf(stderr, "you must be root to use the -u option\n"); + exit(1); + } + if ((pent = getpwnam(opt_u)) == NULL) { + fprintf(stderr, "cannot find user `%s'\n", opt_u); + exit(1); + } + run_uid = pent->pw_uid; + run_gid = pent->pw_gid; + + if (initgroups(opt_u, run_gid) < 0) { + perror("initgroups"); + exit(1); + } + } else { + run_uid = getuid(); + run_gid = getgid(); + } + if (opt_u || !geteuid()) { + struct stat statbuf; + run_euid = run_uid; + run_egid = run_gid; + + if (!stat(proc->filename, &statbuf)) { + if (statbuf.st_mode & S_ISUID) { + run_euid = statbuf.st_uid; + } + if (statbuf.st_mode & S_ISGID) { + run_euid = statbuf.st_gid; + } + } + if (setregid(run_gid, run_egid) < 0) { + perror("setregid"); + exit(1); + } + if (setreuid(run_uid, run_euid) < 0) { + perror("setreuid"); + exit(1); + } + } +} |