Code

Fixed dialog ignore account state
[gosa.git] / gosa-si / modules / GosaSupportDaemon.pm
index 526afd36c146285bf6738cf59da4d31fec0813ae..9c33df325d1a937c45dfc85392be2cbcda85349a 100644 (file)
@@ -1,10 +1,27 @@
 package GOSA::GosaSupportDaemon;
 
+use strict;
+use warnings;
+
 use Exporter;
-@ISA = qw(Exporter);
+use IO::Socket::INET;
+use Crypt::Rijndael;
+use Digest::MD5  qw(md5 md5_hex md5_base64);
+use MIME::Base64;
+use XML::Quote qw(:all);
+use XML::Simple;
+use Data::Dumper;
+use Net::DNS;
+use Net::ARP;
+use DateTime;
+
+our @ISA = qw(Exporter);
+
 my @functions = (
     "create_passwd",
     "create_xml_hash",
+    "createXmlHash",
+    "myXmlHashToString",
     "get_content_from_xml_hash",
     "add_content2xml_hash",
     "create_xml_string",
@@ -36,19 +53,9 @@ my @functions = (
     "check_opsi_res",
     "calc_timestamp",
     "opsi_callobj2string",
-    ); 
-@EXPORT = @functions;
-use strict;
-use warnings;
-use IO::Socket::INET;
-use Crypt::Rijndael;
-use Digest::MD5  qw(md5 md5_hex md5_base64);
-use MIME::Base64;
-use XML::Simple;
-use Data::Dumper;
-use Net::DNS;
-use DateTime;
-
+    );
+    
+our @EXPORT = @functions;
 
 my $op_hash = {
     'eq' => '=',
@@ -67,7 +74,7 @@ END {}
 
 ### Start ######################################################################
 
-my $xml = new XML::Simple();
+our $xml = new XML::Simple();
 
 sub daemon_log {
     my ($msg, $level) = @_ ;
@@ -113,6 +120,91 @@ sub create_xml_hash {
     return $hash
 }
 
+sub createXmlHash {
+       my ($header, $source, $target) = @_;
+       return { header=>$header, source=>$source, target=>$target};
+}
+
+sub _transformHashToString {
+       my ($hash) = @_;
+       my $s = "";
+
+       while (my ($tag, $content) = each(%$hash)) {
+
+               if (ref $content eq "HASH") {
+                       $s .= "<$tag>".&_transformHashToString($content)."</$tag>";
+               } elsif ( ref $content eq "ARRAY") {
+                       $s .= &_transformArrayToString($tag, $content);
+               } else {
+                       $content = defined $content ? $content : "";
+                       $s .= "<$tag>".&xml_quote($content)."</$tag>";
+               }
+       }
+       return $s;
+}
+
+sub _transformArrayToString {
+       my ($tag, $contentArray) = @_;
+       my $s = "";
+       foreach my $content (@$contentArray) {
+               if (ref $content eq "HASH") {
+                       $s .= "<$tag>".&_transformHashToString($content)."</$tag>";
+               } else {
+                       $content = defined $content ? $content : "";
+                       $s .= "<$tag>".&xml_quote($content)."</$tag>";
+               }
+       }
+       return $s;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  myXmlHashToString
+#   PARAMETERS:  xml_hash - hash - hash from function createXmlHash
+#      RETURNS:  xml_string - string - xml string representation of the hash
+#  DESCRIPTION:  Transforms the given hash to a xml wellformed string. I.e.:
+#                   {
+#                   'header' => 'a'
+#                   'source' => 'c',
+#                   'target' => 'b',
+#                   'hit' => [ '1',
+#                              '2',
+#                              { 
+#                                'hit31' => 'ABC',
+#                               'hit32' => 'XYZ'
+#                              }
+#                            ],
+#                   'res0' => {
+#                      'res1' => {
+#                         'res2' => 'result'
+#                      }
+#                   },
+#               };
+#           
+#                               will be transformed to 
+#                               <xml>
+#                                      <header>a</header>
+#                                      <source>c</source>
+#                                      <target>b</target>
+#                                      <hit>1</hit>
+#                                      <hit>2</hit>
+#                                      <hit>
+#                                              <hit31>ABC</hit31>
+#                                              <hit32>XYZ</hit32>
+#                                      </hit>
+#                                      <res0>
+#                                              <res1>
+#                                                      <res2>result</res2>
+#                                              </res1>
+#                                      </res0>
+#                              </xml>
+#
+#===============================================================================
+sub myXmlHashToString {
+       my ($hash) = @_;
+       return "<xml>".&_transformHashToString($hash)."</xml>";
+}
+
 
 #===  FUNCTION  ================================================================
 #         NAME:  create_xml_string
@@ -422,8 +514,8 @@ sub get_orderby_statement {
 sub get_dns_domains() {
         my $line;
         my @searches;
-        open(RESOLV, "</etc/resolv.conf") or return @searches;
-        while(<RESOLV>){
+        open(my $RESOLV, "<", "/etc/resolv.conf") or return @searches;
+        while(<$RESOLV>){
                 $line= $_;
                 chomp $line;
                 $line =~ s/^\s+//;
@@ -435,7 +527,7 @@ sub get_dns_domains() {
                         push(@searches, split(/ /, $1));
                 }
         }
-        close(RESOLV);
+        close($RESOLV);
 
         my %tmp = map { $_ => 1 } @searches;
         @searches = sort keys %tmp;
@@ -600,6 +692,15 @@ sub get_ip {
 sub get_interface_for_ip {
        my $result;
        my $ip= shift;
+
+       if($ip =~ /^[a-z]/i) {
+               my $ip_address = inet_ntoa(scalar gethostbyname($ip));
+               if(defined($ip_address) && $ip_address =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {
+                       # Write ip address to $source variable
+                       $ip = $ip_address;
+               }
+       }
+
        if ($ip && length($ip) > 0) {
                my @ifs= &get_interfaces();
                if($ip eq "0.0.0.0") {
@@ -626,12 +727,12 @@ sub get_interfaces {
        my @result;
        my $PROC_NET_DEV= ('/proc/net/dev');
 
-       open(PROC_NET_DEV, "<$PROC_NET_DEV")
+       open(my $FD_PROC_NET_DEV, "<", "$PROC_NET_DEV")
                or die "Could not open $PROC_NET_DEV";
 
-       my @ifs = <PROC_NET_DEV>;
+       my @ifs = <$FD_PROC_NET_DEV>;
 
-       close(PROC_NET_DEV);
+       close($FD_PROC_NET_DEV);
 
        # Eat first two line
        shift @ifs;
@@ -654,27 +755,46 @@ sub get_local_ip_for_remote_ip {
     if($remote_ip =~ /^(\d\d?\d?\.){3}\d\d?\d?$/) {
         my $PROC_NET_ROUTE= ('/proc/net/route');
 
-        open(PROC_NET_ROUTE, "<$PROC_NET_ROUTE")
+        open(my $FD_PROC_NET_ROUTE, "<", "$PROC_NET_ROUTE")
             or die "Could not open $PROC_NET_ROUTE";
 
-        my @ifs = <PROC_NET_ROUTE>;
+        my @ifs = <$FD_PROC_NET_ROUTE>;
 
-        close(PROC_NET_ROUTE);
+        close($FD_PROC_NET_ROUTE);
 
         # Eat header line
         shift @ifs;
         chomp @ifs;
+        my $iffallback = ''; 
+
+        # linux-vserver might have * as Iface due to hidden interfaces, set a default 
+        foreach my $line(@ifs) { 
+            my ($Iface,$Destination,$Gateway,$Flags,$RefCnt,$Use,$Metric,$Mask,$MTU,$Window,$IRTT)=split(/\s/, $line); 
+            if ($Iface =~ m/^[^\*]+$/) { 
+                 $iffallback = $Iface; 
+            } 
+        }
         foreach my $line(@ifs) {
             my ($Iface,$Destination,$Gateway,$Flags,$RefCnt,$Use,$Metric,$Mask,$MTU,$Window,$IRTT)=split(/\s/, $line);
             my $destination;
             my $mask;
             my ($d,$c,$b,$a)=unpack('a2 a2 a2 a2', $Destination);
+            if ($Iface =~ m/^[^\*]+$/) { 
+                 $iffallback = $Iface;
+            } 
             $destination= sprintf("%d.%d.%d.%d", hex($a), hex($b), hex($c), hex($d));
             ($d,$c,$b,$a)=unpack('a2 a2 a2 a2', $Mask);
             $mask= sprintf("%d.%d.%d.%d", hex($a), hex($b), hex($c), hex($d));
             if(new NetAddr::IP($remote_ip)->within(new NetAddr::IP($destination, $mask))) {
                 # destination matches route, save mac and exit
-                $result= &get_ip($Iface);
+                #$result= &get_ip($Iface);
+
+                if ($Iface =~ m/^\*$/ ) { 
+                    $result= &get_ip($iffallback);    
+                } else { 
+                    $result= &get_ip($Iface); 
+                } 
                 last;
             }
         }
@@ -687,29 +807,11 @@ sub get_local_ip_for_remote_ip {
 sub get_mac_for_interface {
        my $ifreq= shift;
        my $result;
-       if ($ifreq && length($ifreq) > 0) { 
+       if ($ifreq && length($ifreq) > 0) {
                if($ifreq eq "all") {
                        $result = "00:00:00:00:00:00";
                } else {
-                       my $SIOCGIFHWADDR= 0x8927;     # man 2 ioctl_list
-
-                       # A configured MAC Address should always override a guessed value
-                       if ($main::server_mac_address and length($main::server_mac_address) > 0) {
-                               $result= $main::server_mac_address;
-                       }
-
-                       socket SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('ip')
-                               or die "socket: $!";
-
-                       if(ioctl SOCKET, $SIOCGIFHWADDR, $ifreq) {
-                               my ($if, $mac)= unpack 'h36 H12', $ifreq;
-
-                               if (length($mac) > 0) {
-                                       $mac=~ m/^([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/;
-                                       $mac= sprintf("%s:%s:%s:%s:%s:%s", $1, $2, $3, $4, $5, $6);
-                                       $result = $mac;
-                               }
-                       }
+        $result = Net::ARP::get_mac($ifreq);
                }
        }
        return $result;
@@ -757,10 +859,12 @@ sub run_as {
                &main::daemon_log("ERROR: The sudo utility is not available! Please fix this!");
        }
        my $cmd_line= "$sudo_cmd su - $uid -c '$command'";
-       open(PIPE, "$cmd_line |");
-       my $result = {'resultCode' => $?};
-       $result->{'command'} = $cmd_line;
-       push @{$result->{'output'}}, <PIPE>;
+       open(my $PIPE, "$cmd_line |");
+       my $result = {'command' => $cmd_line};
+       push @{$result->{'output'}}, <$PIPE>;
+       close($PIPE);
+       my $exit_value = $? >> 8;
+       $result->{'resultCode'} = $exit_value;
        return $result;
 }
 
@@ -827,20 +931,27 @@ sub check_opsi_res {
         if ($res->is_error) {
             my $error_string;
             if (ref $res->error_message eq "HASH") { 
+                               # for different versions
                 $error_string = $res->error_message->{'message'}; 
+                               $_ = $res->error_message->{'message'};
             } else { 
+                               # for different versions
                 $error_string = $res->error_message; 
+                               $_ = $res->error_message;
             }
             return 1, $error_string;
         }
     } else {
+               # for different versions
+               $_ = $main::opsi_client->status_line;
         return 1, $main::opsi_client->status_line;
     }
     return 0;
 }
 
 sub calc_timestamp {
-    my ($timestamp, $operation, $value) = @_ ;
+    my ($timestamp, $operation, $value, $entity) = @_ ;
+       $entity = defined $entity ? $entity : "seconds";
     my $res_timestamp = 0;
     
     $value = int($value);
@@ -855,12 +966,12 @@ sub calc_timestamp {
             );
 
     if ($operation eq "plus" || $operation eq "+") {
-        $dt->add( seconds => $value);
+        $dt->add($entity => $value);
         $res_timestamp = $dt->ymd('').$dt->hms('');
     }
 
     if ($operation eq "minus" || $operation eq "-") {
-        $dt->subtract(seconds => $value);
+        $dt->subtract($entity => $value);
         $res_timestamp = $dt->ymd('').$dt->hms('');
     }