#!/usr/bin/eperl -w
#
# Copyright (c) Ensim Corporation 2000, 2001   All Rights Reserved.
#
# This software is furnished under a license and may be used and copied
# only  in  accordance  with  the  terms  of such  license and with the
# inclusion of the above copyright notice. This software or any other
# copies thereof may not be provided or otherwise made available to any
# other person. No title to and ownership of the software is hereby
# transferred.
#
# The information in this software is subject to change without notice
# and  should  not be  construed  as  a commitment by Ensim Corporation.
# Ensim assumes no responsibility for the use or  reliability  of its
# software on equipment which is not supplied by Ensim.
#
# Exit codes (on failure error message goes to stderr):
#  0 - success
#  1 - failure
#
# This program performs a virtual domain operation. Based on the
# actual operation it does a chroot and execs the command or passes
# the virtual domain as an environment variable. Its arguments are the domain
# name, the command (with full path) and its arguments.
#
# VirtDomainOperation vx.com /usr/path/to/list_aliases
#

use English;

use lib ($ENV{OCW_SVCPATH} or "/usr/lib/opcenter") . "/virtualhosting";
use lib ($ENV{OCW_SVCPATH} or "/usr/lib/opcenter") . "/cmdline_common";

use ERRORS;
use Carper;

use strict;

push @INC, ($ENV{'OCW_SVCPATH'} || "/usr/lib/opcenter")."/virtualhosting";
push @INC, ($ENV{'OCW_SVCPATH'} || "/usr/lib/opcenter")."/cmdline_common";
if ($0 =~ /^(.+)\/([^\/]+)$/) {
  push @INC, $1; #the directory where the script resides
}
require CmdLineCoder;
require VHConfiguration;
require VHConst;

#unescape the command line arguments
&CmdLineCoder::decode_args();

#these scripts are called only if their respective options (falgs)
#from the virtualhosting conf file are on
%::restrictedscripts = ("/usr/lib/opcenter/ftp/EnableAnonFtp" => "AnonFtp",
			"/usr/lib/opcenter/ftp/DisableAnonFtp" => "AnonFtp",
		       );

#these scripts will be called in the chrooted environment
@::nonchrootscripts = ("/usr/lib/opcenter/proftpd/EnableAnonFtp",
		       "/usr/lib/opcenter/proftpd/DisableAnonFtp",
		       "/usr/lib/opcenter/proftpd/ChangeFtpOption",
		       "/usr/lib/opcenter/apache/get_config",
		       "/usr/lib/opcenter/apache/set_userpasswd",
		       "/usr/lib/opcenter/apache/remove_userpasswd",
		       "/usr/lib/opcenter/apache/get_protection",
		       "/usr/lib/opcenter/apache/protect_directory",
		       "/usr/lib/opcenter/apache/set_config",
                       "/usr/lib/opcenter/mivamerchant/get_webname",
		       "/usr/lib/opcenter/virtualhosting/ChangeDomainPasswd",
		      );

my($error_message) = &VirtDomainOperation;

if ($error_message) {
  print STDERR $error_message;
  exit 1;
}
exit 0;

#
# Main function for performing an operation on virtual domains.
#
sub VirtDomainOperation {
  my ($Domain,$User,$Program);
  #Process the command line arguments
  if ($#ARGV < 1) {
    $cerr += $E_ARGS ;
    return "The number of arguments is too small.\n";
  }
  $Domain = shift @ARGV;
  if ($ARGV[0] eq "-u") {
    shift @ARGV;
    $User = shift @ARGV;
  } else {
    $User = undef;
  }
  if ($#ARGV < 0) {
    $cerr += $E_ARGS ;
    return "The number of arguments is too small.\n";
  }
  $Program = shift @ARGV;

  my ($error_message);

  #Check the domain name.
  if ($Domain !~ /^[a-zA-Z0-9-\.]+\.[a-zA-Z]+$/ and $Domain ne "localhost") {
    $cerr += $E_INVALIDDOMAINNAME and 
    $cerr += { domain => $Domain } ;
    return "Invalid domain name $Domain .\n";
  }
  #Check the user name.
  if (defined ($User) and $User !~ /^[a-zA-Z0-9_-]+$/ ) {
    $cerr += $E_INVALIDUSER and 
    $cerr += { user => $User } ;
    return "Invalid user name $User \n";
  }
  my ($chroot);
  if ($Domain eq "localhost") {
    $chroot = "";
  } else {
    #Get the domain info from the conf file
    my ($record);
    if ($error_message = &VHConfiguration::GetDomainConf($Domain,\$record))
      {return $error_message;}
    #Check if the command is restricted by a virtual hosting flag
    if ($::restrictedscripts{$Program}) {
      unless ($record->{$::restrictedscripts{$Program}}) {
      $cerr += $E_NOTALLOWED ;
	return "You are not allowed to perform this operation.\n";
      }
    }
    unless ($ENV{'OCW_SVCPATH'}) {$ENV{'OCW_SVCPATH'} = "/usr/lib/opcenter"}
    unless (grep {$Program eq $_} @::nonchrootscripts) {
      $chroot = "$VHConst::VIRTUALFS/$record->{User}";
      $VHConst::VIRTUALFS .= ""; #Just need this to avoid a perl warning
    } else {
      $ENV{VirtualDomain} = join (" ",(map {"$_=$record->{$_}"} (keys %$record)));
    }
  }

  if($chroot) {
    chdir $chroot; #This is to work around a Linux bug
    chroot ($chroot) or 
        $cerr += $E_RUNASROOTCHROOT and
        return "Run this script as root. Chroot failed.\n";
  }

  if(defined $User) {
    my(@pwent)=getpwnam($User);
    unless(@pwent) {
        $cerr += $E_NOUSER and $cerr += { user => $User } ;
        return "User $User does not exist.\n";}
    ($GID,$EGID)=($pwent[3],$pwent[3]);
    ($UID,$EUID)=($pwent[2],$pwent[2]);
  }
  exec ($Program, (map {&CmdLineCoder::encode_string($_)} @ARGV)) or
    $cerr += $E_CANNOTEXEC and
    $cerr += { what => $Program, perror => $! } and 
    return "Could not exec $Program : $! \n";
}
