#!/usr/bin/perl
use CGI qw(:standard);
use CGI::Carp qw/fatalsToBrowser/;

push @INC, "/home/websites/splitreflection.com".$ENV{'SCRIPT_NAME'};

my $valid_user = "apache";
my $valid_parent = "/usr/sbin/apache2";

my %credentials;
&validate($valid_user, $valid_parent, $ENV{'PATH_INFO'});
&getCreds();
&setuid($credentials{"uid"});
if(($< < 500) || ($> < 500))
{ die "Error setting uid"; }
my $command = "/home/websites/splitreflection.com".$ENV{'SCRIPT_NAME'}.$ENV{'PATH_INFO'};
$ENV{'SCRIPT_NAME'} .= $ENV{'PATH_INFO'};
&run($command);

exit;

sub run
{
  my $script = shift;
  open my $filehandle, "<".$script or die "$! opening $script";
  my $data = join "", <$filehandle>;
  close $filehandle;

  if($data =~ /(.*)/s){$data = $1;}
  eval $data;
  if($@){die "Error in eval:$@"};
}

sub getCreds
{
  my $user;
  if($ENV{'REMOTE_USER'} =~ /(.*)/)
  { $user = $1; }

  open my $fh, "</etc/passwd";
  my @passwd = <$fh>;
  close $fh;
  @passwd = grep($_ =~ /^$ENV{'REMOTE_USER'}:/, @passwd);
  (my $tmp, $tmp, $credentials{'uid'}, $credentials{'group'}, $credentials{'description'}, $credentials{'home'}, $credentials{'shell'}) = split ":", $passwd[0];
  $credentials{'username'} = $ENV{'REMOTE_USER'};
  my @groups;
  my $gids = "$credentials{'group'} ";
  open my $fh, "</etc/group";
  while(my $line = <$fh>)
  {
    my ($grp, $tmp, $gid, $users) = split ":", $line;
    my @users = split ",", $users;
    grep
    {
      chomp $_;
      if($_ eq $credentials{'username'})
      {
        push @groups, $grp;
	$gids .= "$gid ";
      }
    } @users;
  }
  close $fh;
  $ENV{'GIDS'} = $gids;
  $( = $gids or die "Could not set real gid to $gids: $!";
  $) = $gids or die "Could not set effective gid to $gids: $!";
  grep
  {
    my ($key, $value) = split "=", $_;
    chomp $value;
    $credentials{$key} = "yes";
  } @groups;
}

sub setuid
{
  my $uid = shift;
  $< = $uid or die "Could not set real uid to $uid: $!";
  $> = $uid or die "Could not set effective uid to $uid: $!";
}

sub validate
{ # &validate(user, parent, file)
  # Ensures this was run by the given user from the given parent process, and that the file has no redirection in it.
  
  my $user = shift;
  my $parent = shift;
  my $file = shift;

  my $pid = getppid;
  $ENV{"PATH"} = "";

  open my $filehandle, "/bin/ps -ef|/bin/awk '{print \$1, \$2, \$8}' |/bin/grep ' $pid ' |";
  my $line = <$filehandle>;
  close $filehandle;
  chomp $line;
  if($line ne "$user $pid $parent")
  {
    die "$line is unauthorized.";
  }

  if($file =~ /\.\./)
  {
    die "Invalid file $file";
  }
}
