X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-server;h=f1e33172f6f830ac16bc535e8481f4d85a9030d2;hb=eb472cef73faf54bdbbd24e079afbc336aedc7d9;hp=d391e2de71a3bd1a3f384d333094e4095ff5265a;hpb=7af2542e41e7872d844a5c7d839b803ed12cefbf;p=gosa.git diff --git a/gosa-si/gosa-si-server b/gosa-si/gosa-si-server index d391e2de7..f1e33172f 100755 --- a/gosa-si/gosa-si-server +++ b/gosa-si/gosa-si-server @@ -1,9 +1,9 @@ #!/usr/bin/perl #=============================================================================== # -# FILE: gosa-sd +# FILE: gosa-si-server # -# USAGE: ./gosa-sd +# USAGE: ./gosa-si-server # # DESCRIPTION: # @@ -39,7 +39,7 @@ use Digest::MD5 qw(md5 md5_hex md5_base64); use XML::Simple; use Data::Dumper; use Sys::Syslog qw( :DEFAULT setlogsock); -use Time::HiRes qw( usleep); +use Time::HiRes qw( usleep clock_gettime ); use Cwd; use File::Spec; use File::Basename; @@ -51,6 +51,7 @@ use POE qw(Component::Server::TCP Wheel::Run Filter::Reference); use Net::LDAP; use Net::LDAP::Util qw(:escape); + # revision number of server and program name my $server_headURL; my $server_revision; @@ -63,7 +64,6 @@ my $db_module = "DBsqlite"; no strict "refs"; require ("GOSA/".$db_module.".pm"); ("GOSA/".$db_module)->import; -#daemon_log("0 INFO: importing database module '$db_module'", 1); } my $modules_path = "/usr/lib/gosa-si/modules"; @@ -90,11 +90,12 @@ our (%cfg_defaults, $log_file, $pid_file, $server_ip, $server_port, $ClientPackages_key, $dns_lookup, $arp_activ, $gosa_unit_tag, $GosaPackages_key, $gosa_timeout, - $foreign_server_string, $server_domain, $ServerPackages_key, $foreign_servers_register_delay, + $serverPackages_enabled, $foreign_server_string, $server_domain, $ServerPackages_key, $foreign_servers_register_delay, $wake_on_lan_passwd, $job_synchronization, $modified_jobs_loop_delay, $arp_enabled, $arp_interface, $opsi_enabled, $opsi_server, $opsi_admin, $opsi_password, - $new_systems_ou, + $new_systems_ou, + $arch, ); # additional variable which should be globaly accessable @@ -104,7 +105,7 @@ our $gosa_address; our $no_arp; our $forground; our $cfg_file; -our ($ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password, $ldap_server_dn, $ldap_version); +our ($ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password, $ldap_server_dn, $ldap_version, $ldap_retry_sec); our ($mysql_username, $mysql_password, $mysql_database, $mysql_host); our $known_modules; our $known_functions; @@ -151,6 +152,7 @@ my @job_queue_col_names = ("id INTEGER PRIMARY KEY", "plainname VARCHAR(255) DEFAULT 'none'", "siserver VARCHAR(255) DEFAULT 'none'", "modified INTEGER DEFAULT '0'", + "periodic VARCHAR(6) DEFAULT 'none'", ); # holds all other gosa-si-server @@ -194,7 +196,6 @@ our $packages_list_tn = "packages_list"; my $packages_list_file_name; our @packages_list_col_names = ("distribution VARCHAR(255)", "package VARCHAR(255)", "version VARCHAR(255)", "section VARCHAR(255)", "description TEXT", "template LONGBLOB", "timestamp VARCHAR(14)"); my $outdir = "/tmp/packages_list_db"; -my $arch = "i386"; # holds all messages which should be delivered to a user our $messaging_db; @@ -225,6 +226,10 @@ our $logged_in_user_date_of_expiry = 600; # List of month names, used in function daemon_log my @monthnames = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); +# List of accepted periodical xml tags related to cpan modul DateTime +our $check_periodic = {"months"=>'', "weeks"=>'', "days"=>'', "hours"=>'', "minutes"=>''}; + + %cfg_defaults = ( "general" => { "log-file" => [\$log_file, "/var/run/".$prg.".log"], @@ -244,41 +249,44 @@ my @monthnames = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "foreign-clients" => [\$foreign_clients_file_name, '/var/lib/gosa-si/foreign_clients.db'], "source-list" => [\$sources_list, '/etc/apt/sources.list'], "repo-path" => [\$repo_path, '/srv/www/repository'], + "debian-arch" => [\$arch, 'i386'], "ldap-uri" => [\$ldap_uri, ""], "ldap-base" => [\$ldap_base, ""], "ldap-admin-dn" => [\$ldap_admin_dn, ""], "ldap-admin-password" => [\$ldap_admin_password, ""], "ldap-version" => [\$ldap_version, 3], + "ldap-retry-sec" => [\$ldap_retry_sec, 10], "gosa-unit-tag" => [\$gosa_unit_tag, ""], "max-clients" => [\$max_clients, 10], "wol-password" => [\$wake_on_lan_passwd, ""], - "mysql-username" => [\$mysql_username, "gosa_si"], - "mysql-password" => [\$mysql_password, ""], - "mysql-database" => [\$mysql_database, "gosa_si"], - "mysql-host" => [\$mysql_host, "127.0.0.1"], + "mysql-username" => [\$mysql_username, "gosa_si"], + "mysql-password" => [\$mysql_password, ""], + "mysql-database" => [\$mysql_database, "gosa_si"], + "mysql-host" => [\$mysql_host, "127.0.0.1"], }, "GOsaPackages" => { "job-queue" => [\$job_queue_file_name, '/var/lib/gosa-si/jobs.db'], "job-queue-loop-delay" => [\$job_queue_loop_delay, 3], "messaging-db-loop-delay" => [\$messaging_db_loop_delay, 3], "key" => [\$GosaPackages_key, "none"], - "new-systems-ou" => [\$new_systems_ou, 'ou=workstations,ou=systems'], + "new-systems-ou" => [\$new_systems_ou, 'ou=workstations,ou=systems'], }, "ClientPackages" => { "key" => [\$ClientPackages_key, "none"], "user-date-of-expiry" => [\$logged_in_user_date_of_expiry, 600], }, "ServerPackages"=> { + "enabled" => [\$serverPackages_enabled, "true"], "address" => [\$foreign_server_string, ""], - "dns-lookup" => [\$dns_lookup, "true"], - "domain" => [\$server_domain, ""], - "key" => [\$ServerPackages_key, "none"], + "dns-lookup" => [\$dns_lookup, "true"], + "domain" => [\$server_domain, ""], + "key" => [\$ServerPackages_key, "none"], "key-lifetime" => [\$foreign_servers_register_delay, 120], "job-synchronization-enabled" => [\$job_synchronization, "true"], "synchronization-loop" => [\$modified_jobs_loop_delay, 5], }, "ArpHandler" => { - "enabled" => [\$arp_enabled, "true"], + "enabled" => [\$arp_enabled, "false"], "interface" => [\$arp_interface, "all"], }, "Opsi" => { @@ -311,14 +319,18 @@ usage: $prg [-hvf] [-c config] [-d number] 'vvvvvvv': debug plus info logs -no-arp : starts $prg without connection to arp module -d : if verbose level is higher than 7x 'v' specified parts can be debugged - 1 : receiving messages - 2 : sending messages - 4 : encrypting/decrypting messages - 8 : verification if a message complies gosa-si requirements - 16 : - + 1 : report incoming messages + 2 : report unencrypted outgoing messages + 4 : report encrypting key for messages + 8 : report decrypted incoming message and verification if the message complies gosa-si requirements + 16 : message processing + 32 : ldap connectivity + 64 : database status and connectivity + 128 : main process + 256 : creation of packages_list_db + 512 : ARP debug information EOF - print "\n" ; + exit(0); } @@ -376,10 +388,13 @@ sub daemon_log { $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; $year+=1900; - + # Microseconds since epoch + my $microSeconds = sprintf("%.2f", &Time::HiRes::clock_gettime()); + $microSeconds =~ s/^\d*(.\d\d)$/$1/; + # Build log message and write it to log file and commandline chomp($msg); - my $log_msg = "$month $monthday $hours:$minutes:$seconds $prg $msg\n"; + my $log_msg = "$month $monthday $hours:$minutes:$seconds$microSeconds $prg $msg\n"; flock(LOG_HANDLE, LOCK_EX); seek(LOG_HANDLE, 0, 2); print LOG_HANDLE $log_msg; @@ -427,11 +442,7 @@ sub check_cmdline_param () { } # Exit if an error occour - if( $err_counter > 0 ) - { - &usage( "", 1 ); - exit( -1 ); - } + if( $err_counter > 0 ) { &usage( "", 1 ); } } @@ -509,6 +520,13 @@ sub import_modules { if( $file =~ /ArpHandler.pm/ ) { if( $arp_enabled eq "false" ) { next; } } + + # ServerPackages switch + if ($file eq "ServerPackages.pm" && $serverPackages_enabled eq "false") + { + $dns_lookup = "false"; + next; + } eval { require $file; }; if ($@) { @@ -652,15 +670,17 @@ sub check_outgoing_xml_validity { die 'source has length 0'; } - # Check if source contains hostname instead of ip address - 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+$/) { - # Write ip address to $source variable - $source = "$ip_address:$port"; - } - } + # Check if source contains hostname instead of ip address + if($source =~ /^[a-z][\w\-\.]+:\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+$/) { + # Write ip address to $source variable + $source = "$ip_address:$port"; + $msg_hash->{source}[0] = $source ; + $msg =~ s/.*<\/source>/$source<\/source>/; + } + } 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 nor 'GOSA'"; @@ -692,7 +712,7 @@ sub check_outgoing_xml_validity { $msg_hash = undef; } - return ($msg_hash); + return ($msg, $msg_hash); } @@ -983,7 +1003,7 @@ sub send_msg_to_target { if($new_status eq "down"){ daemon_log("$session_id WARNING: set '$address' from status '$act_status' to '$new_status'", 3); } else { - daemon_log("$session_id INFO: set '$address' from status '$act_status' to '$new_status'", 5); + daemon_log("$session_id DEBUG: set '$address' from status '$act_status' to '$new_status'", 138); } } } @@ -1004,7 +1024,7 @@ sub send_msg_to_target { if($new_status eq "down"){ daemon_log("$session_id WARNING: set '$address' from status '$act_status' to '$new_status'", 3); } else { - daemon_log("$session_id INFO: set '$address' from status '$act_status' to '$new_status'", 5); + daemon_log("$session_id DEBUG: set '$address' from status '$act_status' to '$new_status'", 138); } } } @@ -1014,8 +1034,8 @@ sub send_msg_to_target { sub update_jobdb_status_for_send_msgs { my ($session_id, $answer, $error) = @_; - &daemon_log("$session_id DEBUG: try to update job status", 7); if( $answer =~ /(\d+)<\/jobdb_id>/ ) { + &daemon_log("$session_id DEBUG: try to update job status", 138); my $jobdb_id = $1; $answer =~ /
(.*)<\/header>/; @@ -1033,7 +1053,6 @@ sub update_jobdb_status_for_send_msgs { ||($job_header eq "trigger_action_halt") ) { my $sql_statement = "UPDATE $job_queue_tn SET status='done' WHERE id=$jobdb_id"; - &daemon_log("$session_id DEBUG: $sql_statement", 7); my $res = $job_db->update_dbentry($sql_statement); # Reactivate jobs, jobs need to deliver their message @@ -1042,14 +1061,22 @@ sub update_jobdb_status_for_send_msgs { ||($job_header eq "trigger_action_reinstall") ||($job_header eq "trigger_activate_new") ) { - &reactivate_job_with_delay($session_id, $job_target, $job_header, 30 ); - + if ($job_target =~ /^([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})$/i) { + &reactivate_job_with_delay($session_id, $job_target, $job_header, 30 ); + } else { + # If we don't have the mac adress at this time, we use the plainname + my $plainname_result = $job_db->select_dbentry("SELECT plainname from jobs where id=$jobdb_id"); + my $plainname = $job_target; + if ((keys(%$plainname_result) > 0) ) { + $plainname = $plainname_result->{1}->{$job_target}; + } + &reactivate_job_with_delay($session_id, $plainname, $job_header, 30 ); + } # For all other messages } else { my $sql_statement = "UPDATE $job_queue_tn ". "SET status='error', result='can not deliver msg, please consult log file' ". "WHERE id=$jobdb_id"; - &daemon_log("$session_id DEBUG: $sql_statement", 7); my $res = $job_db->update_dbentry($sql_statement); } @@ -1069,14 +1096,13 @@ sub update_jobdb_status_for_send_msgs { my $sql_statement = "UPDATE $job_queue_tn ". "SET status='done' ". "WHERE id=$jobdb_id AND status='processed'"; - &daemon_log("$session_id DEBUG: $sql_statement", 7); my $res = $job_db->update_dbentry($sql_statement); } else { - &daemon_log("$session_id DEBUG: sending message succeed but cannot update job status.", 7); + &daemon_log("$session_id DEBUG: sending message succeed but cannot update job status.", 138); } } } else { - &daemon_log("$session_id DEBUG: cannot update job status, msg has no jobdb_id-tag.", 7); + &daemon_log("$session_id DEBUG: cannot update job status, msg has no jobdb_id-tag.", 138); } } @@ -1087,11 +1113,10 @@ sub reactivate_job_with_delay { if (not defined $delay) { $delay = 30 } ; my $delay_timestamp = &calc_timestamp(&get_time(), "plus", $delay); - my $sql = "UPDATE $job_queue_tn Set timestamp='$delay_timestamp', status='waiting' WHERE (macaddress LIKE 'target' AND headertag='$header')"; + my $sql = "UPDATE $job_queue_tn Set timestamp='$delay_timestamp', status='waiting' WHERE (macaddress LIKE '$target' OR plainname LIKE '$target') AND headertag='$header'"; my $res = $job_db->update_dbentry($sql); daemon_log("$session_id INFO: '$header'-job will be reactivated at '$delay_timestamp' ". "cause client '$target' is currently not available", 5); - daemon_log("$session_id $sql", 7); return; } @@ -1118,7 +1143,7 @@ sub msg_to_decrypt { ($msg, $msg_hash, $module) = &input_from_unknown_host($next_msg, $session_id); # msg is from a gosa-si-server - if(( !$msg ) || ( !$msg_hash ) || ( !$module )){ + if(((!$msg) || (!$msg_hash) || (!$module)) && ($serverPackages_enabled eq "true")){ if (not defined $msg_source) { # Only needed, to be compatible with older gosa-si-server versions @@ -1131,7 +1156,15 @@ sub msg_to_decrypt { } # msg is from a gosa-si-client if(( !$msg ) || ( !$msg_hash ) || ( !$module )){ - ($msg, $msg_hash, $module) = &input_from_known_client($next_msg, $msg_source, $session_id); + if (not defined $msg_source) + { + # Only needed, to be compatible with older gosa-si-server versions + ($msg, $msg_hash, $module) = &input_from_known_client($next_msg, $heap->{'remote_ip'}, $session_id); + } + else + { + ($msg, $msg_hash, $module) = &input_from_known_client($next_msg, $msg_source, $session_id); + } } # an error occurred if(( !$msg ) || ( !$msg_hash ) || ( !$module )){ @@ -1139,7 +1172,7 @@ sub msg_to_decrypt { # or a server. In case of a client, send a ping. If the client could not understand a msg from its # server the client cause a re-registering process. In case of a server, decrease update_time in kown_server_db # and trigger a re-registering process for servers - if (defined $msg_source && $msg_source =~ /:$server_port$/) + if (defined $msg_source && $msg_source =~ /:$server_port$/ && $serverPackages_enabled eq "true") { daemon_log("$session_id WARNING: Cannot understand incoming msg from server '$msg_source'. Cause re-registration process for servers.", 3); my $update_statement = "UPDATE $known_server_tn SET update_time='19700101000000' WHERE hostname='$msg_source'"; @@ -1147,19 +1180,20 @@ sub msg_to_decrypt { my $upadte_res = $known_server_db->exec_statement($update_statement); $kernel->yield("register_at_foreign_servers"); } - elsif (defined $msg_source) + elsif ((defined $msg_source) && (not $msg_source =~ /:$server_port$/)) { daemon_log("$session_id WARNING: Cannot understand incoming msg from client '$msg_source'. Send ping-msg to cause a re-registering of the client if necessary", 3); #my $remote_ip = $heap->{'remote_ip'}; #my $remote_port = $heap->{'remote_port'}; my $ping_msg = "
gosa_ping
$server_address$msg_source
"; my ($test_error, $test_error_string) = &send_msg_to_target($ping_msg, "$msg_source", "dummy-key", "gosa_ping", $session_id); - daemon_log("$session_id WARNING: sending msg to cause re-registering: $ping_msg", 3); + daemon_log("$session_id WARNING: Sending msg to cause re-registering: $ping_msg", 3); } else { my $foreign_host = defined $msg_source ? $msg_source : $heap->{'remote_ip'}; - daemon_log("$session_id ERROR: incoming message from host '$foreign_host' cannot be understood. Processing aborted: $tmp_next_msg", 1); + daemon_log("$session_id ERROR: Incoming message from host '$foreign_host' cannot be understood. Processing aborted!", 1); + daemon_log("$session_id DEBUG: Aborted message: $tmp_next_msg", 11); } $error++ @@ -1281,7 +1315,7 @@ sub msg_to_decrypt { module=>$module, sessionid=>$session_id, } ); - + $kernel->yield('watch_for_next_tasks'); } # target is own address with forward_to_gosa-tag pointing at myself -> forward to gosa @@ -1322,7 +1356,7 @@ sub msg_to_decrypt { $msg =~ s/
gosa_/
/; my $error= &send_msg_to_target($msg, $hostname, $hostkey, $header, $session_id); if ($error) { - &daemon_log("$session_id ERROR: Some problems occurred while trying to send msg to client '$hostkey': $msg", 1); + &daemon_log("$session_id ERROR: Some problems occurred while trying to send msg to client '$hostname': $msg", 1); } } else @@ -1401,6 +1435,7 @@ sub msg_to_decrypt { sessionid=>$session_id, } ); $done = 1; + $kernel->yield('watch_for_next_tasks'); } @@ -1504,17 +1539,18 @@ sub process_task { # process incoming msg if( $error == 0) { daemon_log("$session_id INFO: Incoming msg (session_id=$session_id) with header '".@{$msg_hash->{'header'}}[0]."'", 5); - daemon_log("$session_id DEBUG: Processing module ".$module, 7); + daemon_log("$session_id DEBUG: Processing module ".$module, 26); $answer_l = &{ $module."::process_incoming_msg" }($msg, $msg_hash, $session_id); if ( 0 < @{$answer_l} ) { my $answer_str = join("\n", @{$answer_l}); + my @headers; while ($answer_str =~ /
(\w+)<\/header>/g) { - daemon_log("$session_id INFO: got answer message with header '$1'", 5); + push(@headers, $1); } - daemon_log("$session_id DEBUG: $module: got answer from module: \n".$answer_str,9); + daemon_log("$session_id DEBUG: got answer message(s) with header: '".join("', '", @headers)."'", 26); } else { - daemon_log("$session_id DEBUG: $module: got no answer from module!" ,7); + daemon_log("$session_id DEBUG: $module: got no answer from module!" ,26); } } @@ -1526,7 +1562,7 @@ sub process_task { foreach my $answer ( @{$answer_l} ) { # check outgoing msg to xml validity - my $answer_hash = &check_outgoing_xml_validity($answer, $session_id); + my ($answer, $answer_hash) = &check_outgoing_xml_validity($answer, $session_id); if( not defined $answer_hash ) { next; } $answer_header = @{$answer_hash->{'header'}}[0]; @@ -1570,6 +1606,9 @@ sub process_task { if( defined $session_id ) { $add_on = ".session_id=$session_id"; } + my $header = ($1) if $answer =~ /
(\S*)<\/header>/; + daemon_log("$session_id INFO: send ".$header." message to GOsa", 5); + daemon_log("$session_id DEBUG: message:\n$answer", 12); # answer is for GOSA and has to returned to connected client my $gosa_answer = &encrypt_msg($answer, $GosaPackages_key); $client_answer = $gosa_answer.$add_on; @@ -1586,7 +1625,7 @@ sub process_task { # Target of msg is a mac address elsif( $answer_target =~ /^([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})$/i ) { - daemon_log("$session_id INFO: target is mac address '$answer_target', looking for host in known_clients and foreign_clients", 5); + daemon_log("$session_id DEBUG: target is mac address '$answer_target', looking for host in known_clients and foreign_clients", 138); # Looking for macaddress in known_clients my $sql_statement = "SELECT * FROM known_clients WHERE macaddress LIKE '$answer_target'"; @@ -1673,7 +1712,6 @@ sub session_start { $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); @@ -1693,16 +1731,35 @@ sub session_start { sub watch_for_done_jobs { - #CHECK: $heap for what? - my ($kernel,$heap) = @_[KERNEL, HEAP]; + my $kernel = $_[KERNEL]; my $sql_statement = "SELECT * FROM ".$job_queue_tn." WHERE ((status='done') AND (modified='0'))"; my $res = $job_db->select_dbentry( $sql_statement ); - while( my ($id, $hit) = each %{$res} ) { - my $jobdb_id = $hit->{id}; - my $sql_statement = "DELETE FROM $job_queue_tn WHERE id=$jobdb_id"; - my $res = $job_db->del_dbentry($sql_statement); + while( my ($number, $hit) = each %{$res} ) + { + # Non periodical jobs can be deleted. + if ($hit->{periodic} eq "none") + { + my $jobdb_id = $hit->{id}; + my $sql_statement = "DELETE FROM $job_queue_tn WHERE id=$jobdb_id"; + my $res = $job_db->del_dbentry($sql_statement); + } + + # Periodical jobs should not be deleted but reactivated with new timestamp instead. + else + { + my ($p_time, $periodic) = split("_", $hit->{periodic}); + my $reactivated_ts = $hit->{timestamp}; + my $act_ts = int(&get_time()); + while ($act_ts > int($reactivated_ts)) # Redo calculation to avoid multiple jobs in the past + { + $reactivated_ts = &calc_timestamp($reactivated_ts, "plus", $p_time, $periodic); + } + my $sql = "UPDATE $job_queue_tn SET status='waiting', timestamp='$reactivated_ts' WHERE id='".$hit->{id}."'"; + my $res = $job_db->exec_statement($sql); + &daemon_log("J INFO: Update periodical job '".$hit->{headertag}."' for client '".$hit->{targettag}."'. New execution time '$reactivated_ts'.", 5); + } } $kernel->delay_set('watch_for_done_jobs',$job_queue_loop_delay); @@ -1711,7 +1768,6 @@ sub watch_for_done_jobs { sub watch_for_opsi_jobs { my ($kernel) = $_[KERNEL]; - # This is not very nice to look for opsi install jobs, but headertag has to be trigger_action_reinstall. The only way to identify a # opsi install job is to parse the xml message. There is still the correct header. my $sql_statement = "SELECT * FROM ".$job_queue_tn." WHERE ((xmlmessage LIKE '%opsi_install_client
%') AND (status='processing') AND (siserver='localhost'))"; @@ -1735,10 +1791,14 @@ sub watch_for_opsi_jobs { }; my $hres = $opsi_client->call($opsi_url, $callobj); - #my ($hres_err, $hres_err_string) = &check_opsi_res($hres); + # TODO : move all opsi relevant statments to opsi plugin + # The following 3 lines must be tested befor they can replace the rubbish above and below !!! + #my ($res, $err) = &opsi_com::_getProductStates_hash(hostId=>$hostId) + #if (not $err) { + # my $htmp = $res->{$hostId}; + # if (not &check_opsi_res($hres)) { my $htmp= $hres->result->{$hostId}; - # Check state != not_installed or action == setup -> load and add my $products= 0; my $installed= 0; @@ -1929,7 +1989,7 @@ sub watch_for_new_jobs { my $func_error = &send_msg_to_target($job_msg, $server_address, $GosaPackages_key, $header, "J"); # update status in job queue to ... - # ... 'processing', for jobs: 'reinstall', 'update' + # ... 'processing', for jobs: 'reinstall', 'update', activate_new if (($header =~ /gosa_trigger_action_reinstall/) || ($header =~ /gosa_trigger_activate_new/) || ($header =~ /gosa_trigger_action_update/)) { @@ -1940,7 +2000,7 @@ sub watch_for_new_jobs { # ... 'done', for all other jobs, they are no longer needed in the jobqueue else { my $sql_statement = "UPDATE $job_queue_tn SET status='done' WHERE id=$jobdb_id"; - my $dbres = $job_db->update_dbentry($sql_statement); + my $dbres = $job_db->exec_statement($sql_statement); } @@ -2049,7 +2109,6 @@ sub watch_for_delivery_messages { # select outgoing messages my $sql_statement = "SELECT * FROM $messaging_tn WHERE ( flag='p' AND direction='out' )"; - #&daemon_log("0 DEBUG: $sql", 7); my $res = $messaging_db->exec_statement( $sql_statement ); # build out msg for each usr @@ -2061,7 +2120,6 @@ sub watch_for_delivery_messages { # resolve usr -> host where usr is logged in my $sql = "SELECT * FROM $login_users_tn WHERE (user='$receiver')"; - #&daemon_log("0 DEBUG: $sql", 7); my $res = $login_users_db->exec_statement($sql); # receiver is logged in nowhere @@ -2151,21 +2209,18 @@ sub watch_for_done_messages { my ($kernel,$heap) = @_[KERNEL, HEAP]; my $sql = "SELECT * FROM $messaging_tn WHERE (flag='p' AND direction='in')"; - #&daemon_log("0 DEBUG: $sql", 7); my $res = $messaging_db->exec_statement($sql); foreach my $hit (@{$res}) { my $msg_id = @{$hit}[0]; my $sql = "SELECT * FROM $messaging_tn WHERE (id='$msg_id' AND direction='out' AND (NOT flag='s'))"; - #&daemon_log("0 DEBUG: $sql", 7); my $res = $messaging_db->exec_statement($sql); # not all usr msgs have been seen till now if ( ref(@$res[0]) eq "ARRAY") { next; } $sql = "DELETE FROM $messaging_tn WHERE (id='$msg_id')"; - #&daemon_log("0 DEBUG: $sql", 7); $res = $messaging_db->exec_statement($sql); } @@ -2224,15 +2279,13 @@ sub watch_for_next_tasks { } my $message_id = $hit->{'id'}; my $session_id = $hit->{'sessionid'}; - &daemon_log("$session_id DEBUG: start processing for message with incoming id: '$message_id'", 7); + &daemon_log("$session_id DEBUG: start processing for message with incoming id: '$message_id'", 11); $kernel->yield('next_task', $hit); my $sql = "DELETE FROM $incoming_tn WHERE id=$message_id"; my $res = $incoming_db->exec_statement($sql); } - - $kernel->delay_set('watch_for_next_tasks', 1); } @@ -2248,16 +2301,16 @@ sub get_ldap_handle { if ($subroutine eq "(eval)") { $caller_text = "eval block within file '$file' for '$evalText'"; } - daemon_log("$session_id INFO: new ldap handle for '$caller_text' required!", 7); + daemon_log("$session_id DEBUG: new ldap handle for '$caller_text' required!", 42); get_handle: my $ldap_handle = Net::LDAP->new( $ldap_uri ); if (not ref $ldap_handle) { - daemon_log("$session_id ERROR: Connection to LDAP URI '$ldap_uri' failed! Retrying!", 1); - usleep(100000); + daemon_log("$session_id ERROR: Connection to LDAP URI '$ldap_uri' failed! Retrying in $ldap_retry_sec seconds.", 1); + sleep($ldap_retry_sec); goto get_handle; } else { - daemon_log("$session_id DEBUG: Connection to LDAP URI '$ldap_uri' established.", 6); + daemon_log("$session_id DEBUG: Connection to LDAP URI '$ldap_uri' established.", 42); } $ldap_handle->bind($ldap_admin_dn, password => $ldap_admin_password) or &daemon_log("$session_id ERROR: Could not bind as '$ldap_admin_dn' to LDAP URI '$ldap_uri'!", 1); @@ -2266,11 +2319,13 @@ get_handle: sub release_ldap_handle { - my ($ldap_handle) = @_ ; + my ($ldap_handle, $session_id) = @_ ; + if (not defined $session_id ) { $session_id = 0 }; + if(ref $ldap_handle) { $ldap_handle->disconnect(); } - &main::daemon_log("0 DEBUG: Released a ldap handle!", 6); + &main::daemon_log("$session_id DEBUG: Released a ldap handle!", 42); return; } @@ -2348,13 +2403,13 @@ sub change_fai_state { daemon_log("$session_id Error: Setting FAIstate to '$state' for ".$entry->dn. "failed: ".$result->error, 1); } } else { - daemon_log("$session_id DEBUG FAIstate at host '".$entry->dn."' already at state '$st'", 7); + daemon_log("$session_id DEBUG FAIstate at host '".$entry->dn."' already at state '$st'", 42); } } } else { daemon_log("$session_id ERROR: LDAP search failed: ldap_base=$ldap_base, filter=$search", 1); } - &release_ldap_handle($ldap_handle); + &release_ldap_handle($ldap_handle, $session_id); return; } @@ -2414,7 +2469,7 @@ sub change_goto_state { } } - &release_ldap_handle($ldap_handle); + &release_ldap_handle($ldap_handle, $session_id); return; } @@ -2524,7 +2579,7 @@ sub create_fai_release_db { ); if(($mesg->code == 0) && ($mesg->count != 0)) { - daemon_log("$session_id DEBUG: create_fai_release_db: count " . $mesg->count,8); + daemon_log("$session_id DEBUG: create_fai_release_db: count " . $mesg->count,138); # Walk through all possible FAI container ou's my @sql_list; @@ -2551,14 +2606,14 @@ sub create_fai_release_db { } } - daemon_log("$session_id DEBUG: create_fai_release_db: Inserting ".scalar @sql_list." entries to DB",8); + daemon_log("$session_id DEBUG: create_fai_release_db: Inserting ".scalar @sql_list." entries to DB",138); &release_ldap_handle($ldap_handle); if(@sql_list) { unshift @sql_list, "VACUUM"; unshift @sql_list, "DELETE FROM $table_name"; $fai_release_db->exec_statementlist(\@sql_list); } - daemon_log("$session_id DEBUG: create_fai_release_db: Done with inserting",7); + daemon_log("$session_id DEBUG: create_fai_release_db: Done with inserting",138); } else { daemon_log("$session_id INFO: create_fai_release_db: error: " . $mesg->code, 5); } @@ -2608,14 +2663,14 @@ sub resolve_fai_classes { my $fai_filter= "(|(&(objectClass=FAIclass)(|(objectClass=".join(")(objectClass=", @possible_fai_classes).")))(objectClass=FAIbranch))"; my $fai_classes; - daemon_log("$session_id DEBUG: Searching for FAI entries in base $fai_base",7); + daemon_log("$session_id DEBUG: Searching for FAI entries in base $fai_base", 138); my $mesg= $ldap_handle->search( base => $fai_base, scope => 'sub', attrs => ['cn','objectClass','FAIstate'], filter => $fai_filter, ); - daemon_log("$session_id DEBUG: Found ".$mesg->count()." FAI entries",7); + daemon_log("$session_id DEBUG: Found ".$mesg->count()." FAI entries", 138); if($mesg->{'resultCode'} == 0 && $mesg->count != 0) { @@ -3096,7 +3151,7 @@ sub parse_package_info { $repo_dirs{ "${repo_path}/pool" } = 1; foreach $package ("Packages.gz"){ - daemon_log("$session_id DEBUG: create_packages_list: fetch $baseurl, $dist, $section", 7); + daemon_log("$session_id DEBUG: create_packages_list: fetch $baseurl, $dist, $section", 266); get_package( "$baseurl/dists/$dist/$section/binary-$arch/$package", "$outdir/$dist/$section", $session_id ); parse_package( "$outdir/$dist/$section", $dist, $path, $session_id ); } @@ -3114,9 +3169,9 @@ sub get_package { # This is ugly, but I've no time to take a look at "how it works in perl" if(0 == system("wget '$url' -O '$dest' 2>/dev/null") ) { system("gunzip -cd '$dest' > '$dest.in'"); - daemon_log("$session_id DEBUG: run command: gunzip -cd '$dest' > '$dest.in'", 7); + daemon_log("$session_id DEBUG: run command: gunzip -cd '$dest' > '$dest.in'", 266); unlink($dest); - daemon_log("$session_id DEBUG: delete file '$dest'", 7); + daemon_log("$session_id DEBUG: delete file '$dest'", 266); } else { daemon_log("$session_id ERROR: create_packages_list_db: get_packages: fetching '$url' into '$dest' failed!", 1); } @@ -3223,7 +3278,7 @@ sub cleanup_and_extract { if( -f "$dir/DEBIAN/templates" ) { - daemon_log("0 DEBUG: Found debconf templates in '$package' - $newver", 7); + daemon_log("0 DEBUG: Found debconf templates in '$package' - $newver", 266); my $tmpl= ""; { local $/=undef; @@ -3242,6 +3297,79 @@ sub cleanup_and_extract { } +sub prepare_server_registration +{ + # Add foreign server from cfg file + my @foreign_server_list; + if ($foreign_server_string ne "") { + my @cfg_foreign_server_list = split(",", $foreign_server_string); + foreach my $foreign_server (@cfg_foreign_server_list) { + push(@foreign_server_list, $foreign_server); + } + + daemon_log("0 INFO: found foreign server in config file: ".join(", ", @foreign_server_list), 5); + } + + # Perform a DNS lookup for server registration if flag is true + if ($dns_lookup eq "true") { + # Add foreign server from dns + my @tmp_servers; + if (not $server_domain) { + # Try our DNS Searchlist + for my $domain(get_dns_domains()) { + chomp($domain); + my ($tmp_domains, $error_string) = &get_server_addresses($domain); + if(@$tmp_domains) { + for my $tmp_server(@$tmp_domains) { + push @tmp_servers, $tmp_server; + } + } + } + if(@tmp_servers && length(@tmp_servers)==0) { + daemon_log("0 WARNING: no foreign gosa-si-server found in DNS for domain '$server_domain'", 3); + } + } else { + @tmp_servers = &get_server_addresses($server_domain); + if( 0 == @tmp_servers ) { + daemon_log("0 WARNING: no foreign gosa-si-server found in DNS for domain '$server_domain'", 3); + } + } + + daemon_log("0 INFO: found foreign server via DNS ".join(", ", @tmp_servers), 5); + + foreach my $server (@tmp_servers) { + unshift(@foreign_server_list, $server); + } + } else { + daemon_log("0 INFO: DNS lookup for server registration is disabled", 5); + } + + # eliminate duplicate entries + @foreign_server_list = &del_doubles(@foreign_server_list); + 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 $cur_timestamp = &get_time(); + foreach my $foreign_server (@foreign_server_list) { + + # do not add myself to known_server_db + if (&is_local($foreign_server)) { next; } + ###################################### + + my $res = $known_server_db->add_dbentry( {table=>$known_server_tn, + primkey=>['hostname'], + hostname=>$foreign_server, + macaddress=>"", + status=>'not_yet_registered', + hostkey=>"none", + loaded_modules => "none", + timestamp=>$cur_timestamp, + update_time=>'19700101000000', + } ); + } +} + sub register_at_foreign_servers { my ($kernel) = $_[KERNEL]; @@ -3249,12 +3377,10 @@ sub register_at_foreign_servers { # block them for race conditional registration processes of other si-servers. my $act_time = &get_time(); my $block_statement = "UPDATE $known_server_tn SET status='new_server',update_time='19700101000000' WHERE (CAST(update_time AS UNSIGNED))<$act_time "; - &daemon_log("0 DEBUG: $block_statement", 7); my $block_res = $known_server_db->exec_statement($block_statement); # Fetch all si-server from db where update_time is younger than act_time my $fetch_statement = "SELECT * FROM $known_server_tn WHERE update_time='19700101000000'"; - &daemon_log("0 DEBUG: $fetch_statement", 7); my $fetch_res = $known_server_db->exec_statement($fetch_statement); # Detect already connected clients. Will be added to registration msg later. @@ -3306,7 +3432,6 @@ sub control_server_registration { # Check if all registration processes succeed or not my $select_statement = "SELECT * FROM $known_server_tn WHERE status='new_server'"; - &daemon_log("0 DEBUG $select_statement", 7); my $select_res = $known_server_db->exec_statement($select_statement); # If at least one registration process failed, maybe in case of a race condition @@ -3316,7 +3441,6 @@ sub control_server_registration { # Release block statement 'new_server' to make the server accessible # for foreign registration processes my $update_statement = "UPDATE $known_server_tn SET status='waiting' WHERE status='new_server'"; - &daemon_log("0 DEBUG: $update_statement", 7); my $update_res = $known_server_db->exec_statement($update_statement); # Set a random delay to avoid the registration race condition @@ -3342,7 +3466,7 @@ GetOptions("h|help" => \&usage, "v|verbose+" => \$verbose, "no-arp+" => \$no_arp, "d=s" => \$debug_parts, - ) or (&usage("", 1)&&(exit(-1))); + ) or &usage("", 1); # read and set config parameters &check_cmdline_param ; @@ -3408,6 +3532,9 @@ daemon_log($server_status_hash->{$server_status}.": $server_revision", 1); no strict "refs"; if ($db_module eq "DBmysql") { + + daemon_log("0 INFO: importing database module '$db_module'", 1); + # connect to incoming_db $incoming_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password); @@ -3439,6 +3566,9 @@ daemon_log($server_status_hash->{$server_status}.": $server_revision", 1); $messaging_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password); } elsif ($db_module eq "DBsqlite") { + + daemon_log("0 INFO: importing database module '$db_module'", 1); + # connect to incoming_db unlink($incoming_file_name); $incoming_db = GOSA::DBsqlite->new($incoming_file_name); @@ -3463,7 +3593,7 @@ daemon_log($server_status_hash->{$server_status}.": $server_revision", 1); chown($root_uid, $adm_gid, $foreign_clients_file_name); # connect to known_server_db - #unlink($known_server_file_name); + unlink($known_server_file_name); # do not delete, gosa-si-server should be forced to check config file and dns at each start $known_server_db = GOSA::DBsqlite->new($known_server_file_name); chmod(0640, $known_server_file_name); chown($root_uid, $adm_gid, $known_server_file_name); @@ -3500,8 +3630,10 @@ daemon_log($server_status_hash->{$server_status}.": $server_revision", 1); } } - # Creating tables + +daemon_log("0 INFO: creating tables in database with '$db_module'", 1); + $messaging_db->create_table($messaging_tn, \@messaging_col_names); $packages_list_db->create_table($packages_list_tn, \@packages_list_col_names); $fai_release_db->create_table($fai_release_tn, \@fai_release_col_names); @@ -3516,95 +3648,20 @@ $job_db->create_table($job_queue_tn, \@job_queue_col_names); # create xml object used for en/decrypting $xml = new XML::Simple(); - -# foreign servers -my @foreign_server_list; - -# add foreign server from cfg file -if ($foreign_server_string ne "") { - my @cfg_foreign_server_list = split(",", $foreign_server_string); - foreach my $foreign_server (@cfg_foreign_server_list) { - push(@foreign_server_list, $foreign_server); - } - - daemon_log("0 INFO: found foreign server in config file: ".join(", ", @foreign_server_list), 5); -} - -# Perform a DNS lookup for server registration if flag is true -if ($dns_lookup eq "true") { - # Add foreign server from dns - my @tmp_servers; - if (not $server_domain) { - # Try our DNS Searchlist - for my $domain(get_dns_domains()) { - chomp($domain); - my ($tmp_domains, $error_string) = &get_server_addresses($domain); - if(@$tmp_domains) { - for my $tmp_server(@$tmp_domains) { - push @tmp_servers, $tmp_server; - } - } - } - if(@tmp_servers && length(@tmp_servers)==0) { - daemon_log("0 WARNING: no foreign gosa-si-server found in DNS for domain '$server_domain'", 3); - } - } else { - @tmp_servers = &get_server_addresses($server_domain); - if( 0 == @tmp_servers ) { - daemon_log("0 WARNING: no foreign gosa-si-server found in DNS for domain '$server_domain'", 3); - } - } - - daemon_log("0 INFO: found foreign server via DNS ".join(", ", @tmp_servers), 5); - - foreach my $server (@tmp_servers) { - unshift(@foreign_server_list, $server); - } -} else { - daemon_log("0 INFO: DNS lookup for server registration is disabled", 5); -} - - -# eliminate duplicate entries -@foreign_server_list = &del_doubles(@foreign_server_list); -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 $cur_timestamp = &get_time(); -foreach my $foreign_server (@foreign_server_list) { - - # do not add myself to known_server_db - if (&is_local($foreign_server)) { next; } - ###################################### - - my $res = $known_server_db->add_dbentry( {table=>$known_server_tn, - primkey=>['hostname'], - hostname=>$foreign_server, - macaddress=>"", - status=>'not_yet_registered', - hostkey=>"none", - loaded_modules => "none", - timestamp=>$cur_timestamp, - update_time=>'19700101000000', - } ); -} - - # Import all modules &import_modules; # Check wether all modules are gosa-si valid passwd check &password_check; +# Check DNS and config file for server registration +if ($serverPackages_enabled eq "true") { &prepare_server_registration; } + # Create functions hash -#print STDERR Dumper $known_modules; while (my ($module, @mod_info) = each %$known_modules) { -#print STDERR Dumper $module; while (my ($plugin, $functions) = each %{$mod_info[0][2]}) { -#print STDERR Dumper $functions; while (my ($function, $nothing) = each %$functions ) { $known_functions->{$function} = $nothing; @@ -3627,9 +3684,14 @@ POE::Component::Server::TCP->new( ClientInput => sub { my ($kernel, $input, $heap, $session) = @_[KERNEL, ARG0, HEAP, SESSION]; my $session_id = $session->ID; - if ($input =~ /;([\d\.]+:[\d]+)$/) + if ($input =~ /;([\d\.]+):([\d]+)$/) { - &daemon_log("$session_id DEBUG: incoming message from '$1'", 11); + # Messages from other servers should be blocked if config option is set + if (($2 eq $server_port) && ($serverPackages_enabled eq "false")) + { + return; + } + &daemon_log("$session_id DEBUG: incoming message from '$1:$2'", 11); } else { @@ -3641,6 +3703,7 @@ POE::Component::Server::TCP->new( }, InlineStates => { msg_to_decrypt => \&msg_to_decrypt, + watch_for_next_tasks => \&watch_for_next_tasks, next_task => \&next_task, task_result => \&handle_task_result, task_done => \&handle_task_done, @@ -3662,7 +3725,6 @@ POE::Session->create( task_result => \&handle_task_result, task_done => \&handle_task_done, task_debug => \&handle_task_debug, - watch_for_next_tasks => \&watch_for_next_tasks, watch_for_new_messages => \&watch_for_new_messages, watch_for_delivery_messages => \&watch_for_delivery_messages, watch_for_done_messages => \&watch_for_done_messages,