# global variables

$conn = "";
$conncache = "";
$conncache2 = "";

# webmin stuff
# PerlLDAP stuff

use Mozilla::LDAP::Conn;                # Main "OO" layer for LDAP
use Mozilla::LDAP::Utils;               # LULU, utilities.

use strict;
no strict "vars";

sub connect
{
   if ( "$ldap_server" eq "1" ) {
         $conn = new Mozilla::LDAP::Conn ($config{ldap_server}, $config {ldap_port},
               $config{ldap_user}, $config{ldap_passwd});
         $line_conn=$config{ldap_server}.":".$config {ldap_port};
   } elsif ( "$ldap_server" eq "2" ) {
         $conn = new Mozilla::LDAP::Conn ($config{ldap2_server}, $config {ldap2_port},
               $config{ldap2_user}, $config{ldap2_passwd});
         $line_conn=$config{ldap2_server}.":".$config {ldap2_port};
   }
   #&error("Couldn't connect to LDAP server") unless $conn;
   if (! $conn) {
        print "<P><B><I>$text{'ldap_admerr'}</I> ( $line_conn )</B><P>\n";
        print "<P><B><I>$text{'ldap_connerr'}</I></B><P>\n";
        &webmin_log("LDAP", "connect", $line_conn, "$conn");
        &footCacheHere; exit  
   }
}

sub connect_cache
{
   if ( "$ldapcache_server" eq "1" ) {
        $conncache = new Mozilla::LDAP::Conn ($config{ldapcache_server},
           $config {ldapcache_port},$config{ldapcache_user}, $config{ldapcache_passwd});
         $line_conn=$config{ldapcache_server}.":".$config {ldapcache_port};
   } elsif ( "$ldapcache_server" eq "2" ) {
        $conncache = new Mozilla::LDAP::Conn ($config{ldapcache2_server},
           $config {ldapcache2_port},$config{ldapcache2_user}, $config{ldapcache2_passwd});
         $line_conn=$config{ldapcache2_server}.":".$config {ldapcache2_port};
   }
   #&error("Couldn't connect to LDAP server") unless $conncache;
   if (! $conncache) {
        print "<P><B><I>$text{'ldapcache_admerr'}</I> ( $line_conn )</B><P>\n";
        print "<P><B><I>$text{'ldapcache_connerr'}</I></B><P>\n";
        &webmin_log("LDAP CACHE", "connect", $line_conn, "$conncache");
        &footCacheHere; exit  
   }
}

# add_cache_ou ($tta3tier)
# following $tta3tier->{ObjType}[0] ( usr | ou | app | grpapps | host | grphosts | domain ) 
# add  obj  as OU 
# in ldapcache_base" as DN   
# returning $status_con as ( 0=OK, -1 = error, -2 = missing elements )
#
sub add_cache_ou
{
  	local (%obj) = @_;
	my ($status_con,$dn,$ouname,$entry);

	$status_con = 0;
    	if (!$obj->{target}) { return -2 };
        $objdescrip=&scan_objdescrip(\%$obj);
  	if ($objdescrip eq "" ) { $objdescrip= "organization"};
    	$dn = $obj->{target}.",".$config{ldapcache_base};
    	$entry = $conncache->newEntry ();
    	$entry->setDN ($dn);
        $entry->{objectclass} = ["top", "organizationalunit"];
    	$entry->{ou} = [$obj->{target}];
    	$entry->{description} = [$objdescrip];
    	$conncache->add ($entry);
 	if ($err = $conncache->getErrorCode ()) {
    		print "<hr>\n";
       		print "<b> add ($dn): $err:".$conncache->getErrorString ()."</b>\n";
       		print "<hr>\n";
	        $status_con=-1;
    	}; 
        &webmin_log("LDAP CACHE", "newEntry", $dn, "$err");
        return $status_con;
}

# cache_obj($tta3tier)
# following $tta3tier->{action} ( add or mod ) 
# add or update  $tta3tier->{origin} 
# in $tta3tier->{target},"ldapcache_base" as DN for the OU  
# returning $status_con as ( 0=OK, -1 = error, -2 = missing elements )
#
sub cache_obj
{
  	my (%tta3tier) = @_;
  	local (%obj) = @_;
	my ($status_con,$objtype,$dn,$ou,$dn_t,$entry);
        my (@lista_targets) = ($tta3tier->{target},$tta3tier->{oudn});
        local (@dn_lin);
        my ($dntarget,$elem,$lnum,$dn_t);

	$status_con = 0;
    	if (!$tta3tier->{origin} ||  !$tta3tier->{target} ) { return -2 };

        if ( $tta3tier->{action} ne "add" && $tta3tier->{action} ne "mod" ) { return -2 };
    	if ( $tta3tier->{oudn} eq "default" ) {
    	     $dn_t = $tta3tier->{target};
        } else {
    	     $dn_t = $tta3tier->{oudn}.",".$tta3tier->{target};
        }
    	$dn = $tta3tier->{origin}.",".$dn_t.",".$config{ldapcache_base};
        $objtype=$tta3tier->{objetype};
        if ( $tta3tier->{action} eq "add" ) {
                # scanning for target .... and full_target
                $objtype=$tta3tier->{objetype};;
                $dn_t = $config{ldapcache_base};
                foreach $elem (@lista_targets) {
                   @dn_lin = split(/,/, $elem);
                   for ( $lnum= $#dn_lin ; $lnum >= 0 ; $lnum-- ) {
    	               if ( "$dn_lin[$lnum]" ne "default" ) {
    	                   $ou=$dn_lin[$lnum];
    	                   $dn_t = $ou.",".$dn_t;
	                   $dntarget=&sel_cache_obj($dn_t);
                           if (!$dntarget) { 
                                $objdescrip=&scan_objdescrip(
                                      $objtype,$dn_t,$tta3tier->{target});
                                if ($objdescrip eq "" ) { $objdescrip= "organization"};
                                $entry = $conncache->newEntry ();
                                $entry->setDN ($dn_t);
                                $entry->{objectclass} = ["top", "organizationalunit"];
                                $entry->{ou} = [$ou];
                                $entry->{description} = [$objdescrip];
                                $conncache->add ($entry);
                                  if ($err = $conncache->getErrorCode ()) {
                                      print "<hr>\n";
                                      print "<b> add_ou ($dn_t): $err:".$conncache->getErrorString ()."</b>\n";
                                      print "<hr>\n";
                                      $status_con=-1;
                                };
                                &webmin_log("LDAP CACHE", "newEntry", $dn_t, "$err");
                           };
                        };
                        if ($status_con ne 0 ) { return -2 };
                   }
                   if ($status_con ne 0 ) { return -2 };
                   $objtype="ou";
                }
                if ( $tta3tier->{login}.length gt 0 ) {                          
                     # Redy to go
	             $entry = $conncache->newEntry ();
    	             $entry->setDN ($dn);
       		     $entry->{objectclass} = ["ttacacheapp"];
                     $entry->{cn} = [$tta3tier->{origin}];
                }
        } elsif ( $tta3tier->{action} eq "mod" ) {
                $entry = $conncache->browse ($dn_obj); 
		if ($err = $conn->getErrorCode ()) {
        		print "<hr>\n";
        		print "<b> mod ($dn): $err:".$conn->getErrorString ()."</b>\n";
        		print "<hr>\n";
                        &webmin_log("LDAP CACHE", "browse", $dn, "$err");
			return -1;
    		}
                &webmin_log("LDAP CACHE", "browse", $dn, "$err");
        }
        $entry->{tta3tierdomain} = [$tta3tier->{domain}];
	$entry->{tta3tierlogin} = [$tta3tier->{login}];
	$entry->{tta3tierpassword} = [$tta3tier->{password}];
	$entry->{tta3tierstringcmd} = [$tta3tier->{stringcmd}];
	$entry->{tta3tiertitle} = [$tta3tier->{title}];
	$entry->{tta3tieroudn} = [$tta3tier->{oudn}];
	$entry->{tta3tierappkey1} = [$tta3tier->{appkey1}];
	$entry->{tta3tierappkey2} = [$tta3tier->{appkey2}];
	$entry->{tta3tierappkey3} = [$tta3tier->{appkey3}];
	$entry->{tta3tierappkey4} = [$tta3tier->{appkey4}];
	$entry->{tta3tierappkey5} = [$tta3tier->{appkey5}];
	$entry->{tta3tierappkey6} = [$tta3tier->{appkey6}];
	$entry->{tta3tiermaxsess} = [$tta3tier->{maxsess}];
	$entry->{tta3tierticketstatus} = [$tta3tier->{ticketstatus}];
	$entry->{tta3tierticketcounter} = [$tta3tier->{ticketcounter}];
	$entry->{tta3tierendticket} = [$tta3tier->{endticket}];
	$entry->{tta3tierdoifendticket} = [$tta3tier->{doifendticket}];
        if ( $tta3tier->{action} eq "add" ) {
                if ( $tta3tier->{login}.length gt 0 ) { $conncache->add ($entry) };
        } elsif ( $tta3tier->{action} eq "mod" ) {
                if ( $tta3tier->{login}.length gt 0 ) { $conncache->update ($entry) };
        }
	if ($err = $conncache->getErrorCode ()) {
            print "<hr>\n";
    	    print "<b> $action ($dn): $err:".$conncache->getErrorString ()."</b>\n";
       	    print "<hr>\n";
            $status_con=-1;
	}; 
        &webmin_log("LDAP CACHE", $tta3tier->{action}, $dn, "$err");
#  &print_tta3tier(\%$tta3tier);  # debugging trace 
        return $status_con;
}

sub del_cache_obj
{
    my ($dn) = @_;
    my ($status_con,$dn_cn);
 
    $status_con = 0;
    # scanning for subentries "cn" in $dn 
    $entry = $conncache->search ($dn, "subtree", "(cn=*)" );
    while ($entry) {
               $dn_cn = $entry->getDN ();
               $entry = $conncache->nextEntry ();
    	       $conncache->delete ($dn_cn);
    }
    $conncache->delete ($dn);
    if ($err = $conncache->getErrorCode ()) {
                print "<hr>\n";
                print "<b> del ($dn): $err:".$conncache->getErrorString ()."</b>\n";
                print "<hr>\n";
                $status_con=-1;
    };
    &webmin_log("LDAP CACHE", "delete all", $dn, "$err");
    return $status_con;
}

sub del_ldap_obj
{
    local ($status_ldap);
 
    $status_ldap=0;
    $ldapcache_server=1;
    &connect_cache ();
    if ( &del_cache_obj($dn) eq 0 ) {
         &del_obj($dn); 
         if ( $config{ldapcache2_server}.length gt 0 ) {
              $ldapcache_server=2;
              &connect_cache ();
              if (&del_cache_obj($dn) ne 0 ) {
                  &err_replication();
                  $status_ldap=1;
              } else {
                &del_obj($dn); 
              }
         }
    } else {
      $status_ldap=1;
    }
  return $status_ldap;
}

sub del_obj
{
     my ($status_con);
     $status_con = 0;
 
     $entry = $conncache->browse ($dn);
     if ($err = $conncache->getErrorCode ()) {
            print "<hr>\n";
            print "<b> del ($dn): $err:".$conncache->getErrorString ()."</b>\n";
            print "<hr>\n";
            $status_con=-1;
            &webmin_log("LDAP CACHE", "browse", $dn, "$err");
     } else {
            $conncache->delete ($entry);
            if ($err = $conncache->getErrorCode ()) {
                   print "<hr>\n";
                   print "<b> del ($dn): $err:".$conncache->getErrorString ()."</b>\n";
                   print "<hr>\n";
                   $status_con=-1;
            }
            &webmin_log("LDAP CACHE", "delete entry", $dn, "$err");
     }
     return $status_con;
}


sub mod_obj
{
     my ($status_con);
     $status_con = 0;
 
     $entry = $conncache->browse ($dn);
     if ($err = $conncache->getErrorCode ()) {
            print "<hr>\n";
            print "<b> mod ($dn): $err:".$conncache->getErrorString ()."</b>\n";
            print "<hr>\n";
            $status_con=-1;
            &webmin_log("LDAP CACHE", "browse entry", $dn, "$err");
     } else {
            $entry->{tta3tierdomain} = [$in{tta3tier_domain}];
            $entry->{tta3tierlogin} = [$in{tta3tier_login}];
            $entry->{tta3tierpassword} = [$in{tta3tier_password}];
            $entry->{tta3tierstringcmd} = [$in{tta3tier_stringcmd}];
            $entry->{tta3tiertitle} = [$in{tta3tier_title}];
            $entry->{tta3tieroudn} = [$in{tta3tier_oudn}];
            $entry->{tta3tierappkey1} = [$in{tta3tier_appkey1}];
            $entry->{tta3tierappkey2} = [$in{tta3tier_appkey2}];
            $entry->{tta3tierappkey3} = [$in{tta3tier_appkey3}];
            $entry->{tta3tierappkey4} = [$in{tta3tier_appkey4}];
            $entry->{tta3tierappkey5} = [$in{tta3tier_appkey5}];
            $entry->{tta3tierappkey6} = [$in{tta3tier_appkey6}];
            $entry->{tta3tiermaxsess} = [$in{tta3tier_maxsess}];
            $entry->{tta3tierticketstatus} = [$in{tta3tier_ticketstatus}];
            $entry->{tta3tierticketcounter} = [$in{tta3tier_ticketcounter}];
            $entry->{tta3tierendticket} = [$in{tta3tier_endticket}];
            $entry->{tta3tierdoifendticket} = [$in{tta3tier_doifendticket}];
 
            $conncache->update ($entry);
            if ($err = $conncache->getErrorCode ()) {
                  print "<hr>\n";
                  print "<b> mod ($dn): $err:".$conncache->getErrorString ()."</b>\n";
                  print "<hr>\n";
                  $status_con=-1;
            }
            &webmin_log("LDAP CACHE", "update entry", $dn, "$err");
     }
     return $status_con;
}

sub sel_cache_obj
{

    my ($dn) = @_;
 
    my ($entry);
 
    $entry = $conncache->browse ($dn);
    return $entry;
}

sub add_usr
{
    my ($status_con);
    $status_con = 0;

    $entry = $conn->newEntry ();
    $entry->setDN ($dn);
    if ( "$config{ldap_type}" eq "OpenLDAP" ) {
        $entry->{objectclass} =
             ["top", "person", "organizationalperson", "inetorgperson", "uidObject"];
    } else {
        $entry->{objectclass} =
             ["top", "person", "organizationalperson", "inetorgperson"];
    }
    $entry->{userpassword} = [$password];
    if ( "$config{ldap_type}" eq "OpenLDAP" ) {
         $entry->{description} = [$organizationname];
    } else {
         if ( "$where" ne "" ) { $entry->{displayname} = [$where]; }
         $entry->{departmentnumber} = [$organizationname];
    }
    if ( "$surname" ne "" ) { $entry->{sn} = [$surname]; }
    $entry->{cn} = [$username];
    $entry->{uid} = [$username];
    if ( "$email" ne "" ) { $entry->{mail} = [$email];}
    $conn->add ($entry);
    if ($err = $conn->getErrorCode ()) {
	print "<hr>\n";
        print "<b> add ($dn): $err:".$conn->getErrorString ()."</b>\n";
	print "<hr>\n";
        $status_con=1;
    } 
    &webmin_log("LDAP", "new entry", $dn, "$err");
    return $status_con;
}

sub mod_usr
{
    my ($status_con);
    $status_con = 0;

    # assume the uid (or the DN) was not changed
    # no change for cn username --- password in other form
    $entry = $conn->browse ($dn);
    if ($err = $conn->getErrorCode ()) {
        print "<hr>\n";
        print "<b> mod ($dn): $err:".$conn->getErrorString ()."</b>\n";
        print "<hr>\n";
        $status_con=1;
        &webmin_log("LDAP", "browse entry", $dn, "$err");
    }
    else {
            $entry->{mail} = [$in{email}];
            $entry->{sn} = [$in{surname}];
            $entry->{displayname} = [$in{descrip}];
            $conn->update ($entry);
            if ($err = $conn->getErrorCode ()) {
               print "<hr>\n";
               print "<b> mod ($dn): $err:".$conn->getErrorString ()."</b>\n";
               print "<hr>\n";
               $status_con=1;
            } 
            &webmin_log("LDAP", "update entry", $dn, "$err");
    }
    return $status_con;
}

sub mod_usr_password
{
    my ($status_con);
    $status_con = 0;

    # assume the uid (or the DN) was not changed
    # no change for ou ouname ---
    $entry = $conn->browse ($dn);
    if ($err = $conn->getErrorCode ()) {
           print "<hr>\n";
           print "<b> mod ($dn): $err:".$conn->getErrorString ()."</b>\n";
           print "<hr>\n";
           $status_con=1;
           &webmin_log("LDAP", "browse entry", $dn, "$err");
    }
    else {
           $entry->{userpassword} = [$password];
           $surname=$entry->{sn};
           $conn->update ($entry);
           if ($err = $conn->getErrorCode ()) {
                  print "<hr>\n";
                  print "<b> mod ($dn): $err:".$conn->getErrorString ()."</b>\n";
                  print "<hr>\n";
                  $status_con=1;
           }
            &webmin_log("LDAP", "update entry password", $dn, "$err");
    }
    return $status_con;
}

sub del_usr
{
    my ($status_con);
    $status_con = 0;

    $conn->delete ($dn);
    if ($conn -> getErrorCode()) {
        $err = $conn->getErrorCode ();
        print "<hr>\n";
        print "<b> del ($dn): $err:".$conn->getErrorString ()."</b>\n";
        print "<hr>\n";
        $status_con=1;
    }
    &webmin_log("LDAP", "delete entry", $dn, "$err");
    return $status_con;
}

sub add_ou
{
    my ($status_con);
    $status_con = 0;

    $entry = $conn->newEntry ();
    $entry->setDN ($dn);
    $entry->{objectclass} = ["top", "organizationalunit"];
    $entry->{ou} = [$ouname];
    $conn->add ($entry);
    if ($err = $conn->getErrorCode ()) {
        print "<hr>\n";
        print "<b> add ($dn): $err:".$conn->getErrorString ()."</b>\n";
        print "<hr>\n";
        $status_con=1;
    }
    &webmin_log("LDAP", "add ou", $dn, "$err");
    return $status_con;
}

sub mod_ou
{
    my ($status_con);
    $status_con = 0;

    # assume the uid (or the DN) was not changed
    # no change for ou ouname ---
    $entry = $conn->browse ($dn);
    if ($err = $conn->getErrorCode ()) {
        print "<hr>\n";
        print "<b> mod ($dn): $err:".$conn->getErrorString ()."</b>\n";
        print "<hr>\n";
        $status_con=1;
        &webmin_log("LDAP", "browse ou", $dn, "$err");
    } else {
            $entry->{description} = [$in{descrip}];
            $conn->update ($entry);
            if ($err = $conn->getErrorCode ()) {
               print "<hr>\n";
               print "<b> mod ($dn): $err:".$conn->getErrorString ()."</b>\n";
               print "<hr>\n";
               $status_con=1;
            }
            &webmin_log("LDAP", "update ou", $dn, "$err");
    }
    return $status_con;
}

sub del_ou
{
    my ($status_con);
    $status_con = 0;

    $conn->delete($dn);
    if ($conn -> getErrorCode()) {
        $err = $conn->getErrorCode ();
        print "<hr>\n";
        print "<b> del ($dn): $err:".$conn->getErrorString ()."</b>\n";
        print "<hr>\n";
        $status_con=1;
    }
    &webmin_log("LDAP", "delete ou", $dn, "$err");
    return $status_con;
}

# This function exist to allow other actions further than to print a messages
# just by example we can gently exit CGI by doing " &footHere; exit " 
# All replication return not 0 will cross this funcion.
sub err_replication
{
        print "<b> ($dn):".$text{'replica_err'} ."-->".$line_conn."</b>\n";
        print "<b> ".$text{'replica_msg'} ."</b>\n";
}

