X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-server;h=ada883ba08d8c225d9040d5cb39a4217c8586dd2;hb=6d4f9c12acf600c263f6350a2300bac383b967b8;hp=75fec07b1a336106418d4457614e8709c0aa911a;hpb=ddc00569f9beee9e56ad0485bc0687a9e6bc64b5;p=gosa.git diff --git a/gosa-si/gosa-si-server b/gosa-si/gosa-si-server index 75fec07b1..ada883ba0 100755 --- a/gosa-si/gosa-si-server +++ b/gosa-si/gosa-si-server @@ -86,6 +86,7 @@ our (%cfg_defaults, $log_file, $pid_file, $arp_activ, $gosa_unit_tag, $GosaPackages_key, $gosa_ip, $gosa_port, $gosa_timeout, $foreign_server_string, $server_domain, $ServerPackages_key, $foreign_servers_register_delay, + $wake_on_lan_passwd, $job_synchronization, $modified_jobs_loop_delay, ); # additional variable which should be globaly accessable @@ -98,6 +99,11 @@ our $forground; our $cfg_file; our ($ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password, $ldap_server_dn); +# dak variables +our $dak_base_directory; +our $dak_signing_keys_directory; +our $dak_queue_directory; +our $dak_user; # specifies the verbosity of the daemon_log $verbose = 0 ; @@ -140,6 +146,8 @@ my @job_queue_col_names = ("id INTEGER PRIMARY KEY", "xmlmessage DEFAULT 'none'", "macaddress DEFAULT 'none'", "plainname DEFAULT 'none'", + "siserver DEFAULT 'none'", + "modified DEFAULT '0'", ); # holds all other gosa-si-server @@ -225,6 +233,7 @@ my $max_children = 2; "ldap-admin-password" => [\$ldap_admin_password, ""], "gosa-unit-tag" => [\$gosa_unit_tag, ""], "max-clients" => [\$max_clients, 10], + "wol-password" => [\$wake_on_lan_passwd, ""], }, "GOsaPackages" => { "ip" => [\$gosa_ip, "0.0.0.0"], @@ -233,6 +242,10 @@ my $max_children = 2; "job-queue-loop-delay" => [\$job_queue_loop_delay, 3], "messaging-db-loop-delay" => [\$messaging_db_loop_delay, 3], "key" => [\$GosaPackages_key, "none"], + "dak-base" => [\$dak_base_directory, "/srv/archive"], + "dak-keyring" => [\$dak_signing_keys_directory, "/srv/archive/keyrings"], + "dak-queue" => [\$dak_queue_directory, "/srv/archive/queue"], + "dak-user" => [\$dak_user, "deb-dak"], }, "ClientPackages" => { "key" => [\$ClientPackages_key, "none"], @@ -242,6 +255,8 @@ my $max_children = 2; "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], } ); @@ -457,11 +472,36 @@ sub import_modules { close (DIR); } +#=== FUNCTION ================================================================ +# NAME: password_check +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: escalates an critical error if two modules exist which are avaialable by +# the same password +#=============================================================================== +sub password_check { + my $passwd_hash = {}; + while (my ($mod_name, $mod_info) = each %$known_modules) { + my $mod_passwd = @$mod_info[1]; + if (not defined $mod_passwd) { next; } + if (not exists $passwd_hash->{$mod_passwd}) { + $passwd_hash->{$mod_passwd} = $mod_name; + + # escalates critical error + } else { + &daemon_log("0 ERROR: two loaded modules do have the same password. Please modify the 'key'-parameter in config file"); + &daemon_log("0 ERROR: module='$mod_name' and module='".$passwd_hash->{$mod_passwd}."'"); + exit( -1 ); + } + } + +} + #=== FUNCTION ================================================================ # NAME: sig_int_handler # PARAMETERS: signal - string - signal arose from system -# RETURNS: noting +# RETURNS: nothing # DESCRIPTION: handels tasks to be done befor signal becomes active #=============================================================================== sub sig_int_handler { @@ -528,7 +568,7 @@ sub check_key_and_xml_validity { sub check_outgoing_xml_validity { - my ($msg) = @_; + my ($msg, $session_id) = @_; my $msg_hash; eval{ @@ -581,8 +621,8 @@ sub check_outgoing_xml_validity { } }; if($@) { - daemon_log("WARNING: outgoing msg is not gosa-si envelope conform", 5); - daemon_log("$@ ".(defined($msg) && length($msg)>0)?$msg:"Empty Message", 8); + daemon_log("$session_id ERROR: outgoing msg is not gosa-si envelope conform: ", 1); + daemon_log("$@ ".(defined($msg) && length($msg)>0)?$msg:"Empty Message", 1); $msg_hash = undef; } @@ -810,36 +850,6 @@ sub open_socket { } -# moved to GosaSupportDaemon: 03-06-2008: rettenbe -#=== 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; -#} - - sub get_local_ip_for_remote_ip { my $remote_ip= shift; my $result="0.0.0.0"; @@ -1033,8 +1043,8 @@ sub msg_to_decrypt { if(( !$msg ) || ( !$msg_hash ) || ( !$module )){ # if an incoming msg could not be decrypted (maybe a wrong key), send client a ping. If the client # could not understand a msg from its server the client cause a re-registering process - daemon_log("$session_id INFO cannot understand incoming msg, send 'ping'-msg to all host with ip '".$heap->{remote_ip}. - "' to cause a re-registering of the client if necessary", 5); + daemon_log("$session_id WARNING cannot understand incoming msg, send 'ping'-msg to all host with ip '".$heap->{remote_ip}. + "' to cause a re-registering of the client if necessary", 3); my $sql_statement = "SELECT * FROM $main::known_clients_tn WHERE (hostname LIKE '".$heap->{'remote_ip'}."%')"; my $query_res = $known_clients_db->select_dbentry( $sql_statement ); while( my ($hit_num, $hit) = each %{ $query_res } ) { @@ -1054,11 +1064,15 @@ sub msg_to_decrypt { my $done = 0; my $sql; my $res; + # check whether this message should be processed here if ($error == 0) { $header = @{$msg_hash->{'header'}}[0]; $target = @{$msg_hash->{'target'}}[0]; $source = @{$msg_hash->{'source'}}[0]; + my $not_found_in_known_clients_db = 0; + my $not_found_in_known_server_db = 0; + my $not_found_in_foreign_clients_db = 0; my $local_address; my ($target_ip, $target_port) = split(':', $target); if ($target =~ /^\d+\.\d+\.\d+\.\d+:\d+$/) { @@ -1081,22 +1095,24 @@ sub msg_to_decrypt { if ($source eq "GOSA") { $msg =~ s/<\/xml>/$local_address,$session_id<\/forward_to_gosa><\/xml>/; } - print STDERR "target is own address without forward_to_gosa-tag -> process here\n"; + #print STDERR "target is own address without forward_to_gosa-tag -> process here\n"; } } # target is a client address in known_clients -> process here - if (not $done) { - $sql = "SELECT * FROM $known_clients_tn WHERE (hostname='$target' OR macaddress LIKE '$target')"; - $res = $known_clients_db->select_dbentry($sql); - if (keys(%$res) > 0) { - $done = 1; - my $hostname = $res->{1}->{'hostname'}; - $msg =~ s/$target<\/target>/$hostname<\/target>/; - print STDERR "target is a client address in known_clients -> process here\n"; - } - } - + if (not $done) { + $sql = "SELECT * FROM $known_clients_tn WHERE (hostname='$target' OR macaddress LIKE '$target')"; + $res = $known_clients_db->select_dbentry($sql); + if (keys(%$res) > 0) { + $done = 1; + my $hostname = $res->{1}->{'hostname'}; + $msg =~ s/$target<\/target>/$hostname<\/target>/; + #print STDERR "target is a client address in known_clients -> process here\n"; + } else { + $not_found_in_known_clients_db = 1; + } + } + # target ist own address with forward_to_gosa-tag not pointing to myself -> process here if (not $done) { my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0]; @@ -1106,31 +1122,29 @@ sub msg_to_decrypt { my ($gosa_at, $gosa_session_id) = split(/,/, $forward_to_gosa); if ($gosa_at ne $local_address) { $done = 1; - print STDERR "target is own address with forward_to_gosa-tag not pointing to myself -> process here\n"; + #print STDERR "target is own address with forward_to_gosa-tag not pointing to myself -> process here\n"; } } } # if message should be processed here -> add message to incoming_db - if ($done) { - - # if a job or a gosa message comes from a foreign server, fake module to GosaPackages - # so gosa-si-server knows how to process this kind of messages - if ($header =~ /^gosa_/ || $header =~ /job_/) { - $module = "GosaPackages"; - } - - my $res = $incoming_db->add_dbentry( {table=>$incoming_tn, - primkey=>[], - headertag=>$header, - targettag=>$target, - xmlmessage=>&encode_base64($msg), - timestamp=>&get_time, - module=>$module, - sessionid=>$session_id, - } ); + if ($done) { + # if a job or a gosa message comes from a foreign server, fake module to GosaPackages + # so gosa-si-server knows how to process this kind of messages + if ($header =~ /^gosa_/ || $header =~ /^job_/) { + $module = "GosaPackages"; + } - } + my $res = $incoming_db->add_dbentry( {table=>$incoming_tn, + primkey=>[], + headertag=>$header, + targettag=>$target, + xmlmessage=>&encode_base64($msg), + timestamp=>&get_time, + module=>$module, + sessionid=>$session_id, + } ); + } # target is own address with forward_to_gosa-tag pointing at myself -> forward to gosa if (not $done) { @@ -1149,7 +1163,7 @@ sub msg_to_decrypt { $heap->{'client'}->put($msg); } $done = 1; - print STDERR "target is own address with forward_to_gosa-tag pointing at myself -> forward to gosa\n"; + #print STDERR "target is own address with forward_to_gosa-tag pointing at myself -> forward to gosa\n"; } } @@ -1160,7 +1174,9 @@ sub msg_to_decrypt { $sql = "SELECT * FROM $foreign_clients_tn WHERE (hostname='$target' OR macaddress LIKE '$target')"; $res = $foreign_clients_db->select_dbentry($sql); if (keys(%$res) > 0) { - my $hostname = $res->{1}->{'hostname'}; + my $hostname = $res->{1}->{'hostname'}; + my ($host_ip, $host_port) = split(/:/, $hostname); + my $local_address = &get_local_ip_for_remote_ip($host_ip).":$server_port"; my $regserver = $res->{1}->{'regserver'}; my $sql = "SELECT * FROM $known_server_tn WHERE hostname='$regserver'"; my $res = $known_server_db->select_dbentry($sql); @@ -1174,8 +1190,10 @@ sub msg_to_decrypt { &send_msg_to_target($msg, $regserver, $regserver_key, $header, $session_id); } $done = 1; - print STDERR "target is a client address in foreign_clients -> forward to registration server\n"; - } + #print STDERR "target is a client address in foreign_clients -> forward to registration server\n"; + } else { + $not_found_in_foreign_clients_db = 1; + } } # target is a server address -> forward to server @@ -1193,11 +1211,29 @@ sub msg_to_decrypt { &send_msg_to_target($msg, $target, $hostkey, $header, $session_id); $done = 1; - print STDERR "target is a server address -> forward to server\n"; - } + #print STDERR "target is a server address -> forward to server\n"; + } else { + $not_found_in_known_server_db = 1; + } + } + + # target is not in foreign_clients_db, known_server_db or known_clients_db, maybe it is a complete new one -> process here + if ( $not_found_in_foreign_clients_db + && $not_found_in_known_server_db + && $not_found_in_known_clients_db) { + my $res = $incoming_db->add_dbentry( {table=>$incoming_tn, + primkey=>[], + headertag=>$header, + targettag=>$target, + xmlmessage=>&encode_base64($msg), + timestamp=>&get_time, + module=>$module, + sessionid=>$session_id, + } ); + $done = 1; + } - } if (not $done) { daemon_log("$session_id ERROR: do not know what to do with this message: $msg", 1); @@ -1265,6 +1301,7 @@ sub handle_task_done { sub process_task { no strict "refs"; + #CHECK: Not @_[...]? my ($session, $heap, $task) = @_; my $error = 0; my $answer_l; @@ -1313,7 +1350,7 @@ sub process_task { foreach my $answer ( @{$answer_l} ) { # check outgoing msg to xml validity - my $answer_hash = &check_outgoing_xml_validity($answer); + my $answer_hash = &check_outgoing_xml_validity($answer, $session_id); if( not defined $answer_hash ) { next; } $answer_header = @{$answer_hash->{'header'}}[0]; @@ -1426,21 +1463,24 @@ sub session_start { $kernel->yield('create_fai_release_db', $fai_release_tn ); $kernel->yield('watch_for_next_tasks'); $kernel->sig(USR1 => "sig_handler"); - $kernel->sig(USR2 => "create_packages_list_db"); + $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); + $kernel->delay_set('watch_for_modified_jobs', $modified_jobs_loop_delay); $kernel->delay_set('watch_for_new_messages', $messaging_db_loop_delay); $kernel->delay_set('watch_for_delivery_messages', $messaging_db_loop_delay); $kernel->delay_set('watch_for_done_messages', $messaging_db_loop_delay); $kernel->delay_set('watch_for_old_known_clients', $job_queue_loop_delay); + } sub watch_for_done_jobs { + #CHECK: $heap for what? my ($kernel,$heap) = @_[KERNEL, HEAP]; - my $sql_statement = "SELECT * FROM ".$job_queue_tn." WHERE status='done'"; + 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} ) { @@ -1453,12 +1493,40 @@ sub watch_for_done_jobs { } +# if a job got an update or was modified anyway, send to all other si-server an update message +# of this jobs +sub watch_for_modified_jobs { + my ($kernel,$heap) = @_[KERNEL, HEAP]; + + my $sql_statement = "SELECT * FROM $job_queue_tn WHERE ((siserver='localhost') AND (modified='1'))"; + my $res = $job_db->select_dbentry( $sql_statement ); + + # if db contains no jobs which should be update, do nothing + if (keys %$res != 0) { + + if ($job_synchronization eq "true") { + # make out of the db result a gosa-si message + my $update_msg = &db_res2si_msg ($res, "foreign_job_updates", "KNOWN_SERVER", "MY_LOCAL_ADDRESS"); + + # update all other SI-server + &inform_all_other_si_server($update_msg); + } + + # set jobs all jobs to modified = 0, wait until the next modification for updates of other si-server + $sql_statement = "UPDATE $job_queue_tn SET modified='0' "; + $res = $job_db->update_dbentry($sql_statement); + } + + $kernel->delay_set('watch_for_modified_jobs', $modified_jobs_loop_delay); +} + + sub watch_for_new_jobs { if($watch_for_new_jobs_in_progress == 0) { $watch_for_new_jobs_in_progress = 1; my ($kernel,$heap) = @_[KERNEL, HEAP]; - # check gosa job queue for jobs with executable timestamp + # check gosa job quaeue for jobs with executable timestamp my $timestamp = &get_time(); my $sql_statement = "SELECT * FROM $job_queue_tn WHERE status='waiting' AND (CAST (timestamp AS INTEGER)) < $timestamp ORDER BY timestamp"; my $res = $job_db->exec_statement( $sql_statement ); @@ -1549,6 +1617,7 @@ sub watch_for_new_jobs { } + sub watch_for_new_messages { my ($kernel,$heap) = @_[KERNEL, HEAP]; my @coll_user_msg; # collection list of outgoing messages @@ -1777,7 +1846,7 @@ sub watch_for_next_tasks { my $res = $incoming_db->exec_statement($sql); } - $kernel->delay_set('watch_for_next_tasks', 1); + $kernel->delay_set('watch_for_next_tasks', 0.1); } @@ -1792,7 +1861,7 @@ sub get_ldap_handle { if ($session_id == 0) { daemon_log("$session_id DEBUG: get_ldap_handle invoked without a session_id, create a new ldap_handle", 7); $ldap_handle = Net::LDAP->new( $ldap_uri ); - $ldap_handle->bind($ldap_admin_dn, password => $ldap_admin_password); + $ldap_handle->bind($ldap_admin_dn, password => $ldap_admin_password) or daemon_log("$session_id ERROR: Bind to LDAP $ldap_uri as $ldap_admin_dn failed!"); } else { my $session_reference = $global_kernel->ID_id_to_session($session_id); @@ -1809,7 +1878,7 @@ sub get_ldap_handle { # used handle is still valid - or if we've to reconnect... #if (not exists $heap->{ldap_handle}) { $ldap_handle = Net::LDAP->new( $ldap_uri ); - $ldap_handle->bind($ldap_admin_dn, password => $ldap_admin_password); + $ldap_handle->bind($ldap_admin_dn, password => $ldap_admin_password) or daemon_log("$session_id ERROR: Bind to LDAP $ldap_uri as $ldap_admin_dn failed!"); $heap->{ldap_handle} = $ldap_handle; #} } @@ -1962,13 +2031,23 @@ sub change_goto_state { } } } else { - daemon_log("$session_id ERROR: LDAP search failed: ldap_base=$ldap_base, filter=$search", 1); + daemon_log("$session_id ERROR: LDAP search failed in function change_goto_state: ldap_base=$ldap_base, filter=$search", 1); } } } +sub run_recreate_packages_db { + my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; + my $session_id = $session->ID; + &main::daemon_log("$session_id INFO: Recreating FAI Packages DB ('$fai_release_tn', '$fai_server_tn', '$packages_list_tn')", 5); + $kernel->yield('create_fai_release_db', $fai_release_tn); + $kernel->yield('create_fai_server_db', $fai_server_tn); + return; +} + + sub run_create_fai_server_db { my ($kernel, $session, $heap, $table_name) = @_[KERNEL, SESSION, HEAP, ARG0]; my $session_id = $session->ID; @@ -2695,7 +2774,6 @@ sub parse_package { close( $PACKAGES ); unlink( "$path.in" ); - &main::daemon_log("$session_id DEBUG: unlink '$path.in'", 1); } @@ -2939,6 +3017,11 @@ daemon_log("0 INFO: found foreign server in config file and DNS: $all_foreign_se # add all found foreign servers to known_server my $act_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, @@ -2949,6 +3032,12 @@ foreach my $foreign_server (@foreign_server_list) { } +# import all modules +&import_modules; +# check wether all modules are gosa-si valid passwd check +&password_check; + + POE::Component::Server::TCP->new( Alias => "TCP_SERVER", Port => $server_port, @@ -2985,11 +3074,13 @@ POE::Session->create( watch_for_delivery_messages => \&watch_for_delivery_messages, watch_for_done_messages => \&watch_for_done_messages, watch_for_new_jobs => \&watch_for_new_jobs, + watch_for_modified_jobs => \&watch_for_modified_jobs, watch_for_done_jobs => \&watch_for_done_jobs, watch_for_old_known_clients => \&watch_for_old_known_clients, create_packages_list_db => \&run_create_packages_list_db, create_fai_server_db => \&run_create_fai_server_db, create_fai_release_db => \&run_create_fai_release_db, + recreate_packages_db => \&run_recreate_packages_db, session_run_result => \&session_run_result, session_run_debug => \&session_run_debug, session_run_done => \&session_run_done, @@ -2998,14 +3089,6 @@ POE::Session->create( ); -# import all modules -&import_modules; - -# TODO -# check wether all modules are gosa-si valid passwd check - - - POE::Kernel->run(); exit;