X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=trunk%2Fgosa-si%2Fgosa-si-server;h=c79bfdd1c9297b919b8121f3477987557619fb61;hb=a1a3d31a784b87c089b95bfea006f369d928a2b5;hp=0b00e52bcbfedbf579ae4dbdc19c6da77edc9ed1;hpb=0d3e288342a15d4876de0d0d5d5b031b5039961a;p=gosa.git diff --git a/trunk/gosa-si/gosa-si-server b/trunk/gosa-si/gosa-si-server index 0b00e52bc..c79bfdd1c 100755 --- a/trunk/gosa-si/gosa-si-server +++ b/trunk/gosa-si/gosa-si-server @@ -28,7 +28,7 @@ use Getopt::Long; use Config::IniFiles; use POSIX; -use Fcntl; +use Fcntl qw/:flock/; use IO::Socket::INET; use IO::Handle; use IO::Select; @@ -212,6 +212,8 @@ our $client_fai_log_dir = "/var/log/fai"; my @msgs_to_decrypt = qw(); my $max_children = 2; +# Allow 50 POE Childs +sub MAX_CONCURRENT_TASKS () { 50 } # loop delay for job queue to look for opsi jobs my $job_queue_opsi_delay = 10; @@ -324,11 +326,17 @@ sub daemon_log { if(not defined $msg) { return } if(not defined $level) { $level = 1 } if(defined $log_file){ - open(LOG_HANDLE, ">>$log_file"); - if(not defined open( LOG_HANDLE, ">>$log_file" )) { + my $open_log_fh = sysopen(LOG_HANDLE, $log_file, O_WRONLY | O_CREAT | O_APPEND , 0440); + if(not $open_log_fh) { print STDERR "cannot open $log_file: $!"; - return + return; + } + # check owner and group of log_file and update settings if necessary + my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($log_file); + if((not $uid eq $root_uid) || (not $gid eq $adm_gid)) { + chown($root_uid, $adm_gid, $log_file); } + chomp($msg); #$msg =~s/\n//g; # no newlines are allowed in log messages, this is important for later log parsing if($level <= $verbose){ @@ -344,7 +352,10 @@ sub daemon_log { my $name = $prg; my $log_msg = "$month $monthday $hours:$minutes:$seconds $name $msg\n"; + flock(LOG_HANDLE, LOCK_EX); + seek(LOG_HANDLE, 0, 2); print LOG_HANDLE $log_msg; + flock(LOG_HANDLE, LOCK_UN); if( $foreground ) { print STDERR $log_msg; } @@ -499,27 +510,42 @@ sub password_check { } +sub clean_shutdown +{ + unlink($pid_file) if (-w $pid_file); + unlink($packages_list_under_construction) if (-w $packages_list_under_construction); +} -#=== FUNCTION ================================================================ -# NAME: sig_int_handler -# PARAMETERS: signal - string - signal arose from system -# RETURNS: nothing -# DESCRIPTION: handels tasks to be done befor signal becomes active -#=============================================================================== -sub sig_int_handler { +sub sig_int_or_term_handler +{ my ($signal) = @_; + daemon_log("Got SIG${signal} - shutting down gosa-si-server", 1); + clean_shutdown(); + POE::Kernel->signal('gosa-si_server_session', 'KILL'); + POE::Kernel->signal('TCP_SERVER', 'KILL'); + return 1; +} -# if (defined($ldap_handle)) { -# $ldap_handle->disconnect; -# } - # TODO alle verbliebenden ldap verbindungen aus allen heaps beenden - +sub sig_warn_handler +{ + my @loc = caller(0); + daemon_log( "SIGWARN line " . $loc[2] . ": " . $_[0], 1 ); + return 1; +} - daemon_log("shutting down gosa-si-server", 1); - system("kill `ps -C gosa-si-server -o pid=`"); +sub sig_die_handler +{ + my @loc = caller(0); + daemon_log( "SIGDIE line " . $loc[2] . ": " . $_[0], 1 ); + clean_shutdown(); + return 1; } -$SIG{INT} = \&sig_int_handler; +$SIG{'INT'} = \&sig_int_or_term_handler; +$SIG{'TERM'} = \&sig_int_or_term_handler; +$SIG{'__WARN__'} = \&sig_warn_handler; +$SIG{'__DIE__'} = \&sig_die_handler; +$SIG{'USR1'} = 'IGNORE'; sub check_key_and_xml_validity { my ($crypted_msg, $module_key, $session_id) = @_; @@ -599,7 +625,7 @@ sub check_outgoing_xml_validity { } # Check if source contains hostname instead of ip address - if(not $source =~ /^[a-z0-9\.]+:\d+$/i) { + if($source =~ /^[a-z][a-z0-9\.]+:\d+$/i) { my ($hostname,$port) = split(/:/, $source); my $ip_address = inet_ntoa(scalar gethostbyname($hostname)); if(defined($ip_address) && $ip_address =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ && $port =~ /^\d+$/) { @@ -942,6 +968,10 @@ sub send_msg_to_target { $sql_statement = "DELETE FROM known_server WHERE hostname='$address'"; $res = $known_server_db->del_dbentry($sql_statement); daemon_log("$session_id WARNING: failed 2x to send a message to host '$address', delete host from known_server", 3); + + # Remove the registered clients of the server as well + $sql_statement = "DELETE FROM foreign_clients WHERE regserver='$address'"; + $res = $foreign_clients_db->del_dbentry($sql_statement); } else { $sql_statement = "UPDATE known_server SET status='$new_status', timestamp='$timestamp' WHERE hostname='$address'"; @@ -1041,14 +1071,6 @@ sub reactivate_job_with_delay { } -sub sig_handler { - my ($kernel, $signal) = @_[KERNEL, ARG0] ; - daemon_log("0 INFO got signal '$signal'", 1); - $kernel->sig_handled(); - return; -} - - sub msg_to_decrypt { my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; my $session_id = $session->ID; @@ -1376,8 +1398,8 @@ sub process_task { # set timestamp of incoming client uptodate, so client will not # be deleted from known_clients because of expiration - my $act_time = &get_time(); - my $sql = "UPDATE $known_clients_tn SET timestamp='$act_time' WHERE hostname='$source'"; + my $cur_time = &get_time(); + my $sql = "UPDATE $known_clients_tn SET timestamp='$cur_time' WHERE hostname='$source'"; my $res = $known_clients_db->exec_statement($sql); ###################### @@ -1549,12 +1571,12 @@ sub process_task { sub session_start { my ($kernel) = $_[KERNEL]; + $kernel->alias_set('gosa-si_server_session'); $global_kernel = $kernel; $kernel->yield('register_at_foreign_servers'); $kernel->yield('create_fai_server_db', $fai_server_tn ); $kernel->yield('create_fai_release_db', $fai_release_tn ); $kernel->yield('watch_for_next_tasks'); - $kernel->sig(USR1 => "sig_handler"); $kernel->sig(USR2 => "recreate_packages_db"); $kernel->delay_set('watch_for_new_jobs', $job_queue_loop_delay); $kernel->delay_set('watch_for_done_jobs', $job_queue_loop_delay); @@ -1568,9 +1590,14 @@ sub session_start { if ($opsi_enabled eq "true") { $kernel->delay_set('watch_for_opsi_jobs', $job_queue_opsi_delay); } - } +sub session_stop { + my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; + $kernel->alias_remove($heap->{alias}); + $kernel->alarm_remove_all(); + $kernel->post($heap->{child_session}, '_stop'); +} sub watch_for_done_jobs { #CHECK: $heap for what? @@ -1780,8 +1807,7 @@ sub watch_for_new_jobs { my $res_2 = $job_db->exec_statement( $sql_statement_2 ); if(defined($res_2) and defined @{$res_2}[0]) { # Set status from goto-activation to 'waiting' and update timestamp - $job_db->exec_statement("UPDATE $job_queue_tn SET status='waiting' WHERE macaddress LIKE '$macaddress' AND headertag = 'trigger_action_reinstall'"); - $job_db->exec_statement("UPDATE $job_queue_tn SET timestamp='".&calc_timestamp(&get_time(), 'plus', 30)."' WHERE macaddress LIKE '$macaddress' AND headertag = 'trigger_action_reinstall'"); + $job_db->exec_statement("UPDATE $job_queue_tn SET status='waiting', timestamp='".&calc_timestamp(&get_time(), 'plus', 30)."' WHERE macaddress LIKE '$macaddress' AND headertag = 'trigger_action_reinstall'"); } } next; @@ -1928,7 +1954,8 @@ sub watch_for_delivery_messages { my ($kernel, $heap) = @_[KERNEL, HEAP]; # select outgoing messages - my $sql_statement = "SELECT * FROM $messaging_tn WHERE ( flag='p' AND direction='out' )"; + my $timestamp= &get_time(); + my $sql_statement = "SELECT * FROM $messaging_tn WHERE ( flag='p' AND direction='out' AND delivery_time<$timestamp)"; #&daemon_log("0 DEBUG: $sql", 7); my $res = $messaging_db->exec_statement( $sql_statement ); @@ -2061,7 +2088,7 @@ sub watch_for_old_known_clients { my $sql_statement = "SELECT * FROM $known_clients_tn"; my $res = $known_clients_db->select_dbentry( $sql_statement ); - my $act_time = int(&get_time()); + my $cur_time = int(&get_time()); while ( my ($hit_num, $hit) = each %$res) { my $expired_timestamp = int($hit->{'timestamp'}); @@ -2076,7 +2103,7 @@ sub watch_for_old_known_clients { $dt->add( seconds => 2 * int($hit->{'keylifetime'}) ); $expired_timestamp = $dt->ymd('').$dt->hms(''); - if ($act_time > $expired_timestamp) { + if ($cur_time > $expired_timestamp) { my $hostname = $hit->{'hostname'}; my $del_sql = "DELETE FROM $known_clients_tn WHERE hostname='$hostname'"; my $del_res = $known_clients_db->exec_statement($del_sql); @@ -3193,6 +3220,10 @@ GetOptions("h|help" => \&usage, "no-arp+" => \$no_arp, ); +# Prepare UID / GID as daemon_log may need it quite early +$root_uid = getpwnam('root'); +$adm_gid = getgrnam('adm'); + # read and set config parameters &check_cmdline_param ; &read_configfile($cfg_file, %cfg_defaults); @@ -3239,10 +3270,10 @@ if ($server_headURL =~ /\/tag\// || $server_status = "developmental" ; } -# Prepare log file -$root_uid = getpwnam('root'); -$adm_gid = getgrnam('adm'); -chmod(0640, $log_file); +# Prepare log file and set permissons +open(FH, ">>$log_file"); +close FH; +chmod(0440, $log_file); chown($root_uid, $adm_gid, $log_file); chown($root_uid, $adm_gid, "/var/lib/gosa-si"); @@ -3293,60 +3324,61 @@ daemon_log($server_status_hash->{$server_status}.": $server_revision", 1); # connect to gosa-si job queue unlink($job_queue_file_name); ## just for debugging $job_db = GOSA::DBsqlite->new($job_queue_file_name); - chmod(0660, $job_queue_file_name); + chmod(0640, $job_queue_file_name); chown($root_uid, $adm_gid, $job_queue_file_name); # connect to known_clients_db unlink($known_clients_file_name); ## just for debugging $known_clients_db = GOSA::DBsqlite->new($known_clients_file_name); - chmod(0660, $known_clients_file_name); + chmod(0640, $known_clients_file_name); chown($root_uid, $adm_gid, $known_clients_file_name); # connect to foreign_clients_db unlink($foreign_clients_file_name); $foreign_clients_db = GOSA::DBsqlite->new($foreign_clients_file_name); - chmod(0660, $foreign_clients_file_name); + chmod(0640, $foreign_clients_file_name); chown($root_uid, $adm_gid, $foreign_clients_file_name); # connect to known_server_db unlink($known_server_file_name); $known_server_db = GOSA::DBsqlite->new($known_server_file_name); - chmod(0660, $known_server_file_name); + chmod(0640, $known_server_file_name); chown($root_uid, $adm_gid, $known_server_file_name); # connect to login_usr_db unlink($login_users_file_name); $login_users_db = GOSA::DBsqlite->new($login_users_file_name); - chmod(0660, $login_users_file_name); + chmod(0640, $login_users_file_name); chown($root_uid, $adm_gid, $login_users_file_name); # connect to fai_server_db unlink($fai_server_file_name); $fai_server_db = GOSA::DBsqlite->new($fai_server_file_name); - chmod(0660, $fai_server_file_name); + chmod(0640, $fai_server_file_name); chown($root_uid, $adm_gid, $fai_server_file_name); # connect to fai_release_db unlink($fai_release_file_name); $fai_release_db = GOSA::DBsqlite->new($fai_release_file_name); - chmod(0660, $fai_release_file_name); + chmod(0640, $fai_release_file_name); chown($root_uid, $adm_gid, $fai_release_file_name); # connect to packages_list_db #unlink($packages_list_file_name); unlink($packages_list_under_construction); $packages_list_db = GOSA::DBsqlite->new($packages_list_file_name); - chmod(0660, $packages_list_file_name); + chmod(0640, $packages_list_file_name); chown($root_uid, $adm_gid, $packages_list_file_name); # connect to messaging_db unlink($messaging_file_name); $messaging_db = GOSA::DBsqlite->new($messaging_file_name); - chmod(0660, $messaging_file_name); + chmod(0640, $messaging_file_name); chown($root_uid, $adm_gid, $messaging_file_name); } } + # Creating tables $messaging_db->create_table($messaging_tn, \@messaging_col_names); $packages_list_db->create_table($packages_list_tn, \@packages_list_col_names); @@ -3359,7 +3391,6 @@ $known_clients_db->create_table($known_clients_tn, \@known_clients_col_names); $incoming_db->create_table($incoming_tn, \@incoming_col_names); $job_db->create_table($job_queue_tn, \@job_queue_col_names); - # create xml object used for en/decrypting $xml = new XML::Simple(); @@ -3418,7 +3449,7 @@ my $all_foreign_server = join(", ", @foreign_server_list); daemon_log("0 INFO: found foreign server in config file and DNS: '$all_foreign_server'", 5); # add all found foreign servers to known_server -my $act_timestamp = &get_time(); +my $cur_timestamp = &get_time(); foreach my $foreign_server (@foreign_server_list) { # do not add myself to known_server_db @@ -3429,10 +3460,10 @@ foreach my $foreign_server (@foreign_server_list) { primkey=>['hostname'], hostname=>$foreign_server, macaddress=>"", - status=>'not_jet_registered', + status=>'not_yet_registered', hostkey=>"none", loaded_modules => "none", - timestamp=>$act_timestamp, + timestamp=>$cur_timestamp, } ); } @@ -3479,8 +3510,8 @@ daemon_log("0 INFO: start socket for incoming xml messages at port '$server_port POE::Session->create( inline_states => { _start => \&session_start, + _stop => \&session_stop, register_at_foreign_servers => \®ister_at_foreign_servers, - sig_handler => \&sig_handler, next_task => \&next_task, task_result => \&handle_task_result, task_done => \&handle_task_done,