Code

Removed usePrototype flag, its activated always now.
[gosa.git] / gosa-si / server / events / siTriggered.pm
index 9638cca17ab52b50464a5946b6d13d6fa0ba08fd..f190e15fee6f580d6f3f12b3cf0d184a36562bcb 100644 (file)
@@ -1,19 +1,24 @@
 package siTriggered;
+
+use strict;
+use warnings;
+
 use Exporter;
-@ISA = qw(Exporter);
+use Data::Dumper;
+use GOSA::GosaSupportDaemon;
+use Socket;
+
+our @ISA = qw(Exporter);
+
 my @events = (
     "got_ping",
     "detected_hardware",
     "trigger_wake",
     "reload_ldap_config",
+    "get_terminal_server",
     );
-@EXPORT = @events;
-
-use strict;
-use warnings;
-use GOSA::GosaSupportDaemon;
-use Socket;
-
+    
+our @EXPORT = @events;
 
 BEGIN {}
 
@@ -28,49 +33,107 @@ my $ldap_admin_password;
 my $mesg;
 
 my %cfg_defaults = (
-"server" => {
-    "ldap-uri" => [\$ldap_uri, ""],
-    "ldap-base" => [\$ldap_base, ""],
-    "ldap-admin-dn" => [\$ldap_admin_dn, ""],
-    "ldap-admin-password" => [\$ldap_admin_password, ""],
+    "server" => {
+        "ldap-uri" => [\$ldap_uri, ""],
+        "ldap-base" => [\$ldap_base, ""],
+        "ldap-admin-dn" => [\$ldap_admin_dn, ""],
+        "ldap-admin-password" => [\$ldap_admin_password, ""],
     },
 );
-&read_configfile($main::cfg_file, %cfg_defaults);
+&GOSA::GosaSupportDaemon::read_configfile($main::cfg_file, %cfg_defaults);
 
 
-sub get_events {
-    return \@events;
-}
+sub get_terminal_server
+{
+       my ($msg, $msg_hash, $session_id) = @_ ;
+       my $source = @{$msg_hash->{source}}[0];
+       my @out_msg_l;
+
+       # Send get_load message to all si-clients at terminal server specified in LDAP
+       my $ldap_handle = &main::get_ldap_handle();
+       if (defined $ldap_handle) 
+       {
+               my $ldap_mesg = $ldap_handle->search(
+                               base => $ldap_base,
+                               scope => 'sub',
+                               attrs => ['macAddress', 'cn', 'ipHostNumber'],
+                               filter => "objectClass=goTerminalServer",
+                               );
+               if ($ldap_mesg->count) 
+               {       
+                       # Parse all LDAP results to a sql compliant where statement
+                       my @entries = $ldap_mesg->entries;
+                       @entries = map ($_->get_value("macAddress"), @entries);
+                       @entries = map ("macaddress LIKE '$_'", @entries);
+
+                       my ($hit, $hash, $db_res, $out_msg);
+                       # Check known clients if a terminal server is active
+                       $db_res = $main::known_clients_db->select_dbentry("SELECT * FROM $main::known_clients_tn WHERE ".join(" AND ", @entries));
+                       while (($hit, $hash) = each %$db_res) 
+                       {
+                               $out_msg = &create_xml_string(&create_xml_hash('get_load', $source, $hash->{macaddress}));
+                               push(@out_msg_l, $out_msg);
+                       }
+                       # Check foreign_clients if a terminal server is active
+                       $db_res = $main::foreign_clients_db->select_dbentry("SELECT * FROM $main::foreign_clients_tn WHERE ".join(" AND ", @entries));
+                       while (($hit, $hash) = each %$db_res) 
+                       {
+                               $out_msg = &create_xml_string(&create_xml_hash('get_load', $source, $hash->{macaddress}));
+                               push(@out_msg_l, $out_msg);
+                       }
 
+### JUST FOR DEBUGGING # CAN BE DELETED AT ANY TIME ###########################
+#                      my $db_res = $main::known_clients_db->select_dbentry("SELECT * FROM $main::known_clients_tn WHERE macaddress LIKE '00:01:6c:9d:b9:fa'");
+#                      while (($hit, $hash) = each %$db_res) 
+#                      {
+#                              $out_msg = &create_xml_string(&create_xml_hash('get_load', $source, $hash->{macaddress}));
+#                              push(@out_msg_l, $out_msg);
+#                      }
+### JUST FOR DEBUGGING # CAN BE DELETED AT ANY TIME ###########################
+
+                       # Found terminal server but no running clients on them
+                       if (@out_msg_l == 0) 
+                       {
+                               &main::daemon_log("$session_id ERROR: Found no running clients (known_clients_db, foreign_clients_db) on the following determined terminal server", 1);
+                               my @entries = $ldap_mesg->entries;
+                               foreach my $ts (@entries) 
+                               {
+                                       my $ip = (defined $ts->get_value("ipHostNumber")) ? "   ip='".$ts->get_value("ipHostNumber")."'" : "" ;
+                                       my $cn = (defined $ts->get_value("cn")) ? "   cn='".$ts->get_value("cn")."'" : "" ;
+                                       my $mac = (defined $ts->get_value("macAddress")) ? "   macAddress='".$ts->get_value("macAddress")."'" : "" ;
+                                       &main::daemon_log("$session_id ERROR: ".$cn.$mac.$ip , 1);
+                               }
+                       }
 
-sub read_configfile {
-    my ($cfg_file, %cfg_defaults) = @_;
-    my $cfg;
+               }
+               # No terminal server found in LDAP
+               if ($ldap_mesg->count == 0) 
+               {
+                       &main::daemon_log("$session_id ERROR: No terminal server found in LDAP: \n\tbase='$ldap_base'\n\tscope='sub'\n\tattrs='['macAddress']'\n\tfilter='objectClass=goTerminalServer'", 1);
+               }
 
-    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
-        if( -r $cfg_file ) {
-            $cfg = Config::IniFiles->new( -file => $cfg_file );
-        } else {
-            &main::daemon_log("ERROR: siTriggered.pm couldn't read config file!", 1);
-        }
-    } else {
-        $cfg = Config::IniFiles->new() ;
-    }
-    foreach my $section (keys %cfg_defaults) {
-        foreach my $param (keys %{$cfg_defaults{ $section }}) {
-            my $pinfo = $cfg_defaults{ $section }{ $param };
-            ${@$pinfo[0]} = $cfg->val( $section, $param, @$pinfo[1] );
-        }
-    }
+               # Translating errors ?
+               if ($ldap_mesg->code) 
+               {
+                       &main::daemon_log("$session_id ERROR: Cannot fetch terminal server from LDAP: \n\tbase='$ldap_base'\n\tscope='sub'\n\tattrs='['macAddress']'\n\tfilter='objectClass=goTerminalServer'", 1);
+               }
+       }
+       &main::release_ldap_handle($ldap_handle);
+
+    return @out_msg_l;
 }
 
 
+sub get_events {
+    return \@events;
+}
+
 sub reload_ldap_config {
     my ($msg, $msg_hash, $session_id) = @_;
     my $header = @{$msg_hash->{header}}[0];
     my $target = @{$msg_hash->{$header}}[0];
 
-    my $out_msg = &SIPackages::new_ldap_config($target);
+    my $out_msg = &ClientPackages::new_ldap_config($target, $session_id);
     my @out_msg_l = ( $out_msg );
     return @out_msg_l;
 }
@@ -112,6 +175,10 @@ sub got_ping {
     my $out_hash = &create_xml_hash($header, $source, "GOSA");
     &add_content2xml_hash($out_hash, "session_id", $session_id);
     $out_msg = &create_xml_string($out_hash);
+    my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
+    if (defined $forward_to_gosa) {
+        $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
+    }
     push(@out_msg_l, $out_msg);
     
     return @out_msg_l;
@@ -119,8 +186,9 @@ sub got_ping {
 
 
 sub detected_hardware {
-       my ($msg, $msg_hash, $session_id) = @_ ;
+       my ($msg, $msg_hash, $session_id) = @_;
        my $address = $msg_hash->{source}[0];
+       my $header = $msg_hash->{header}[0];
        my $gotoHardwareChecksum= $msg_hash->{detected_hardware}[0]->{gotoHardwareChecksum};
 
        my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$address'";
@@ -129,7 +197,7 @@ sub detected_hardware {
        # check hit
        my $hit_counter = keys %{$res};
        if( not $hit_counter == 1 ) {
-               &main::daemon_log("ERROR: more or no hit found in known_clients_db by query by '$address'", 1);
+               &main::daemon_log("$session_id ERROR: more or no hit found in known_clients_db by query by '$address'", 1);
                return;
        }
 
@@ -137,18 +205,13 @@ sub detected_hardware {
        my $hostkey = $res->{1}->{hostkey};
 
        if (not defined $macaddress) {
-               &main::daemon_log("ERROR: no mac address found for client $address", 1);
+               &main::daemon_log("$session_id ERROR: no mac address found for client $address", 1);
                return;
        }
-       # Build LDAP connection
-       &main::refresh_ldap_handle();
-       if( not defined $main::ldap_handle ) {
-               &main::daemon_log("ERROR: cannot connect to ldap: $ldap_uri", 1);
-               return;
-       } 
 
        # Perform search
-       $mesg = $main::ldap_handle->search(
+       my $ldap_handle = &main::get_ldap_handle();
+       $mesg = $ldap_handle->search(
                base   => $ldap_base,
                scope  => 'sub',
                filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))"
@@ -159,11 +222,14 @@ sub detected_hardware {
                &main::daemon_log("INFO: Need to create a new LDAP Entry for client $address", 4);
                my $ipaddress= $1 if $address =~ /^([0-9\.]*?):.*$/;
                my $dnsname;
-               if (defined($msg_hash->{'force-hostname'}) && 
-                       defined($msg_hash->{'force-hostname'}[0]) &&
-                       length($msg_hash->{'force-hostname'}[0]) > 0){
-                       $dnsname= $msg_hash->{'force-hostname'}[0];
-                       &main::daemon_log("INFO: Using forced hostname $dnsname for client $address", 4);
+               #FIXME: like in ClientPackages!
+               #if ( defined($heap->{force-hostname}->{$macaddress}) ){
+               #       $dnsname= $heap->{force-hostname}->{$macaddress};
+               #       &main::daemon_log("INFO: Using forced hostname $dnsname for client $address", 4);
+               if (-e "/var/tmp/$macaddress" ){
+                       open(my $TFILE, "<", "/var/tmp/$macaddress");
+                       $dnsname= <$TFILE>;
+                       close($TFILE);
                } else {
                        $dnsname= gethostbyaddr(inet_aton($ipaddress), AF_INET) || $ipaddress;
                }
@@ -173,7 +239,7 @@ sub detected_hardware {
                &main::daemon_log("INFO: Creating entry for $dn",5);
                my $entry= Net::LDAP::Entry->new( $dn );
                $entry->dn($dn);
-               $entry->add("objectClass" => "goHard");
+               $entry->add("objectClass" => "GOhard");
                $entry->add("cn" => $cn);
                $entry->add("macAddress" => $macaddress);
                $entry->add("gotomode" => "locked");
@@ -183,14 +249,15 @@ sub detected_hardware {
                        $entry->add("objectClass" => "gosaAdministrativeUnitTag");
                        $entry->add("gosaUnitTag" => $main::gosa_unit_tag);
                }
-               my $res=$entry->update($main::ldap_handle);
+               my $res=$entry->update($ldap_handle);
                if(defined($res->{'errorMessage'}) &&
                        length($res->{'errorMessage'}) >0) {
                        &main::daemon_log("ERROR: can not add entries to LDAP: ".$res->{'errorMessage'}, 1);
+                       &main::release_ldap_handle($ldap_handle);
                        return;
                } else {
                        # Fill $mesg again
-                       $mesg = $main::ldap_handle->search(
+                       $mesg = $ldap_handle->search(
                                base   => $ldap_base,
                                scope  => 'sub',
                                filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))"
@@ -208,7 +275,7 @@ sub detected_hardware {
                        if(defined($msg_hash->{detected_hardware}[0]->{$attribute}) &&
                                length($msg_hash->{detected_hardware}[0]->{$attribute}) >0 ) {
                                if(defined($entry->get_value($attribute))) {
-                                       $entry->delete($attribute);
+                                       $entry->delete($attribute => []);
                                }
                                &main::daemon_log("INFO: Adding attribute $attribute with value ".$msg_hash->{detected_hardware}[0]->{$attribute},5);
                                $entry->add($attribute => $msg_hash->{detected_hardware}[0]->{$attribute});     
@@ -219,67 +286,29 @@ sub detected_hardware {
                        if(defined($msg_hash->{detected_hardware}[0]->{$attribute}) &&
                                length($msg_hash->{detected_hardware}[0]->{$attribute}) >0 ) {
                                if(defined($entry->get_value($attribute))) {
-                                       $entry->delete($attribute);
+                                       $entry->delete($attribute => []);
                                }
-                               foreach my $array_entry (@{$msg_hash->{detected_hardware}[0]->{$attribute}}) {
+                               foreach my $array_entry (keys %{{map { $_ => 1 } sort(@{$msg_hash->{detected_hardware}[0]->{$attribute}}) }}) {
                                        $entry->add($attribute => $array_entry);
                                }
                        }
                }
 
-               my $res=$entry->update($main::ldap_handle);
+               my $res=$entry->update($ldap_handle);
                if(defined($res->{'errorMessage'}) &&
                        length($res->{'errorMessage'}) >0) {
                        &main::daemon_log("ERROR: can not add entries to LDAP: ".$res->{'errorMessage'}, 1);
                } else {
                        &main::daemon_log("INFO: Added Hardware configuration to LDAP", 5);
                }
-
        }
-       return ;
-}
-
-
-sub trigger_wake {
-    my ($msg, $msg_hash, $session_id) = @_ ;
-
-    foreach (@{$msg_hash->{macAddress}}){
-        &main::daemon_log("INFO: trigger wake for $_", 5);
-        my $host    = $_;
-        my $ipaddr  = '255.255.255.255';
-        my $port    = getservbyname('discard', 'udp');
-
-        my ($raddr, $them, $proto);
-        my ($hwaddr, $hwaddr_re, $pkt);
-
-        # get the hardware address (ethernet address)
-        $hwaddr_re = join(':', ('[0-9A-Fa-f]{1,2}') x 6);
-        if ($host =~ m/^$hwaddr_re$/) {
-          $hwaddr = $host;
-        } else {
-          &main::daemon_log("ERROR: trigger_wake called with non mac address", 1);
-        }
 
-        # Generate magic sequence
-        foreach (split /:/, $hwaddr) {
-                $pkt .= chr(hex($_));
-        }
-        $pkt = chr(0xFF) x 6 . $pkt x 16;
+       # if there is a job in job queue for this host and this macaddress, delete it, cause its no longer used
+       my $del_sql = "DELETE FROM $main::job_queue_tn WHERE (macaddress LIKE '$macaddress' AND headertag='$header')";
+       my $del_res = $main::job_db->exec_statement($del_sql);
+  &main::release_ldap_handle($ldap_handle);
 
-        # Allocate socket and send packet
-
-        $raddr = gethostbyname($ipaddr)->addr;
-        $them = pack_sockaddr_in($port, $raddr);
-        $proto = getprotobyname('udp');
-
-        socket(S, AF_INET, SOCK_DGRAM, $proto) or die "socket : $!";
-        setsockopt(S, SOL_SOCKET, SO_BROADCAST, 1) or die "setsockopt : $!";
-
-        send(S, $pkt, 0, $them) or die "send : $!";
-        close S;
-    }
-
-    return;
+       return ;
 }
 
 1;