X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fmodules%2FSIPackages.pm;h=bc1be2ff8cd024b3a19074c4a705927e18e09350;hb=78afc9913ee9b1841ab1a23078c86d69987d82d3;hp=1d3213a91a31dfa482bebe2dcfc23b9bb8601d74;hpb=3f00a5e0ed7883a4e41ab9452ae9b05887e19188;p=gosa.git diff --git a/gosa-si/modules/SIPackages.pm b/gosa-si/modules/SIPackages.pm index 1d3213a91..bc1be2ff8 100644 --- a/gosa-si/modules/SIPackages.pm +++ b/gosa-si/modules/SIPackages.pm @@ -12,41 +12,42 @@ use GOSA::GosaSupportDaemon; use IO::Socket::INET; use XML::Simple; use Data::Dumper; +use NetAddr::IP; use Net::LDAP; use Socket; use Net::hostent; +use Net::DNS; BEGIN{} END {} -my ($known_clients_file_name); -my ($server_activ, $server_ip, $server_mac_address, $server_port, $SIPackages_key, $max_clients, $ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password); -my ($bus_activ, $bus_passwd, $bus_ip, $bus_port); +my ($server_ip, $server_mac_address, $server_port, $SIPackages_key, $max_clients, $ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password, $server_interface); +my ($bus_activ, $bus_key, $bus_ip, $bus_port); my $server; my $network_interface; my $no_bus; my (@ldap_cfg, @pam_cfg, @nss_cfg, $goto_admin, $goto_secret); -my %cfg_defaults = -( -"server" => - {"server_activ" => [\$server_activ, "on"], - "server_ip" => [\$server_ip, "0.0.0.0"], - "server_mac_address" => [\$server_mac_address, ""], - "server_port" => [\$server_port, "20081"], - "SIPackages_key" => [\$SIPackages_key, ""], - "max_clients" => [\$max_clients, 100], - "ldap_uri" => [\$ldap_uri, ""], - "ldap_base" => [\$ldap_base, ""], - "ldap_admin_dn" => [\$ldap_admin_dn, ""], - "ldap_admin_password" => [\$ldap_admin_password, ""], +my %cfg_defaults = ( +"bus" => { + "activ" => [\$bus_activ, "on"], + "key" => [\$bus_key, ""], + "ip" => [\$bus_ip, ""], + "port" => [\$bus_port, "20080"], }, -"bus" => - {"bus_activ" => [\$bus_activ, "on"], - "bus_passwd" => [\$bus_passwd, ""], - "bus_ip" => [\$bus_ip, ""], - "bus_port" => [\$bus_port, "20080"], +"server" => { + "ip" => [\$server_ip, "0.0.0.0"], + "mac-address" => [\$server_mac_address, "00:00:00:00:00"], + "port" => [\$server_port, "20081"], + "ldap-uri" => [\$ldap_uri, ""], + "ldap-base" => [\$ldap_base, ""], + "ldap-admin-dn" => [\$ldap_admin_dn, ""], + "ldap-admin-password" => [\$ldap_admin_password, ""], + "max-clients" => [\$max_clients, 100], + }, +"SIPackages" => { + "key" => [\$SIPackages_key, ""], }, ); @@ -55,16 +56,17 @@ my %cfg_defaults = # read configfile and import variables &read_configfile(); -# detect interfaces and mac address $network_interface= &get_interface_for_ip($server_ip); -$server_mac_address= &get_mac($network_interface); +$server_mac_address= &get_mac($network_interface); # complete addresses -if( $server_ip eq "0.0.0.0" ) { - $server_ip = "127.0.0.1"; -} +#if( $server_ip eq "0.0.0.0" ) { +# $server_ip = "127.0.0.1"; +#} my $server_address = "$server_ip:$server_port"; +$main::server_address = $server_address; my $bus_address = "$bus_ip:$bus_port"; +$main::bus_address = $bus_address; # create general settings for this module my $xml = new XML::Simple(); @@ -94,15 +96,11 @@ my $res = $main::known_server_db->add_dbentry( {table=>'known_server', sub get_module_info { my @info = ($server_address, $SIPackages_key, - $server, - $server_activ, - "socket", ); return \@info; } - sub do_wake { my $host = shift; my $ipaddr = shift || '255.255.255.255'; @@ -295,34 +293,6 @@ sub get_mac { return $result; } -#=== FUNCTION ================================================================ -# NAME: get_ip -# PARAMETERS: interface name (i.e. eth0) -# RETURNS: (ip address) -# DESCRIPTION: Uses ioctl to get ip address directly from system. -#=============================================================================== -sub get_ip { - my $ifreq= shift; - my $result= ""; - my $SIOCGIFADDR= 0x8915; # man 2 ioctl_list - my $proto= getprotobyname('ip'); - - socket SOCKET, PF_INET, SOCK_DGRAM, $proto - or die "socket: $!"; - - if(ioctl SOCKET, $SIOCGIFADDR, $ifreq) { - my ($if, $sin) = unpack 'a16 a16', $ifreq; - my ($port, $addr) = sockaddr_in $sin; - my $ip = inet_ntoa $addr; - - if ($ip && length($ip) > 0) { - $result = $ip; - } - } - - return $result; -} - #=== FUNCTION ================================================================ # NAME: register_at_bus @@ -337,20 +307,14 @@ sub register_at_bus { primkey=>'hostname', hostname=>$bus_address, status=>'bus', - hostkey=>$bus_passwd, + hostkey=>$bus_key, timestamp=>&get_time, } ); my $msg_hash = &create_xml_hash("here_i_am", $server_address, $bus_address); my $msg = &create_xml_string($msg_hash); + + &main::send_msg_to_target($msg, $bus_address, $bus_key, "here_i_am"); return $msg; -# my $answer = ""; -# $answer = &send_msg_hash2address($msg_hash, $bus_address, $bus_passwd); -# if ($answer == 0) { -# &main::daemon_log("register at bus: $bus_address", 1); -# } else { -# &main::daemon_log("unable to send 'register'-msg to bus '$bus_address': $answer", 1); -# } -# return; } @@ -361,7 +325,7 @@ sub register_at_bus { # DESCRIPTION: handels the proceeded distribution to the appropriated functions #=============================================================================== sub process_incoming_msg { - my ($msg, $msg_hash) = @_ ; + my ($msg, $msg_hash, $remote_ip) = @_ ; my $error = 0; my $host_name; my $host_key; @@ -369,7 +333,6 @@ sub process_incoming_msg { # process incoming msg my $header = @{$msg_hash->{header}}[0]; - my $source = @{$msg_hash->{source}}[0]; my @target_l = @{$msg_hash->{target}}; &main::daemon_log("SIPackages: msg to process: $header", 3); @@ -382,26 +345,26 @@ sub process_incoming_msg { if( 1 == length @target_l) { my $target = $target_l[0]; - if( $target eq $server_address ) { - if ($header eq 'new_passwd') { - @out_msg_l = &new_passwd($msg_hash) - } elsif ($header eq 'here_i_am') { - @out_msg_l = &here_i_am($msg_hash) - } elsif ($header eq 'who_has') { - @out_msg_l = &who_has($msg_hash) - } elsif ($header eq 'who_has_i_do') { - @out_msg_l = &who_has_i_do($msg_hash) - } elsif ($header eq 'got_ping') { - @out_msg_l = &got_ping($msg_hash) - } elsif ($header eq 'get_load') { - @out_msg_l = &execute_actions($msg_hash) + if(&server_matches($target)) { + if ($header eq 'new_key') { + @out_msg_l = &new_key($msg_hash) + } elsif ($header eq 'here_i_am') { + @out_msg_l = &here_i_am($msg_hash) + } elsif ($header eq 'who_has') { + @out_msg_l = &who_has($msg_hash) + } elsif ($header eq 'who_has_i_do') { + @out_msg_l = &who_has_i_do($msg_hash) + } elsif ($header eq 'got_ping') { + @out_msg_l = &got_ping($msg_hash) + } elsif ($header eq 'get_load') { + @out_msg_l = &execute_actions($msg_hash) } elsif ($header eq 'detected_hardware') { - @out_msg_l = &process_detected_hardware($msg_hash) - } elsif ($header eq 'trigger_wake') { - foreach (@{$msg_hash->{macAddress}}){ - &main::daemon_log("SIPackages: trigger wake for $_", 1); - do_wake($_); - } + @out_msg_l = &process_detected_hardware($msg_hash) + } elsif ($header eq 'trigger_wake') { + foreach (@{$msg_hash->{macAddress}}){ + &main::daemon_log("SIPackages: trigger wake for $_", 1); + do_wake($_); + } } else { &main::daemon_log("ERROR: $header is an unknown core function", 1); @@ -414,11 +377,11 @@ sub process_incoming_msg { } } - if( $error == 0) { - if( 0 == @out_msg_l ) { - push(@out_msg_l, $msg); - } - } +# if( $error == 0) { +# if( 0 == @out_msg_l ) { +# push(@out_msg_l, $msg); +# } +# } return \@out_msg_l; } @@ -453,13 +416,13 @@ sub got_ping { # RETURNS: nothing # DESCRIPTION: process this incoming message #=============================================================================== -sub new_passwd { +sub new_key { my ($msg_hash) = @_; my @out_msg_l; my $header = @{$msg_hash->{header}}[0]; my $source_name = @{$msg_hash->{source}}[0]; - my $source_key = @{$msg_hash->{new_passwd}}[0]; + my $source_key = @{$msg_hash->{new_key}}[0]; my $query_res; # check known_clients_db @@ -471,8 +434,7 @@ sub new_passwd { "SET hostkey='$source_key', timestamp='$act_time' ". "WHERE hostname='$source_name'"; my $res = $main::known_clients_db->update_dbentry( $sql_statement ); - - my $hash = &create_xml_hash("confirm_new_passwd", $server_address, $source_name); + my $hash = &create_xml_hash("confirm_new_key", $server_address, $source_name); my $out_msg = &create_xml_string($hash); push(@out_msg_l, $out_msg); } @@ -489,7 +451,7 @@ sub new_passwd { "WHERE hostname='$source_name'"; my $res = $main::known_server_db->update_dbentry( $sql_statement ); - my $hash = &create_xml_hash("confirm_new_passwd", $server_address, $source_name); + my $hash = &create_xml_hash("confirm_new_key", $server_address, $source_name); my $out_msg = &create_xml_string($hash); push(@out_msg_l, $out_msg); } @@ -549,6 +511,7 @@ sub here_i_am { # add entry to known_clients_db + my $act_timestamp = &get_time; my $res = $main::known_clients_db->add_dbentry( {table=>'known_clients', primkey=>'hostname', hostname=>$source, @@ -556,7 +519,7 @@ sub here_i_am { macaddress=>$mac_address, status=>'registered', hostkey=>$new_passwd, - timestamp=>&get_time, + timestamp=>$act_timestamp, } ); if ($res != 0) { @@ -578,6 +541,8 @@ sub here_i_am { # send update msg to bus $out_hash = &create_xml_hash("new_client", $server_address, $bus_address, $source); + &add_content2xml_hash($out_hash, "macaddress", $mac_address); + &add_content2xml_hash($out_hash, "timestamp", $act_timestamp); my $new_client_out = &create_xml_string($out_hash); push(@out_msg_l, $new_client_out); &main::daemon_log("send bus msg that client '$source' has registerd at server '$server_address'", 3); @@ -760,7 +725,7 @@ sub new_ldap_config { # Find admin base and department name $mesg = $ldap->search( base => $ldap_base, scope => 'sub', - attrs => ['dn', 'ou'], + attrs => ['dn', 'ou', 'FAIclass'], filter => "(&(objectClass=gosaAdministrativeUnit)(gosaUnitTag=$unit_tag))"); #$mesg->code && die $mesg->error; if($mesg->code) { @@ -782,6 +747,13 @@ sub new_ldap_config { $data{'unit_tag'}= $unit_tag; } + # Fill release if available + my $FAIclass= $entry->get_value("FAIclass"); + if (defined $FAIclass && $FAIclass =~ /^.* :([A-Za-z0-9\/.]+).*$/) { + $data{'release'}= $1; + } + + # Unbind $mesg = $ldap->unbind; @@ -792,6 +764,7 @@ sub new_ldap_config { sub process_detected_hardware { my $msg_hash = shift; my $address = $msg_hash->{source}[0]; + my $gotoHardwareChecksum= $msg_hash->{detected_hardware}[0]->{gotoHardwareChecksum}; my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$address'"; my $res = $main::known_clients_db->select_dbentry( $sql_statement ); @@ -800,6 +773,7 @@ sub process_detected_hardware { 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); + return; } my $macaddress = $res->{1}->{macaddress}; @@ -826,13 +800,44 @@ sub process_detected_hardware { filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))" ); + # We need to create a base entry first (if not done from ArpHandler) + if($mesg->count == 0) { + &main::daemon_log("Need to create a new LDAP Entry for client $address", 1); + my $resolver=Net::DNS::Resolver->new; + my $ipaddress= $1 if $address =~ /^([0-9\.]*?):.*$/; + my $dnsresult= $resolver->search($ipaddress); + my $dnsname= (defined($dnsresult))?$dnsresult->{answer}[0]->{ptrdname}:$ipaddress; + my $cn = (($dnsname =~ /^(\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3}/) ? $dnsname : sprintf "%s", $dnsname =~ /([^\.]+)\.?/); + my $dn = "cn=$cn,ou=incoming,$ldap_base"; + &main::daemon_log("Creating entry for $dn",6); + my $entry= Net::LDAP::Entry->new( $dn ); + $entry->dn($dn); + $entry->add("objectClass" => "goHard"); + $entry->add("cn" => $cn); + $entry->add("macAddress" => $macaddress); + $entry->add("gotomode" => "locked"); + $entry->add("gotoSysStatus" => "new-system"); + $entry->add("ipHostNumber" => $ipaddress); + if(my $res=$entry->update($ldap)) { + # Fill $mesg again + $mesg = $ldap->search( + base => $ldap_base, + scope => 'sub', + filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))" + ); + } else { + &main::daemon_log("ERROR: There was a problem adding the entry", 1); + } + + } + if($mesg->count == 1) { my $entry= $mesg->entry(0); $entry->changetype("modify"); foreach my $attribute ( "gotoSndModule", "ghNetNic", "gotoXResolution", "ghSoundAdapter", "ghCpuType", "gotoXkbModel", "ghGfxAdapter", "gotoXMousePort", "ghMemSize", "gotoXMouseType", "ghUsbSupport", "gotoXHsync", - "gotoXDriver", "gotoXVsync", "gotoXMonitor") { + "gotoXDriver", "gotoXVsync", "gotoXMonitor", "gotoHardwareChecksum") { if(defined($msg_hash->{detected_hardware}[0]->{$attribute})) { if(defined($entry->get_value($attribute))) { $entry->delete($attribute); @@ -853,6 +858,7 @@ sub process_detected_hardware { } } + if($entry->update($ldap)) { &main::daemon_log("Added Hardware configuration to LDAP", 4); } @@ -905,71 +911,69 @@ sub hardware_config { if($mesg->count() == 0) { &main::daemon_log("Host was not found in LDAP!", 1); - return; - } - - my $entry= $mesg->entry(0); - my $dn= $entry->dn; - if(defined($entry->get_value("gotoHardwareChecksum"))) { - if(! $entry->get_value("gotoHardwareChecksum") eq $gotoHardwareChecksum) { - $entry->replace(gotoHardwareChecksum => $gotoHardwareChecksum); - if($entry->update($ldap)) { - &main::daemon_log("Hardware changed! Detection triggered.", 4); - } - } else { - # Nothing to do - return; - } } else { - # need to fill it to LDAP - $entry->add(gotoHardwareChecksum => $gotoHardwareChecksum); - if($entry->update($ldap)) { - &main::daemon_log("gotoHardwareChecksum $gotoHardwareChecksum was added to LDAP", 4); - } - - # Look if there another host with this checksum to use the hardware config - $mesg = $ldap->search( - base => $ldap_base, - scope => 'sub', - filter => "(&(objectClass=GOhard)(gotoHardwareChecksum=$gotoHardwareChecksum))" - ); - - if($mesg->count>1) { - my $clone_entry= $mesg->entry(0); - $entry->changetype("modify"); - foreach my $attribute ( - "gotoSndModule", "ghNetNic", "gotoXResolution", "ghSoundAdapter", "ghCpuType", "gotoXkbModel", - "ghGfxAdapter", "gotoXMousePort", "ghMemSize", "gotoXMouseType", "ghUsbSupport", "gotoXHsync", - "gotoXDriver", "gotoXVsync", "gotoXMonitor") { - my $value= $clone_entry->get_value($attribute); - if(defined($value)) { - if(defined($entry->get_value($attribute))) { - $entry->delete($attribute); - } - &main::daemon_log("Adding attribute $attribute with value $value",1); - $entry->add($attribute => $value); - } - } - foreach my $attribute ( - "gotoModules", "ghScsiDev", "ghIdeDev") { - my $array= $clone_entry->get_value($attribute, 'as_ref' => 1); - if(defined($array)) { - if(defined($entry->get_value($attribute))) { - $entry->delete($attribute); - } - foreach my $array_entry (@{$array}) { - $entry->add($attribute => $array_entry); - } + my $entry= $mesg->entry(0); + my $dn= $entry->dn; + if(defined($entry->get_value("gotoHardwareChecksum"))) { + if(! $entry->get_value("gotoHardwareChecksum") eq $gotoHardwareChecksum) { + $entry->replace(gotoHardwareChecksum => $gotoHardwareChecksum); + if($entry->update($ldap)) { + &main::daemon_log("Hardware changed! Detection triggered.", 4); } - + } else { + # Nothing to do + return; } - if($entry->update($ldap)) { - &main::daemon_log("Added Hardware configuration to LDAP", 4); - } - } + } + # need to fill it to LDAP + #$entry->add(gotoHardwareChecksum => $gotoHardwareChecksum); + #if($entry->update($ldap)) { + # &main::daemon_log("gotoHardwareChecksum $gotoHardwareChecksum was added to LDAP", 4); + #} + + ## Look if there another host with this checksum to use the hardware config + #$mesg = $ldap->search( + # base => $ldap_base, + # scope => 'sub', + # filter => "(&(objectClass=GOhard)(gotoHardwareChecksum=$gotoHardwareChecksum))" + #); + + #if($mesg->count>1) { + # my $clone_entry= $mesg->entry(0); + # $entry->changetype("modify"); + # foreach my $attribute ( + # "gotoSndModule", "ghNetNic", "gotoXResolution", "ghSoundAdapter", "ghCpuType", "gotoXkbModel", + # "ghGfxAdapter", "gotoXMousePort", "ghMemSize", "gotoXMouseType", "ghUsbSupport", "gotoXHsync", + # "gotoXDriver", "gotoXVsync", "gotoXMonitor") { + # my $value= $clone_entry->get_value($attribute); + # if(defined($value)) { + # if(defined($entry->get_value($attribute))) { + # $entry->delete($attribute); + # } + # &main::daemon_log("Adding attribute $attribute with value $value",1); + # $entry->add($attribute => $value); + # } + # } + # foreach my $attribute ( + # "gotoModules", "ghScsiDev", "ghIdeDev") { + # my $array= $clone_entry->get_value($attribute, 'as_ref' => 1); + # if(defined($array)) { + # if(defined($entry->get_value($attribute))) { + # $entry->delete($attribute); + # } + # foreach my $array_entry (@{$array}) { + # $entry->add($attribute => $array_entry); + # } + # } + + # } + # if($entry->update($ldap)) { + # &main::daemon_log("Added Hardware configuration to LDAP", 4); + # } + + #} - } # Assemble data package my %data = (); @@ -984,11 +988,56 @@ sub hardware_config { $mesg = $ldap->unbind; &main::daemon_log("Send detect_hardware message to $address", 4); - + # Send information return send_msg("detect_hardware", $server_address, $address, \%data); } +sub server_matches { + my $target = shift; + my $target_ip = sprintf("%s", $target =~ /^([0-9\.]*?):.*$/); + my $result = 0; + + if($server_ip eq $target_ip) { + $result= 1; + } elsif ($server_ip eq "0.0.0.0") { + if ($target_ip eq "127.0.0.1") { + $result= 1; + } else { + my $PROC_NET_ROUTE= ('/proc/net/route'); + + open(PROC_NET_ROUTE, "<$PROC_NET_ROUTE") + or die "Could not open $PROC_NET_ROUTE"; + + my @ifs = ; + + close(PROC_NET_ROUTE); + + # Eat header line + shift @ifs; + chomp @ifs; + 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); + $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($target_ip)->within(new NetAddr::IP($destination, $mask))) { + # destination matches route, save mac and exit + $result= 1; + last; + } + } + } + } else { + &main::daemon_log("Target ip $target_ip does not match Server ip $server_ip",1); + } + + return $result; +} + #=== FUNCTION ================================================================ # NAME: execute_actions