# stta-lib.pl
# STTA Rev. 1.3 Copyright (c) 2001-2002 Jesús Pérez Lorenzo  --- license GNU GPL 
# Common functions 

do '../web-lib.pl';
do 'web-lib.pl';
do 'global-lib.pl';
do 'lists-lib.pl';
do 'html-lib.pl';
do 'ttasess-lib.pl';
do 'monitor-lib.pl';
do 'print-lib.pl';
&init_config();
&load_dataconf();
%access = &get_module_acl();

@access_types = $access{'types'} eq '*' ? (0 .. 100)
				        : split(/\s+/, $access{'types'});
map { $access_types{$_}++ } @access_types;
$debug=$config{debug_code};

if ( $config{'tta_dir'} eq "" || !(-d $config{'tta_dir'})) { 
           &redirect("/config.cgi?$module_name"); }


%ttaprops=();
@ttahosts=();
%sttaparams=();
$cginame= $0 =~ /([^\/]+)$/ ? $1 : '-';   
$ldap_ok=true;
$ldapcache_ok=true;
$tta_ok=true;

if (  $parse_webmin_log ne true ) {   
     &scan_cgiacl();
     if ( $config{check_services} eq "true" ) {
          &load_ttaprops();
          &scanSTTA_services("all"); 
     }
}
$mhost=$sttaparams{'tta'}{'masthost'};

if ( $debug gt 0 ) {
         $DebugFile="/tmp/log";
         open(DebugLog, ">$DebugFile");
}

sub scan_cgiacl
{
    local $cgi_obj=$cginame;
    local $no_acl="index tta_selusr cache_selobj tta_filter stta_warn tta_works license";
    local $tta_acl="tta_backup tta_ensbk tta_archive tta_status tta_passwdcache updldapcache tta_ensdump tta_ensload tta_ensrestore tta_ensrecreate";
    $cgi_obj=~ s/.cgi//;  

    if ( $no_acl =~ /$cgi_obj/ ) {
          return true;  
    } elsif ( $tta_acl =~ /$cgi_obj/  && $access{'backup'} && $access{'global'} ) {
          return true;  
    } elsif ( $cgi_obj =~ /test/ && $debug gt 0  ) {
          if  ( $access{'admin'} && $access{'global'} ) { return true; } 
    } elsif ( $cgi_obj =~ /replica/ ) {
          if  ( $access{'replicate'} && $access{'global'} ) { return true; } 
    } elsif ( $cgi_obj =~ /start/ ) {
          if  ( $access{'stop'} && $access{'global'} ) { return true; } 
    } elsif ( $cgi_obj eq "tta_alivehosts" || $cgi_obj eq "stta_view") {
          if ($access{'alivehosts'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj eq "sttaconfig" || $cgi_obj eq "tta_loadusrs" || $cgi_obj eq "tta_loadous" ) {
          if ($access{'admin'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /cache_/ || $cgi_obj =~ /obj/ || $cgi_obj =~ /profcache/ ) {
          if ($access{'passwd'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /log/ ) {
          if ($access{'supervision'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /dir/ ) {
          if ($access{'supervision'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /ldap_/ ) {
          if ($access{'admin'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /acl/ ) {
          if ($access{'monitor'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /act/ || $cgi_obj eq "mon_script" ) {
          if ($access{'monitor'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /file/ ) {
          if ($access{'supervision'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /sess/ ) {
          if ($access{'sessions'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } elsif ( $cgi_obj =~ /update/ || $cgi_obj =~ /fix/ ) {
          if ($access{'admin'} eq 1 && $access{'global'} eq 1 ) { return true; }; 
    } else {
         $cgi_obj=~s/tta_/_/;  
         $cgi_obj=~s/cache_/_/;  
         $cgi_obj=~s/_sel/_add/;  
         $cgi_obj=~s/_//;  
         $cgi_obj=~s/^mod/add/;  
         if ( $access{$cgi_obj} eq "1" ) { return true } 
    }
    &redirect("stta_warn.cgi?cgi=$cginame"); 
}

# wsplit(string)
# Splits a string like  foo "foo \"bar\"" bazzz  into an array of words
sub wsplit
{
local($s, @rv); $s = $_[0];
$s =~ s/\\\"/\0/g;
while($s =~ /^"([^"]*)"\s*(.*)$/ || $s =~ /^(\S+)\s*(.*)$/) {
	$w = $1; $s = $2;
	$w =~ s/\0/"/g; push(@rv, $w);
	}
return \@rv;
}

# wjoin(word, word, ...)
sub wjoin
{
local(@rv, $w);
foreach $w (@_) {
	if ($w =~ /^\S+$/) { push(@rv, $w); }
	else { push(@rv, "\"$w\""); }
	}
return join(' ', @rv);
}

# dir_name(struct)
sub dir_name
{
local($dfm, $mat);
$_[0]->{'name'} =~ /^(Directory|Files|Location)(Match)?$/;
$dfm = $1; $mat = $2;
if ($mat) { return "$dfm regexp <tt>$_[0]->{'words'}->[0]</tt>"; }
elsif ($_[0]->{'words'}->[0] eq "~")
	{ return "$dfm regexp <tt>$_[0]->{'words'}->[1]</tt>"; }
else { return "$dfm <tt>$_[0]->{'words'}->[0]</tt>"; }
}

# list_user_file(file, &user,  &pass)
sub list_user_file
{
local($_);
open(USERS, $_[0]);
while(<USERS>) {
	/^(\S+):(\S+)/;
	push(@{$_[1]}, $1); $_[2]->{$1} = $2;
	}
close(USERS);
}

#scan_objdescrip($pos,$tta3tier->{objetype}, $dn_t, $tta3tier->{target});
# it tries to get target "objdescrip" from "object list files" depending on type 
#
sub scan_objdescrip 
{
    local ($pos) = $_[0];
    local ($objetype) = $_[1];
    local ($target) = $_[2];
    local ($origin) = $_[3];
    local ($objdescrip) = "";
    local (%lista,@dn_lin);

    $target=~s/,$config{ldapcache_base}//; 
    if ( $origin ne "default") { $target=~s/$origin,//;}
    if ($objetype eq "" ) { $objtype=$objType; }
    if ($objetype eq "ou" ) {
        %lista= &list_ous($pos);
    } elsif ($objetype eq "host" ) {
        if ( $pos eq 2 ) { $pos=3 };
        %lista= &list_hosts($pos);
    } elsif ($objetype eq "grphosts" ) {
        %lista= &list_grphosts($pos);
    } elsif ($objetype eq "app" ) {
        if ( $pos eq 2 ) { $pos=3 };
        %lista= &list_apps($pos);
    } elsif ($objetype eq "grpapps" ) {
        %lista= &list_grpapps($pos);
    } elsif ($objetype eq "domain" ) {
        %lista= &list_domains($pos);
    }
    if ( $lista{$target}->{'obj'} eq $target ) {
         $objdescrip=$lista{$target}->{descrip};
         if ( "$objdescrip" eq "" ) { $objdescrip = $lista{$target}->{name} };
    }
#    print "$objetype --$pos --$lista{$target}->{'obj'} eq $target <br>";
#   print "<p>$objetype ..($origin)  - $pos-- ($target) -- [$objdescrip]<br>";
    return $objdescrip;
}

#set_tta3tier(origin,target,dn,action,objtype)
# Set %tta3tier values from Input $in{} and return 
sub set_tta3tier
{
   local (@tta3tier);
   local ($passwd_coded);

   $tta3tier->{origin} = $_[0];
   $tta3tier->{target} = $_[1];
   $tta3tier->{oudn} = $_[2];
   $tta3tier->{action} = $_[3];
   $tta3tier->{objetype} = $_[4];
   $tta3tier->{login} = $in{tta3tier_login};
   &cipher_text ( "code", $in{tta3tier_password}, \$passwd_coded);
   $tta3tier->{password} = $passwd_coded;
   $tta3tier->{title} = $in{tta3tier_title};
   $tta3tier->{stringcmd} = $in{tta3tier_stringcmd};
   $tta3tier->{domain} = $in{tta3tier_domain};
   $tta3tier->{appkey1} = $in{tta3tier_appkey1};
   $tta3tier->{appkey2} = $in{tta3tier_appkey2};
   $tta3tier->{appkey3} = $in{tta3tier_appkey3};
   $tta3tier->{appkey4} = $in{tta3tier_appkey4};
   $tta3tier->{appkey5} = $in{tta3tier_appkey5};
   $tta3tier->{maxsess} = $in{tta3tier_maxsess};
   $tta3tier->{ticketstatus} = $in{tta3tier_ticketstatus};
   $tta3tier->{ticketcounter} = $in{tta3tier_ticketcounter};
   $tta3tier->{endticket} = $in{tta3tier_endticket};
 
   return @tta3tier;
}

# run_tta_cmd([type_cmd,ens_obj,temp_f])
# Display an error message and exit. The variable $whatfailed must be set
# to the name of the operation that failed.
sub run_tta_cmd
{
 $exec_str = "tta"; 
 $cmd_str = $type_cmd; 

 if ( $tta_ok ne true ) { return -1 };
 if ( "$type_cmd" eq "emulatorsession" ) {
     $temp_f = &tempname();
     $str=" tta emulatorsession  list >$temp_f";
 }
 if ( "$type_cmd" eq "list" ) {
     $temp_f = &tempname();
     $tempf = &tempname();
     open(TEMPF, ">$tempf");
     print TEMPF "--name $ens_obj\n";
     close(TEMPF);
     $str=" tta object list_contents --file $tempf >$temp_f";
 }
 if ( "$type_cmd" eq "attributes" ) {
     $temp_f = &tempname();
     $tempf = &tempname();
     open(TEMPF, ">$tempf");
     print TEMPF "--name $ens_obj\n";
     close(TEMPF);
     $str=" tta object list_attributes --file $tempf >$temp_f";
 }
 if ( "$type_cmd" eq "delete" ) {
       $temp_f = &tempname();
       open(TEMPF, ">$temp_f");
       print TEMPF "$ens_obj\n";
       close(TEMPF);
       $str=" tta object delete --file $temp_f";
 }
 if ( "$type_cmd" eq "new_person" ) {
       $str=" tta object new_person --file $temp_f";
 }
 if ( "$type_cmd" eq "new_host" ) {
       $str=" tta object new_host --file $temp_f";
 }
 if ( "$type_cmd" eq "new_group" ) {
       $str=" tta object new_group --file $temp_f";
 }
 if ( "$type_cmd" eq "new_container" ) {
       $str=" tta object new_container --file $temp_f";
 }
 if ( "$type_cmd" eq "edit" ) {
       $str=" tta object edit --file $temp_f";
 }
 if ( "$type_cmd" eq "new_orgunit" ) {
       $str=" tta object new_orgunit --file $temp_f";
 }
 if ( "$type_cmd" eq "passcache" ) {
       $str=" tta passcache edit --file $temp_f";
 }
 if ( "$type_cmd" eq "new_group" ) {
       $str=" tta object new_group --file $temp_f";
 }
 if ( "$type_cmd" eq "add_link" ) {
       $str=" tta object add_link --file $temp_f";
 }
 if ($str) {
    # For TTA no errors in output commands means  OK ... so change true/false !!! 
    if (&run_cmd($str) eq true ) {
        return "";
    } else {
        return true;
    }
 }
 return -1;
}

# run_cmd([str])
# Display an error message and exit. The variable $whatfailed must be set
# to the name of the operation that failed.
# OUTPUT is going to FILEOUT so can be send it to Webmin Log and Screen if $no_out=false
sub run_cmd
{
  local ($t_str);
  local ($line);
  local ($line_tempf);
  $exec_str = ($exec_str) ? $exec_str : "exec"; 
  $cmd_str = ($cmd_str) ? $cmd_str : "command"; 
  
  $err_msg="";
  $err="";
 
# return false when no output 
# return true printing output does not mean error it depends on command output
# no_out by default is 0 it means to print to screen, otherwise it will go only to LOG

 $t_str=$str;
 $t_str=~s/ //g; 
 if ( !$str || $t_str eq "" ) { return "" };
      
        print $text{msg_processing}." <BR>";

        $| = 1;

        local $temp = &tempname();
        local $outfile = &tempname();
        local $line ="$str\n";

        open(FILEOUT, ">$outfile");
        open(TEMP, ">$temp");
        print TEMP "#!/bin/sh\n";
        print TEMP $env;
	print TEMP "export $export\n" if ($export);
	print TEMP "$str\n";
	close(TEMP);
	chmod(0777, $temp);
	$got = &foreign_call("proc", "safe_process_exec",
	   		     "su root -c $temp", 0, 0,
                              *FILEOUT, undef, 0);   
        if ( $config{output_cgis} eq 1 && $got ) { print "<pre>\n"; }
        if ( $debug eq 0 ) {
              system("rm -f $temp 2>/dev/null");
	      unlink($temp);
        }
        close(FILEOUT);
	open(FILEOUT, $outfile);
	while(<FILEOUT>) {
		s/\r|\n//g;
                if ( $config{output_cgis} eq 1 ) { print "$_ \n"; }
                $line .= "$_\n"; 
        }
        close(FILEOUT);
        if ( $debug eq 0 ) {
             system("rm -f $outfile 2>/dev/null");
	     unlink($outfile);
        }
        if ( $temp_f) {
             $line .= "\nfile: $temp_f :::::::::::::::::::::::\n"; 
	     open(TEMPF, $temp_f);
	     while(<TEMPF>) {
		     s/\r|\n//g;
                     $line .= "$_\n"; 
                     $line_timef .= "$_\n"; 
             }
             close(TEMPF);
        }
        if ( $ens_obj ) {
             &additional_log($str, $ens_obj, $line);
        } else { 
             &additional_log($str, undef, $line);
        }
        $line_timef=~s/"/'/g;
        $line_timef=~s/\n/\\/g;
        &webmin_log($exec_str, "$cmd_str", "$got||user=>".$config{run_exec_user}."||str=>$str||cmd=>$line_timef",undef);
#        if (!$got) { if ( $config{output_cgis} eq 1 ) { print "<i>$text{'run_noout'}</i>\n"; } }
        if ( $config{output_cgis} eq 1 && $got ) { print "<pre>\n"; }
        if (!$got) { return false;}
  return true;
}

sub scan_dn_cache {
   local (@linUserName, @UserPath);
   local ($UserName) = @_ ;
   local ($lnumUser) = 0;

         @linUserName = split(/,/, $UserName);
	 $OuName="";
	 foreach $obj (@linUserName) {
              @UserPath= split(/=/,$obj);
              $lnumUser++;
              if ( $UserPath[0] eq "cn"  &&  $lnumUser eq 1 ) {
		   $NameUser=$UserPath[1];
                        last;
              } else {
                   if ( "$OuName" ne "" ) { $OuName=$OuName.","; }
		         $OuName=$OuName.$UserPath[0]."=".$UserPath[1];
	      }
          }
}

sub load_tta3tier_vars
{
   # This will fill variables with values from hash LDAP entry with DN eq $dn_cache
   # later with should use the hash and avoid more variables in memory 
   # but the point is to preserver original values content somewhere 
   # and to the changes for the presentation and data input. by example password uncipher
   my ($dnCache) = @_ ;
   local $status_con=0;

   # loading variables
   my $cur_entry=&sel_cache_obj($dnCache,"cn=*");
   if ( !defined($cur_entry)  ||  $cur_entry->dn ne $dnCache) {
          $str_cmds=$str_cmds."<tr><td> ".$text{'ldapcache_norecord'}."</td>";
          $status_con=1;
   } else {
          %entryObj=&get_cache_obj($dnCache,$cur_entry);
          $tta3tier_domain = $entryObj{tta3tierdomain};
          $tta3tier_login = $entryObj{tta3tierlogin};
          &cipher_text ( "decode",$entryObj{tta3tierpassword}, \$tta3tier_password);
          # $tta3tier_password = $entryObj{tta3tierpassword};
          $tta3tier_stringcmd = $entryObj{tta3tierstringcmd};
          $tta3tier_title = $entryObj{tta3tiertitle};
          $tta3tier_oudn = $entryObj{tta3tieroudn};
          $tta3tier_appkey1 = $entryObj{tta3tierappkey1};
          $tta3tier_appkey2 = $entryObj{tta3tierappkey2};
          $tta3tier_appkey3 = $entryObj{tta3tierappkey3};
          $tta3tier_appkey4 = $entryObj{tta3tierappkey4};
          $tta3tier_appkey5 = $entryObj{tta3tierappkey5};
          $tta3tier_appkey6 = $entryObj{tta3tierappkey6};
          $tta3tier_maxsess = $entryObj{tta3tiermaxsess};
          $tta3tier_ticketstatus = $entryObj{tta3tierticketstatus};
          $tta3tier_ticketcounter = $entryObj{tta3tierticketcounter};
          $tta3tier_endticket = $entryObj{tta3tierendticket};
          $tta3tier_doifendticket = $entryObj{tta3tierdoifendticket};
   }
   return $status_con
}

1;  # Return true
