Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trace-cmd-record: Add option to run command as a different user #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Documentation/trace-cmd-record.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ OPTIONS
executed will not be changed. This is useful if you want to monitor the
output of the command being executed, but not see the output from trace-cmd.

*--user*::
Run the command as the specified user. Useful to avoid running the
traced command as root.

EXAMPLES
--------

Expand Down
19 changes: 17 additions & 2 deletions tracecmd/trace-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <errno.h>
#include <limits.h>
#include <libgen.h>
#include <pwd.h>

#include "trace-local.h"
#include "trace-msg.h"
Expand Down Expand Up @@ -1191,7 +1192,7 @@ static void trace_or_sleep(enum trace_type type)
sleep(10);
}

static void run_cmd(enum trace_type type, int argc, char **argv)
static void run_cmd(enum trace_type type, uid_t euid, int argc, char **argv)
{
int status;
int pid;
Expand All @@ -1212,6 +1213,10 @@ static void run_cmd(enum trace_type type, int argc, char **argv)
dup2(save_stdout, 1);
close(save_stdout);
}
if (setuid(euid))
die("Failed to setuid to %d: %s", euid, strerror(errno));
if (seteuid(euid))
die("Failed to seteuid to %d: %s", euid, strerror(errno));
if (execvp(argv[0], argv)) {
fprintf(stderr, "\n********************\n");
fprintf(stderr, " Unable to exec %s\n", argv[0]);
Expand Down Expand Up @@ -4298,6 +4303,7 @@ enum {
OPT_funcstack = 254,
OPT_date = 255,
OPT_module = 256,
OPT_euid = 257,
};

void trace_stop(int argc, char **argv)
Expand Down Expand Up @@ -4485,6 +4491,7 @@ struct common_record_context {
int manual;
int topt;
int do_child;
uid_t euid;
int run_command;
};

Expand Down Expand Up @@ -4518,6 +4525,7 @@ static void parse_record_options(int argc,
char *pid;
char *sav;
int neg_event = 0;
struct passwd *pw;

init_common_record_context(ctx, curr_cmd);

Expand All @@ -4539,6 +4547,7 @@ static void parse_record_options(int argc,
{"quiet", no_argument, NULL, OPT_quiet},
{"help", no_argument, NULL, '?'},
{"module", required_argument, NULL, OPT_module},
{"user", required_argument, NULL, OPT_euid},
{NULL, 0, NULL, 0}
};

Expand Down Expand Up @@ -4819,6 +4828,12 @@ static void parse_record_options(int argc,
ctx->instance->filter_mod = optarg;
ctx->filtered = 0;
break;
case OPT_euid:
pw = getpwnam(optarg);
if (!pw)
die("Can not find user %s", optarg);
ctx->euid = pw->pw_uid;
break;
case OPT_quiet:
case 'q':
quiet = 1;
Expand Down Expand Up @@ -4984,7 +4999,7 @@ static void record_trace(int argc, char **argv,
}

if (ctx->run_command)
run_cmd(type, (argc - optind) - 1, &argv[optind + 1]);
run_cmd(type, ctx->euid, (argc - optind) - 1, &argv[optind + 1]);
else {
update_task_filter();
tracecmd_enable_tracing();
Expand Down