X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-client;h=145a82cf848a5381831ae720b8c0be313173ddb0;hb=80cffb3242742d45a7c9b79ecb6acda570c8f86f;hp=4b599084af82da45c3d9e83730d1f41fa9ebf2cd;hpb=5878926b13403289edf8386d10973b4e749c64c8;p=gosa.git diff --git a/gosa-si/gosa-si-client b/gosa-si/gosa-si-client index 4b599084a..145a82cf8 100755 --- a/gosa-si/gosa-si-client +++ b/gosa-si/gosa-si-client @@ -34,22 +34,25 @@ use GOSA::GosaSupportDaemon; use Digest::MD5 qw(md5_hex md5 md5_base64); use MIME::Base64; use XML::Simple; -use Net::DNS; use File::Basename; use File::Spec; # Workaround: need pure perl to make it work with UTF-8 :-( $XML::Simple::PREFERRED_PARSER= "XML::SAX::PurePerl"; +my $client_version = '$HeadURL$:$Rev$'; +my $client_headURL; +my $client_revision; +my $client_status; my $event_dir = "/usr/lib/gosa-si/client/events"; use lib "/usr/lib/gosa-si/client/events"; my (%cfg_defaults, $foreground, $verbose, $pid_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 ($server_ip, $server_port, $server_timeout, $server_domain, $server_key_lifetime); +my ($client_port, $ldap_enabled, $ldap_config, $pam_config, $nss_config); my $xml; -my $default_server_key; my $event_hash; +my $default_server_key; my @servers; my $gotoHardwareChecksum; my $gosa_si_client_fifo; @@ -57,6 +60,7 @@ my %files_to_watch; $verbose= 1; # globalise variables which are used in imported events +our $global_kernel; our $cfg_file; our $opts_file; our $server_address; @@ -235,69 +239,40 @@ $SIG{INT} = \&sig_int_handler; # DESCRIPTION: #=============================================================================== sub daemon_log { - # log into log_file +# log into log_file my( $msg, $level ) = @_; if(not defined $msg) { return } if(not defined $level) { $level = 1 } if(defined $log_file){ open(LOG_HANDLE, ">>$log_file"); + chmod 0600, $log_file; if(not defined open( LOG_HANDLE, ">>$log_file" )) { print STDERR "cannot open $log_file: $!"; - return } - chomp($msg); - if($level <= $verbose){ - my ($seconds, $minutes, $hours, $monthday, $month, - $year, $weekday, $yearday, $sommertime) = localtime(time); - $hours = $hours < 10 ? $hours = "0".$hours : $hours; - $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes; - $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds; - my @monthnames = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); - $month = $monthnames[$month]; - $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; - $year+=1900; - - my $log_msg = "$month $monthday $hours:$minutes:$seconds $prg $msg\n"; - print LOG_HANDLE $log_msg; - if( $foreground ) { - print STDERR $log_msg; - } + return + } + chomp($msg); + if($level <= $verbose){ + my ($seconds, $minutes, $hours, $monthday, $month, + $year, $weekday, $yearday, $sommertime) = localtime(time); + $hours = $hours < 10 ? $hours = "0".$hours : $hours; + $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes; + $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds; + my @monthnames = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); + $month = $monthnames[$month]; + $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; + $year+=1900; + + my $log_msg = "$month $monthday $hours:$minutes:$seconds $prg $msg\n"; + print LOG_HANDLE $log_msg; + if( $foreground ) { + print STDERR $log_msg; } + } close( LOG_HANDLE ); } } -#=== FUNCTION ================================================================ -# NAME: get_interfaces -# PARAMETERS: none -# RETURNS: (list of interfaces) -# DESCRIPTION: Uses proc fs (/proc/net/dev) to get list of interfaces. -#=============================================================================== -sub get_interfaces { - my @result; - my $PROC_NET_DEV= ('/proc/net/dev'); - - open(PROC_NET_DEV, "<$PROC_NET_DEV") - or die "Could not open $PROC_NET_DEV"; - - my @ifs = ; - - close(PROC_NET_DEV); - - # Eat first two line - shift @ifs; - shift @ifs; - - chomp @ifs; - foreach my $line(@ifs) { - my $if= (split /:/, $line)[0]; - $if =~ s/^\s+//; - push @result, $if; - } - - return @result; -} - #=== FUNCTION ================================================================ # NAME: get_mac # PARAMETERS: interface name (i.e. eth0) @@ -345,61 +320,6 @@ sub get_mac { } -#=== FUNCTION ================================================================ -# NAME: get_interface_for_ip -# PARAMETERS: ip address (i.e. 192.168.0.1) -# RETURNS: array: list of interfaces if ip=0.0.0.0, matching interface if found, undef else -# DESCRIPTION: Uses proc fs (/proc/net/dev) to get list of interfaces. -#=============================================================================== -sub get_interface_for_ip { - my $result; - my $ip= shift; - if ($ip && length($ip) > 0) { - my @ifs= &get_interfaces(); - if($ip eq "0.0.0.0") { - $result = "all"; - } else { - foreach (@ifs) { - my $if=$_; - if(get_ip($if) eq $ip) { - $result = $if; - last; - } - } - } - } - 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: get_local_mac_for_remote_ip @@ -496,14 +416,15 @@ sub generate_hw_digest { } -sub create_passwd { - my $new_passwd = ""; - for(my $i=0; $i<31; $i++) { - $new_passwd .= ("a".."z","A".."Z",0..9)[int(rand(62))] - } - - return $new_passwd; -} +# moved to GosaSupportDaemon: rettenbe, 19.05.2008 +#sub create_passwd { +# my $new_passwd = ""; +# for(my $i=0; $i<31; $i++) { +# $new_passwd .= ("a".."z","A".."Z",0..9)[int(rand(62))] +# } +# +# return $new_passwd; +#} sub create_ciphering { @@ -547,42 +468,43 @@ sub decrypt_msg { } -sub get_server_addresses { - my $domain= shift; - my @result; - - my $error = 0; - my $res = Net::DNS::Resolver->new; - my $query = $res->send("_gosa-si._tcp.".$domain, "SRV"); - my @hits; - - if ($query) { - foreach my $rr ($query->answer) { - push(@hits, $rr->target.":".$rr->port); - } - } - else { - #warn "query failed: ", $res->errorstring, "\n"; - $error++; - } - - if( $error == 0 ) { - foreach my $hit (@hits) { - my ($hit_name, $hit_port) = split(/:/, $hit); - chomp($hit_name); - chomp($hit_port); - - my $address_query = $res->send($hit_name); - if( 1 == length($address_query->answer) ) { - foreach my $rr ($address_query->answer) { - push(@result, $rr->address.":".$hit_port); - } - } - } - } - - return @result; -} +# moved to GosaSupportDaemon: rettenbe: 16.05.2008 +#sub get_server_addresses { +# my $domain= shift; +# my @result; +# +# my $error = 0; +# my $res = Net::DNS::Resolver->new; +# my $query = $res->send("_gosa-si._tcp.".$domain, "SRV"); +# my @hits; +# +# if ($query) { +# foreach my $rr ($query->answer) { +# push(@hits, $rr->target.":".$rr->port); +# } +# } +# else { +# #warn "query failed: ", $res->errorstring, "\n"; +# $error++; +# } +# +# if( $error == 0 ) { +# foreach my $hit (@hits) { +# my ($hit_name, $hit_port) = split(/:/, $hit); +# chomp($hit_name); +# chomp($hit_port); +# +# my $address_query = $res->send($hit_name); +# if( 1 == length($address_query->answer) ) { +# foreach my $rr ($address_query->answer) { +# push(@result, $rr->address.":".$hit_port); +# } +# } +# } +# } +# +# return @result; +#} #=== FUNCTION ================================================================ @@ -613,14 +535,16 @@ sub send_msg_to_target { # encrypt xml msg my $crypted_msg = &encrypt_msg($msg, $encrypt_key); - # xxxxxxxxxxxxxx - - - # opensocket my $socket = &open_socket($address); if( !$socket ) { daemon_log("ERROR: cannot send ".$msg_header."msg to $address , host not reachable", 1); + if ($REGISTERED == 1) { + $REGISTERED = 0; # if server is not available, cause reregistering + daemon_log("INFO: cause reregistering at gosa-si-server", 5); + $global_kernel->yield('register_at_gosa_si_server'); + + } $error++; } @@ -628,7 +552,7 @@ sub send_msg_to_target { if( $error == 0 ) { print $socket $crypted_msg."\n"; daemon_log("INFO: send ".$msg_header."msg to $address", 5); - daemon_log("DEBUG: message:\n$msg", 8); + daemon_log("DEBUG: message:\n$msg", 9); } # close socket in any case @@ -681,7 +605,7 @@ sub open_socket { if(not defined $socket) { return; } - &daemon_log("open_socket: $PeerAddr", 7); + &daemon_log("DEBUG: open_socket: $PeerAddr", 7); return $socket; } @@ -710,12 +634,25 @@ sub register_at_gosa_si_server { my $events = join( ",", keys %{$event_hash} ); while(1) { - # fetch first gosa-si-server from @servers - my $server = shift(@servers); - - # append shifted gosa-si-server at the end of @servers, so looking for servers never stop if - # a registration never occured - push( @servers, $server ); + $try_to_register++; + + # after one complete round through all server, stop trying to register + if( $try_to_register > @servers ) { last; } + + # fetch first gosa-si-server from @servers + # append shifted gosa-si-server at the end of @servers, so looking for servers never stop if + # a registration never occured + my $server = shift(@servers); + push( @servers, $server ); + + # Check if our ip is resolvable - if not: don't try to register + if(!(defined($server) && $server =~ m/^[0-9\.]*?:.*$/)) { + &main::daemon_log("ERROR: Server with address '".defined($server)?$server:""."' is invalid!", 1); + if (length(@servers) == 1) { + &main::daemon_log("ERROR: No valid servers found!", 1); + exit(1); + } + } # 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\.]*?):.*$/)); @@ -732,7 +669,10 @@ sub register_at_gosa_si_server { &add_content2xml_hash($register_hash, "new_passwd", $server_key); &add_content2xml_hash($register_hash, "mac_address", $local_mac); &add_content2xml_hash($register_hash, "events", $events); + &add_content2xml_hash($register_hash, "client_status", $client_status); + &add_content2xml_hash($register_hash, "client_revision", $client_revision); &add_content2xml_hash($register_hash, "gotoHardwareChecksum", $gotoHardwareChecksum); + &add_content2xml_hash($register_hash, "key_lifetime", $server_key_lifetime); # Add $HOSTNAME from ENV if force-hostname is set if( defined($client_force_hostname) && $client_force_hostname eq "true") { @@ -745,11 +685,9 @@ 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( $try_to_register >= @servers ) { last; } # if delivery of registration msg succeed - if($res == 0) { + if($res eq "0") { # reset try_to_register $try_to_register = 0; @@ -762,14 +700,12 @@ sub register_at_gosa_si_server { # delivery of registration msg failed } else { - $try_to_register++; # wait 1 sec until trying to register again sleep(1); next; } } # end of while - # one circle through all servers finished and no registration succeed if ( $try_to_register >= @servers ) { &write_to_file("gosa-si-no-server-available", $fai_logpath); @@ -796,7 +732,7 @@ sub check_key_and_xml_validity { my $msg_hash; eval{ $msg = &decrypt_msg($crypted_msg, $module_key); - &main::daemon_log("decrypted_msg: \n$msg", 8); + &main::daemon_log("decrypted_msg: \n$msg", 9); $msg_hash = $xml->XMLin($msg, ForceArray=>1); @@ -907,37 +843,37 @@ sub check_outgoing_xml_validity { } -sub import_events { - - if (not -e $event_dir) { - daemon_log("ERROR: cannot find directory or directory is not readable: $event_dir", 1); - } - opendir (DIR, $event_dir) or die "ERROR while loading gosa-si-events from directory $event_dir : $!\n"; - - while (defined (my $event = readdir (DIR))) { - if( $event eq "." || $event eq ".." ) { next; } - daemon_log("INFO: found event module: $event", 5); - eval{ require $event; }; - if( $@ ) { - daemon_log("ERROR: import of event module '$event' failed", 1); - daemon_log("$@", 1); - next; - } - - $event =~ /(\S*?).pm$/; - my $event_module = $1; - my $events_l = eval( $1."::get_events()") ; - foreach my $event_name (@{$events_l}) { - $event_hash->{$event_name} = $event_module; - } - - } - - my @all_events = keys %$event_hash; - my $all_events_string = join(", ", @all_events); - - daemon_log("INFO: imported events: $all_events_string", 5); -} +#sub import_events { +# +# if (not -e $event_dir) { +# daemon_log("ERROR: cannot find directory or directory is not readable: $event_dir", 1); +# } +# opendir (DIR, $event_dir) or die "ERROR while loading gosa-si-events from directory $event_dir : $!\n"; +# +# while (defined (my $event = readdir (DIR))) { +# if( $event eq "." || $event eq ".." ) { next; } +# daemon_log("INFO: found event module: $event", 5); +# eval{ require $event; }; +# if( $@ ) { +# daemon_log("ERROR: import of event module '$event' failed", 1); +# daemon_log("$@", 1); +# next; +# } +# +# $event =~ /(\S*?).pm$/; +# my $event_module = $1; +# my $events_l = eval( $1."::get_events()") ; +# foreach my $event_name (@{$events_l}) { +# $event_hash->{$event_name} = $event_module; +# } +# +# } +# +# my @all_events = keys %$event_hash; +# my $all_events_string = join(", ", @all_events); +# +# daemon_log("INFO: imported events: $all_events_string", 5); +#} sub trigger_new_key { my ($kernel) = $_[KERNEL] ; @@ -970,14 +906,6 @@ sub trigger_logged_in_users_report { } -#sub generic_file_reset { -# my ( $heap, $wheel_id ) = @_[ HEAP, ARG0 ]; -# -# my $service = $heap->{services}->{$wheel_id}; -# daemon_log("INFO: '$service' watching reset", 5); -# return; -#} - sub generic_file_error { my ( $heap, $operation, $errno, $error_string, $wheel_id ) = @_[ HEAP, ARG0, ARG1, ARG2, ARG3 ]; @@ -1065,6 +993,7 @@ sub save_fai_log { sub _start { my ($kernel, $heap) = @_[KERNEL, HEAP]; $kernel->alias_set('client_session'); + $global_kernel = $kernel; # this is used to throw events at each point of the skript # force a registration at a gosa-si-server $kernel->yield('register_at_gosa_si_server'); @@ -1102,7 +1031,7 @@ sub server_input { daemon_log("INFO: Incoming msg from '$remote_ip'", 5); - daemon_log("DEBUG: Incoming msg:\n$input\n", 8); + daemon_log("DEBUG: Incoming msg:\n$input\n", 9); my ($msg, $msg_hash) = &check_key_and_xml_validity($input, $server_key); if( (!$msg) || (!$msg_hash) ) { @@ -1134,12 +1063,12 @@ sub server_input { if( exists $event_hash->{$header} ) { # a event exists with the header as name - daemon_log("DEBUG: found event '$header' at event-module '".$event_hash->{$header}."'", 7); + daemon_log("INFO: found event '$header' at event-module '".$event_hash->{$header}."'", 5); no strict 'refs'; $answer = &{$event_hash->{$header}."::$header"}($msg, $msg_hash); } else { - daemon_log("WARNING: no event '$header' found in event modules under $event_dir", 1); + daemon_log("WARNING: no event '$header' found in event modules under $event_dir", 3); } } @@ -1206,8 +1135,7 @@ if( ! $foreground ) { $pid = fork; setsid or die "Can't start a new session: $!"; umask 0; -} -else { +} else { $pid = $$; } @@ -1221,8 +1149,22 @@ if( 0 != $pid ) { }; } +# parse head url and revision from svn +my $client_status_hash = { 'developmental'=>'revision', 'stable'=>'release'}; +$client_version =~ /^\$HeadURL: (\S+) \$:\$Rev: (\d+) \$$/; +$client_headURL = defined $1 ? $1 : 'unknown' ; +$client_revision = defined $2 ? $2 : 'unknown' ; +if ($client_headURL =~ /\/tag\// || + $client_headURL =~ /\/branches\// ) { + $client_status = "stable"; +} else { + $client_status = "developmental" ; +} + daemon_log(" ", 1); daemon_log("$prg started!", 1); +daemon_log("INFO: status: $client_status", 1); +daemon_log("INFO: ".$client_status_hash->{$client_status}.": $client_revision", 1); # delete old DBsqlite lock files system('rm -f /tmp/gosa_si_lock*gosa-si-client*'); @@ -1231,17 +1173,27 @@ system('rm -f /tmp/gosa_si_lock*gosa-si-client*'); $client_address = $client_ip.":".$client_port; my $network_interface= &get_interface_for_ip($client_ip); $client_mac_address= &get_mac($network_interface); -daemon_log("gosa-si-client ip address detected: $client_ip", 1); -daemon_log("gosa-si-client mac address detected: $client_mac_address", 1); +daemon_log("INFO: ip address detected: $client_ip", 1); +daemon_log("INFO: gosa-si-client mac address detected: $client_mac_address", 1); # import events -&import_events(); +my ($error, $result, $tmp_hash) = &import_events($event_dir); +$event_hash = $tmp_hash; +if ($error == 0) { + foreach my $log_line (@$result) { + daemon_log("DEBUG: $log_line", 7); + } +} else { + foreach my $log_line (@$result) { + daemon_log("ERROR: $log_line", 1); + } +} # compute hardware checksum $gotoHardwareChecksum= &generate_hw_digest(); -daemon_log("gosa-si-client gotoHardwareChecksum detected: $gotoHardwareChecksum", 1); +daemon_log("INFO: gotoHardwareChecksum detected: $gotoHardwareChecksum", 1); # create socket for incoming xml messages @@ -1250,14 +1202,14 @@ POE::Component::Server::TCP->new( Port => $client_port, ClientInput => \&server_input, ); -daemon_log("start socket for incoming xml messages at port '$client_port' ", 1); +daemon_log("INFO: start socket for incoming xml messages at port '$client_port' ", 1); # prepare variables if( inet_aton($server_ip) ){ $server_ip = inet_ntoa(inet_aton($server_ip)); } ############################################################ # to change -if( $server_ip eq "127.0.1.1" ) { $server_ip = "127.0.0.1" } +#if( $server_ip eq "127.0.1.1" ) { $server_ip = "127.0.0.1" } ############################################################ if (defined $server_ip && defined $server_port) { $server_address = $server_ip.":".$server_port;