From c8e2a70101d80668aa3e3a8141dc3301bfa0da93 Mon Sep 17 00:00:00 2001 From: Andrew Gaffney Date: Mon, 7 Jan 2008 01:09:58 +0000 Subject: write out script_data to file determine UID/GID of run_as user beforehand so we can change the owner of the script we just wrote exec the script we wrote out instead of dummy commands add set_script_file() function svn path=/branches/new-fu/; revision=341 --- client/Scire/Job.pm | 50 +++++++++++++++++++++++++++++++++----------------- client/scireclient.pl | 2 +- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/client/Scire/Job.pm b/client/Scire/Job.pm index 0b016dc..27a5aa7 100644 --- a/client/Scire/Job.pm +++ b/client/Scire/Job.pm @@ -1,6 +1,6 @@ package Scire::Job; -use POSIX qw/WEXITSTATUS WIFEXITED waitpid/; +use POSIX qw/WEXITSTATUS WIFEXITED waitpid setuid setgid/; sub new { my $proto = shift; @@ -35,6 +35,13 @@ sub load_jobfile { } } +sub set_script_file { + my ($self, $scriptfile) = @_; + if(defined $scriptfile and $scriptfile) { + $self->{script_filename} = $scriptfile; + } +} + sub set_stdout_file { my ($self, $outfile) = @_; if(defined $outfile && $outfile) { @@ -52,9 +59,27 @@ sub set_stderr_file { sub run { my $self = shift; - # XXX: write $self->{script_data} out to a file and mark it +x. We'll need - # to find a good location for this, since it can't be noexec. Perhaps the - # queue dir in the job directory will do, or maybe it will be configurable + # XXX: we might want to check capabilities here instead of UID, but I + # have no idea how to do that + my ($run_as_uid, $run_as_gid) = (0, 0); + if($< == 0) { + # XXX: we'll use setuid to drop privileges here + my @user = getpwnam($self->{run_as}); + if(defined @user) { + $run_as_uid = $user[2]; + $run_as_gid = $user[3]; + } else { + return -2; + } + } + + open SCRIPT, ">", $self->{script_filename}; + print SCRIPT $self->{script_data}; + close SCRIPT; + if($run_as_uid) { + chown $run_as_uid, $run_as_gid, $self->{script_filename}; + } + chmod 0500, $self->{script_filename}; my $pid = fork(); if($pid) { @@ -76,24 +101,15 @@ sub run { if(defined $self->{stderr_filename}) { open STDERR, '>', $self->{stderr_filename}; } - # XXX: we might want to check capabilities here instead of UID, but I - # have no idea how to do that - if($< == 0) { - # XXX: we'll use setuid to drop privileges here - my $user = getpwnam($self->{run_as}); - if(defined $user) { - setuid($user[2]); - } else { - # XXX: the specified user does not exist. we should really do - # something here - exit(-2); - } + if($run_as_uid) { + setuid($run_as_uid); + setgid($run_as_gid); } # XXX: exec() to run our command. our STDOUT and STDERR have been # redirected to the files specified, and the exit code is returned # to the main process when we're done executing. This will be changed # to the path of the script we've written to disk once that code is in - exec '/bin/sh', '-c', 'echo foo; echo bar >&2'; + exec '/bin/sh', '-c', $self->{script_filename}; } } diff --git a/client/scireclient.pl b/client/scireclient.pl index 91bd1c5..304051e 100755 --- a/client/scireclient.pl +++ b/client/scireclient.pl @@ -98,7 +98,7 @@ sub parse_command_line { } sub check_job_dir { - my @checkdirs = ($conf{job_dir}, "$conf{job_dir}/queue", "$conf{job_dir}/done", "$conf{job_dir}/failed"); + my @checkdirs = ($conf{job_dir}, "$conf{job_dir}/queue", "$conf{job_dir}/done", "$conf{job_dir}/failed", "$conf{job_dir}/run"); for my $dir (@checkdirs) { if (! -d $dir) { print "WARNING! ${dir} does not exist...creating\n"; -- cgit v1.2.3-65-gdbad