X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-client;h=9b0374de264db0b450c8f716dd700f741b50a421;hb=9d96c80900bc2d8f751662ae4272b419ec612fa0;hp=86bae5f7f0f28dfd127c59481307dc1116a0a6fc;hpb=25d3fe0bc719fde52be5dc8a99e96728616b7d5d;p=gosa.git diff --git a/gosa-si/gosa-si-client b/gosa-si/gosa-si-client index 86bae5f7f..9b0374de2 100755 --- a/gosa-si/gosa-si-client +++ b/gosa-si/gosa-si-client @@ -35,11 +35,12 @@ use Digest::MD5 qw(md5_hex md5 md5_base64); use MIME::Base64; use XML::Simple; use Net::DNS; +use File::Basename; my $event_dir = "/usr/lib/gosa-si/client/events"; use lib "/usr/lib/gosa-si/client/events"; -my ($cfg_file, %cfg_defaults, $foreground, $verbose, $pid_file, $procid, $pid, $log_file, $fai_logpath); +my ($cfg_file, %cfg_defaults, $foreground, $verbose, $pid_file, $opts_file, $procid, $pid, $log_file, $fai_logpath); my ($server_ip, $server_port, $server_key, $server_timeout, $server_domain, $server_key_lifetime); my ($client_ip, $client_port, $client_mac_address, $ldap_enabled, $ldap_config, $pam_config, $nss_config); my $xml; @@ -58,10 +59,16 @@ our $server_key; # default variables our $REGISTERED = 0; +# in function register_at_gosa_si_server, after which period of seconds a new registration should be tried if a registration was +# not successful until now +my $delay_set_time = 5; +our $prg= basename($0); + %cfg_defaults = ( "general" => - {"log-file" => [\$log_file, "/var/run/".$0.".log"], - "pid-file" => [\$pid_file, "/var/run/".$0.".pid"], + {"log-file" => [\$log_file, "/var/run/".$prg.".log"], + "pid-file" => [\$pid_file, "/var/run/".$prg.".pid"], + "opts-file" => [\$opts_file, "/var/run/".$prg.".opts"], }, "client" => {"port" => [\$client_port, "20083"], @@ -217,10 +224,8 @@ sub daemon_log { $month = $monthnames[$month]; $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; $year+=1900; - my $name = $0; - $name =~ s/\.\///; - my $log_msg = "$month $monthday $hours:$minutes:$seconds $name $msg\n"; + my $log_msg = "$month $monthday $hours:$minutes:$seconds $prg $msg\n"; print LOG_HANDLE $log_msg; if( $foreground ) { print STDERR $log_msg; @@ -799,6 +804,32 @@ sub send_msg_to_target { } +sub write_to_file { + my ($string, $file) = @_; + my $error = 0; + + if( not defined $file || not -f $file ) { + &main::daemon_log("ERROR: $prg: check '-f file' failed: $file", 1); + $error++; + } + if( not defined $string || 0 == length($string)) { + &main::daemon_log("ERROR: $prg: empty string to write to file '$file'", 1); + $error++; + } + + if( $error == 0 ) { + + chomp($string); + + open(FILE, ">> $file"); + print FILE $string."\n"; + close(FILE); + } + + return; +} + + sub open_socket { my ($PeerAddr, $PeerPort) = @_ ; if(defined($PeerPort)){ @@ -826,31 +857,36 @@ sub open_socket { #=============================================================================== sub register_at_gosa_si_server { my ($kernel) = $_[KERNEL]; + my $try_to_register = 0; if( not $REGISTERED ) { - # create new passwd and ciphering object for client-server communication $server_key = &create_passwd(); my $events = join( ", ", keys %{$event_hash} ); - while(1) { + if( $try_to_register >= @servers ) { + last; + } + # fetch first gosa-si-server from @servers my $server = shift(@servers); - if( !$server ) { - daemon_log("no gosa-si-server left in list of servers", 1); - daemon_log("unable to register at a gosa-si-server, force shutdown", 1); - exit(1); - } + + # append shifted gosa-si-server at the end of @servers, so looking for servers never stop if + # a registration never occured + push( @servers, $server ); # Check if our ip is resolvable - if not: don't try to register my $ip= &get_local_ip_for_remote_ip(sprintf("%s", $server =~ /^([0-9\.]*?):.*$/)); my $resolver= Net::DNS::Resolver->new; my $dnsresult= $resolver->search($ip); + my $dnsname=""; if(!defined($dnsresult)) { - &write_to_file("goto-dns-error:Could not resolve hostname for ip $ip", $fai_logpath); + &write_to_file("goto-error-dns:$ip", $fai_logpath); exit(1); + } else { + $dnsname=$dnsresult->{answer}[0]->{ptrdname}; } # create registration msg @@ -865,19 +901,45 @@ sub register_at_gosa_si_server { # send xml hash to server with general server passwd my $res = &send_msg_hash_to_target($register_hash, $server, $default_server_key); if($res == 0) { + # reset try_to_register + $try_to_register = 0; + # Set fixed client address $client_ip= &get_local_ip_for_remote_ip(sprintf("%s", $server =~ /^([0-9\.]*?):.*$/)); $client_address= "$client_ip:$client_port"; + + # Write the MAC address to file + if(stat($opts_file)) { + unlink($opts_file); + } + my $opts_file_FH; + my $hostname= $dnsname; + $hostname =~ s/\..*$//; + open($opts_file_FH, ">$opts_file"); + print $opts_file_FH "MAC=\"$local_mac\"\n"; + print $opts_file_FH "IPADDRESS=\"$client_ip\"\n"; + print $opts_file_FH "HOSTNAME=\"$hostname\"\n"; + print $opts_file_FH "FQDN=\"$dnsname\"\n"; + close($opts_file_FH); last; } else { + $try_to_register++; + # wait 1 sec until trying to register again + sleep(1); next; } } - daemon_log("waiting for msg 'register_at_gosa_si_server'",1); -# $kernel->delay_set('register_at_gosa_si_server', 180); - $kernel->delay_set('register_at_gosa_si_server', 5); - # clear old settings and set it again - $kernel->delay_set('trigger_new_key', $server_key_lifetime); + + if( $try_to_register >= @servers ) { + &write_to_file("gosa-si-no-server-available", $fai_logpath); + $kernel->delay_set('register_at_gosa_si_server', $delay_set_time); + } + else { + daemon_log("waiting for msg 'register_at_gosa_si_server'",1); + $kernel->delay_set('register_at_gosa_si_server', $delay_set_time); + # clear old settings and set it again + $kernel->delay_set('trigger_new_key', $server_key_lifetime); + } } return; } @@ -896,6 +958,7 @@ sub check_key_and_xml_validity { $msg_hash = $xml->XMLin($msg, ForceArray=>1); + ############## # check header my $header_l = $msg_hash->{'header'}; if( 1 != @{$header_l} ) { @@ -906,36 +969,102 @@ sub check_key_and_xml_validity { die 'header has length 0'; } + ############## # check source my $source_l = $msg_hash->{'source'}; if( 1 != @{$source_l} ) { - die 'no or more sources specified'; + die 'no or more than 1 sources specified'; } my $source = @{$source_l}[0]; if( 0 == length $source) { die 'source has length 0'; } - - # check target + unless( $source =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$/ ) { + die "source '$source' is neither a complete ip-address with port nor 'GOSA'"; + } + + ############## + # check target my $target_l = $msg_hash->{'target'}; if( 1 != @{$target_l} ) { - die 'no or more targets specified '; + die 'no or more than 1 targets specified '; } my $target = @{$target_l}[0]; if( 0 == length $target) { die 'target has length 0 '; } - + unless( $target =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$/ ){ + die "source is neither a complete ip-address with port nor 'GOSA'"; + } }; if($@) { &main::daemon_log("WARNING: do not understand the message or msg is not gosa-si envelope conform:", 5); &main::daemon_log("$@", 8); + $msg = undef; + $msg_hash = undef; } return ($msg, $msg_hash); } +sub check_outgoing_xml_validity { + my ($msg) = @_; + + my $msg_hash; + eval{ + $msg_hash = $xml->XMLin($msg, ForceArray=>1); + + ############## + # check header + my $header_l = $msg_hash->{'header'}; + if( 1 != @{$header_l} ) { + die 'no or more than one headers specified'; + } + my $header = @{$header_l}[0]; + if( 0 == length $header) { + die 'header has length 0'; + } + + ############## + # check source + my $source_l = $msg_hash->{'source'}; + if( 1 != @{$source_l} ) { + die 'no or more than 1 sources specified'; + } + my $source = @{$source_l}[0]; + if( 0 == length $source) { + die 'source has length 0'; + } + unless( $source =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$/ || + $source =~ /^GOSA$/i ) { + die "source '$source' is neither a complete ip-address with port"; + } + + ############## + # check target + my $target_l = $msg_hash->{'target'}; + if( 1 != @{$target_l} ) { + die "no or more than one targets specified"; + } + foreach my $target (@$target_l) { + if( 0 == length $target) { + die "target has length 0"; + } + unless( $target =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$/ ) { + die "target '$target' is not a complete ip-address with port or a valid target name"; + } + } + }; + if($@) { + daemon_log("WARNING: outgoing msg is not gosa-si envelope conform", 5); + daemon_log("$@ $msg", 8); + $msg_hash = undef; + } + return ($msg_hash); +} + + sub import_events { if (not -e $event_dir) { @@ -1015,21 +1144,31 @@ sub server_input { ######## # answer if( $answer ) { - # preprocessing - if( $answer =~ "
registered
") { - # set registered flag to true to stop sending further registered msgs - $REGISTERED = 1; - } - else { - &send_msg_to_target($answer, $server_address, $server_key); - } - # postprocessing - if( $answer =~ "
new_key
") { - # set new key to global variable - $answer =~ /(\S*?)<\/new_key>/; - my $new_key = $1; - $server_key = $new_key; + + #check gosa-si envelope validity + my $answer_hash = &check_outgoing_xml_validity($answer); + + if( $answer_hash ) { + # answer is valid + + # preprocessing + if( $answer =~ "
registered
") { + # set registered flag to true to stop sending further registered msgs + $REGISTERED = 1; + } + else { + &send_msg_to_target($answer, $server_address, $server_key); + } + + # postprocessing + if( $answer =~ "
new_key
") { + # set new key to global variable + $answer =~ /(\S*?)<\/new_key>/; + my $new_key = $1; + $server_key = $new_key; + } } + } return; @@ -1079,7 +1218,7 @@ if( 0 != $pid ) { } daemon_log(" ", 1); -daemon_log("$0 started!", 1); +daemon_log("$prg started!", 1); # delete old DBsqlite lock files system('rm -f /tmp/gosa_si_lock*gosa-si-client*');