aboutsummaryrefslogtreecommitdiff
path: root/execute_program.c
diff options
context:
space:
mode:
authorJuan Cespedes <cespedes@debian.org>1998-03-10 00:08:41 +0100
committerJuan Cespedes <cespedes@debian.org>1998-03-10 00:08:41 +0100
commite188705c4f1c5c8e377c2438114a99acaeaf8a3a (patch)
treec64b320ce52c94d39000a23c989fccd32bef8554 /execute_program.c
parent5e01f654d83a95f2acffa86df57a4c2db9b0cae9 (diff)
downloadltrace-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.c58
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);
+ }
+ }
+}