diff --git a/gosa-si/gosa-si-server b/gosa-si/gosa-si-server
index ca826949bf5d726bd8b37cb1b349ec577244efee..1e56d7ce7066ed3b9cdf0f9ae743cc7880d81eb5 100755 (executable)
--- a/gosa-si/gosa-si-server
+++ b/gosa-si/gosa-si-server
#!/usr/bin/perl
#===============================================================================
#
-# FILE: gosa-sd
+# FILE: gosa-si-server
#
-# USAGE: ./gosa-sd
+# USAGE: ./gosa-si-server
#
# DESCRIPTION:
#
# REVISION: ---
#===============================================================================
-
-# TODO
-#
-# max_children wird momentan nicht mehr verwendet, jede eingehende nachricht bekommt ein eigenes POE child
-
use strict;
use warnings;
use Getopt::Long;
use Config::IniFiles;
use POSIX;
-use Fcntl;
+use Fcntl qw/:flock/;
use IO::Socket::INET;
use IO::Handle;
use IO::Select;
use XML::Simple;
use Data::Dumper;
use Sys::Syslog qw( :DEFAULT setlogsock);
+use Time::HiRes qw( usleep clock_gettime );
use Cwd;
use File::Spec;
use File::Basename;
use File::Find;
use File::Copy;
use File::Path;
-use GOSA::DBmysql;
use GOSA::GosaSupportDaemon;
use POE qw(Component::Server::TCP Wheel::Run Filter::Reference);
use Net::LDAP;
use Net::LDAP::Util qw(:escape);
-use Time::HiRes qw( usleep);
-my $modules_path = "/usr/lib/gosa-si/modules";
-use lib "/usr/lib/gosa-si/modules";
+my $server_version = '$HeadURL: https://oss.gonicus.de/repositories/gosa/trunk/gosa-si/gosa-si-server $:$Rev$';
# revision number of server and program name
-my $server_version = '$HeadURL: https://oss.gonicus.de/repositories/gosa/trunk/gosa-si/gosa-si-server $:$Rev: 10826 $';
my $server_headURL;
my $server_revision;
my $server_status;
our $prg= basename($0);
+our $verbose= 0;
+
+my $db_module = "DBsqlite";
+{
+no strict "refs";
+require ("GOSA/".$db_module.".pm");
+("GOSA/".$db_module)->import;
+}
+
+my $modules_path = "/usr/lib/gosa-si/modules";
+use lib "/usr/lib/gosa-si/modules";
our $global_kernel;
my ($foreground, $ping_timeout);
my ($gosa_server, $job_queue_timeout, $job_queue_loop_delay);
my ($messaging_db_loop_delay);
my ($procid, $pid);
-my ($arp_fifo);
+my $arp_fifo;
+my $debug_parts = 0;
+my $debug_parts_bitstring;
my ($xml);
my $sources_list;
my $max_clients;
$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
our $server_mac_address;
our $gosa_address;
our $no_arp;
-our $verbose;
our $forground;
our $cfg_file;
-our ($ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password, $ldap_server_dn);
+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;
our $root_uid;
our $adm_gid;
-
-# specifies the verbosity of the daemon_log
-$verbose = 0 ;
-
# if foreground is not null, script will be not forked to background
$foreground = 0 ;
our $incoming_db;
our $incoming_tn = 'incoming';
my $incoming_file_name;
-my @incoming_col_names = ("id INTEGER PRIMARY KEY auto_increment",
+my @incoming_col_names = ("id INTEGER PRIMARY KEY",
"timestamp VARCHAR(14) DEFAULT 'none'",
"headertag VARCHAR(255) DEFAULT 'none'",
"targettag VARCHAR(255) DEFAULT 'none'",
our $job_db;
our $job_queue_tn = 'jobs';
my $job_queue_file_name;
-my @job_queue_col_names = ("id INTEGER PRIMARY KEY auto_increment",
+my @job_queue_col_names = ("id INTEGER PRIMARY KEY",
"timestamp VARCHAR(14) DEFAULT 'none'",
"status VARCHAR(255) DEFAULT 'none'",
"result TEXT",
"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
our $known_server_db;
our $known_server_tn = "known_server";
my $known_server_file_name;
-my @known_server_col_names = ("hostname VARCHAR(255)", "macaddress VARCHAR(17)", "status VARCHAR(255)", "hostkey VARCHAR(255)", "loaded_modules TEXT", "timestamp VARCHAR(14)");
+my @known_server_col_names = ("hostname VARCHAR(255)", "macaddress VARCHAR(17)", "status VARCHAR(255)", "hostkey VARCHAR(255)", "loaded_modules TEXT", "timestamp VARCHAR(14)", "update_time VARCHAR(14)");
# holds all registrated clients
our $known_clients_db;
@@ -173,7 +176,7 @@ my @foreign_clients_col_names = ("hostname VARCHAR(255)", "macaddress VARCHAR(17
our $login_users_db;
our $login_users_tn = "login_users";
my $login_users_file_name;
-my @login_users_col_names = ("client VARCHAR(255)", "user VARCHAR(255)", "timestamp VARCHAR(14)");
+my @login_users_col_names = ("client VARCHAR(255)", "user VARCHAR(255)", "timestamp VARCHAR(14)", "regserver VARCHAR(255) DEFAULT 'localhost'");
# holds all fai server, the debian release and tag
our $fai_server_db;
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;
our $client_fai_log_dir = "/var/log/fai";
# queue which stores taskes until one of the $max_children children are ready to process the task
-my @tasks = qw();
+#my @tasks = qw();
my @msgs_to_decrypt = qw();
my $max_children = 2;
# of this, the user is deleted from login_users_db
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" => {
"messaging" => [\$messaging_file_name, '/var/lib/gosa-si/messaging.db'],
"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'],
+ "repo-path" => [\$repo_path, '/srv/www'],
+ "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" => {
#===============================================================================
sub usage {
print STDERR << "EOF" ;
-usage: $prg [-hvf] [-c config]
+usage: $prg [-hvf] [-c config] [-d number]
-h : this (help) message
-c <file> : config file
-f : foreground, process will not be forked to background
-v : be verbose (multiple to increase verbosity)
+ 'v': error logs
+ 'vvv': warning plus error logs
+ 'vvvvv': info plus warning logs
+ 'vvvvvvv': debug plus info logs
-no-arp : starts $prg without connection to arp module
-
+ -d <int> : if verbose level is higher than 7x 'v' specified parts can be debugged
+ 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);
}
# DESCRIPTION: function for logging
#===============================================================================
sub daemon_log {
- # 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");
- if(not defined open( LOG_HANDLE, ">>$log_file" )) {
- print STDERR "cannot open $log_file: $!";
- return
- }
- chomp($msg);
- #$msg =~s/\n//g; # no newlines are allowed in log messages, this is important for later log parsing
- 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 $name = $prg;
-
- my $log_msg = "$month $monthday $hours:$minutes:$seconds $name $msg\n";
- print LOG_HANDLE $log_msg;
- if( $foreground ) {
- print STDERR $log_msg;
- }
- }
- close( LOG_HANDLE );
- }
+ if (not defined $msg) { return }
+ if (not defined $level) { $level = 1 }
+ my $to_be_logged = 0;
+
+ # Write log line if line level is lower than verbosity given in commandline
+ if ($level <= $verbose)
+ {
+ $to_be_logged = 1 ;
+ }
+
+ # Write if debug flag is set and bitstring matches
+ if ($debug_parts > 0)
+ {
+ my $tmp_level = ($level - 10 >= 0) ? $level - 10 : 0 ;
+ my $tmp_level_bitstring = unpack("B32", pack("N", $tmp_level));
+ if (int($debug_parts_bitstring & $tmp_level_bitstring))
+ {
+ $to_be_logged = 1;
+ }
+ }
+
+ if ($to_be_logged)
+ {
+ if(defined $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;
+ }
+ # 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);
+ }
+
+ # Prepare time string for log message
+ 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;
+ $month = $monthnames[$month];
+ $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$microSeconds $prg $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;
+ }
+ close( LOG_HANDLE );
+ }
+ }
}
# DESCRIPTION: validates commandline parameter
#===============================================================================
sub check_cmdline_param () {
- my $err_config;
my $err_counter = 0;
+
+ # Check configuration file
if(not defined($cfg_file)) {
$cfg_file = "/etc/gosa-si/server.conf";
if(! -r $cfg_file) {
- $err_config = "please specify a config file";
- $err_counter += 1;
+ print STDERR "Please specify a config file.\n";
+ $err_counter++;
}
}
- if( $err_counter > 0 ) {
- &usage( "", 1 );
- if( defined( $err_config)) { print STDERR "$err_config\n"}
- print STDERR "\n";
- exit( -1 );
- }
+
+ # Prepare identification which gosa-si parts should be debugged and which not
+ if (defined $debug_parts)
+ {
+ if ($debug_parts =~ /^\d+$/)
+ {
+ $debug_parts_bitstring = unpack("B32", pack("N", $debug_parts));
+ }
+ else
+ {
+ print STDERR "Value '$debug_parts' invalid for option d (number expected)\n";
+ $err_counter++;
+ }
+ }
+
+ # Exit if an error occour
+ if( $err_counter > 0 ) { &usage( "", 1 ); }
}
sub check_pid {
$pid = -1;
# Check, if we are already running
- if( open(LOCK_FILE, "<$pid_file") ) {
- $pid = <LOCK_FILE>;
+ if( open( my $LOCK_FILE, "<", "$pid_file" ) ) {
+ $pid = <$LOCK_FILE>;
if( defined $pid ) {
chomp( $pid );
if( -f "/proc/$pid/stat" ) {
my($stat) = `cat /proc/$pid/stat` =~ m/$pid \((.+)\).*/;
if( $stat ) {
- daemon_log("ERROR: Already running",1);
- close( LOCK_FILE );
+ print STDERR "\nERROR: Already running!\n";
+ close( $LOCK_FILE );
exit -1;
}
}
}
- close( LOCK_FILE );
+ close( $LOCK_FILE );
unlink( $pid_file );
}
# create a syslog msg if it is not to possible to open PID file
- if (not sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
+ if (not sysopen(my $LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
my($msg) = "Couldn't obtain lockfile '$pid_file' ";
- if (open(LOCK_FILE, '<', $pid_file)
- && ($pid = <LOCK_FILE>))
+ if (open(my $LOCK_FILE, '<', $pid_file)
+ && ($pid = <$LOCK_FILE>))
{
chomp($pid);
$msg .= "(PID $pid)\n";
# state is on is imported by "require 'file';"
#===============================================================================
sub import_modules {
- daemon_log(" ", 1);
-
if (not -e $modules_path) {
daemon_log("0 ERROR: cannot find directory or directory is not readable: $modules_path", 1);
}
opendir (DIR, $modules_path) or die "ERROR while loading modules from directory $modules_path : $!\n";
+
while (defined (my $file = readdir (DIR))) {
if (not $file =~ /(\S*?).pm$/) {
next;
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 ($@) {
daemon_log("0 ERROR: gosa-si-server could not load module $file", 1);
- daemon_log("$@", 5);
+ daemon_log("$@", 1);
+ exit;
} else {
my $info = eval($mod_name.'::get_module_info()');
# Only load module if get_module_info() returns a non-null object
}
}
}
-
close (DIR);
}
if ($msg =~ /<xml>/i){
$msg =~ s/\s+/ /g; # just for better daemon_log
- daemon_log("$session_id DEBUG: decrypted_msg: \n$msg", 8);
+ daemon_log("$session_id DEBUG: decrypted_msg: \n$msg", 18);
$msg_hash = $xml->XMLin($msg, ForceArray=>1);
##############
# check header
if( not exists $msg_hash->{'header'} ) { die "no header specified"; }
my $header_l = $msg_hash->{'header'};
- if( 1 > @{$header_l} ) { die 'empty header tag'; }
+ if( (1 > @{$header_l}) || ( ( 'HASH' eq ref @{$header_l}[0]) && (1 > keys %{@{$header_l}[0]}) ) ) { die 'empty header tag'; }
if( 1 < @{$header_l} ) { die 'more than one header specified'; }
my $header = @{$header_l}[0];
if( 0 == length $header) { die 'empty string in header tag'; }
# check source
if( not exists $msg_hash->{'source'} ) { die "no source specified"; }
my $source_l = $msg_hash->{'source'};
- if( 1 > @{$source_l} ) { die 'empty source tag'; }
+ if( (1 > @{$source_l}) || ( ( 'HASH' eq ref @{$source_l}[0]) && (1 > keys %{@{$source_l}[0]}) ) ) { die 'empty source tag'; }
if( 1 < @{$source_l} ) { die 'more than one source specified'; }
my $source = @{$source_l}[0];
if( 0 == length $source) { die 'source error'; }
# check target
if( not exists $msg_hash->{'target'} ) { die "no target specified"; }
my $target_l = $msg_hash->{'target'};
- if( 1 > @{$target_l} ) { die 'empty target tag'; }
+ if( (1 > @{$target_l}) || ( ('HASH' eq ref @{$target_l}[0]) && (1 > keys %{@{$target_l}[0]}) ) ) { die 'empty target tag'; }
}
};
if($@) {
if( 0 == length $source) {
die 'source has length 0';
}
+
+ # 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>$source<\/source>/;
+ }
+ }
unless( $source =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$/ ||
- $source =~ /^GOSA$/i ) {
+ $source =~ /^GOSA$/i) {
die "source '$source' is neither a complete ip-address with port nor 'GOSA'";
}
$msg_hash = undef;
}
- return ($msg_hash);
+ return ($msg, $msg_hash);
}
next;
}
my $host_key = $hit->{hostkey};
- daemon_log("$session_id DEBUG: input_from_known_server: host_name: $host_name", 7);
- daemon_log("$session_id DEBUG: input_from_known_server: host_key: $host_key", 7);
+ daemon_log("$session_id DEBUG: input_from_known_server: host_name: $host_name", 14);
+ daemon_log("$session_id DEBUG: input_from_known_server: host_key: $host_key", 14);
# check if module can open msg envelope with module key
my ($tmp_msg, $tmp_msg_hash) = &check_key_and_xml_validity($input, $host_key, $session_id);
if( (!$tmp_msg) || (!$tmp_msg_hash) ) {
- daemon_log("$session_id DEBUG: input_from_known_server: deciphering raise error", 7);
- daemon_log("$@", 8);
+ daemon_log("$session_id DEBUG: input_from_known_server: deciphering raise error", 14);
+ daemon_log("$@", 14);
next;
}
else {
$msg = $tmp_msg;
$msg_hash = $tmp_msg_hash;
$module = "ServerPackages";
+ daemon_log("$session_id DEBUG: check_key_and_xml_validity... ok", 14);
last;
}
}
if( (!$msg) || (!$msg_hash) || (!$module) ) {
- daemon_log("$session_id DEBUG: Incoming message is not from a known server", 7);
+ daemon_log("$session_id DEBUG: Incoming message is not from a known server", 14);
}
return ($msg, $msg_hash, $module);
my $query_res = $known_clients_db->select_dbentry( $sql_statement );
while( my ($hit_num, $hit) = each %{ $query_res } ) {
my $host_name = $hit->{hostname};
- if( not $host_name =~ /^$remote_ip:\d*$/) {
+ if( not $host_name =~ /^$remote_ip/) {
next;
}
my $host_key = $hit->{hostkey};
- &daemon_log("$session_id DEBUG: input_from_known_client: host_name: $host_name", 7);
- &daemon_log("$session_id DEBUG: input_from_known_client: host_key: $host_key", 7);
+ &daemon_log("$session_id DEBUG: input_from_known_client: host_name: $host_name", 14);
+ &daemon_log("$session_id DEBUG: input_from_known_client: host_key: $host_key", 14);
# check if module can open msg envelope with module key
($msg, $msg_hash) = &check_key_and_xml_validity($input, $host_key, $session_id);
if( (!$msg) || (!$msg_hash) ) {
- &daemon_log("$session_id DEGUG: input_from_known_client: deciphering raise error", 7);
- &daemon_log("$@", 8);
+ &daemon_log("$session_id DEGUG: input_from_known_client: deciphering raise error", 14);
next;
}
else {
$module = "ClientPackages";
+ daemon_log("$session_id DEBUG: check_key_and_xml_validity... ok", 14);
last;
}
}
if( (!$msg) || (!$msg_hash) || (!$module) ) {
- &daemon_log("$session_id DEBUG: Incoming message is not from a known client", 7);
+ &daemon_log("$session_id DEBUG: Incoming message is not from a known client", 14);
}
return ($msg, $msg_hash, $module);
daemon_log("$session_id ERROR: no key specified in config file for $mod", 1);
next;
}
- daemon_log("$session_id DEBUG: $mod: $module_key", 7);
+ daemon_log("$session_id DEBUG: $mod: $module_key", 14);
# check if module can open msg envelope with module key
($msg, $msg_hash) = &check_key_and_xml_validity($input, $module_key, $session_id);
next;
} else {
$module = $mod;
+ daemon_log("$session_id DEBUG: check_key_and_xml_validity... ok", 18);
last;
}
}
if( (!$msg) || (!$msg_hash) || (!$module)) {
- daemon_log("$session_id DEBUG: Incoming message is not from an unknown host", 7);
+ daemon_log("$session_id DEBUG: Incoming message is not from an unknown host", 14);
}
return ($msg, $msg_hash, $module);
}
-#sub get_local_ip_for_remote_ip {
-# my $remote_ip= shift;
-# my $result="0.0.0.0";
-#
-# if($remote_ip =~ /^(\d\d?\d?\.){3}\d\d?\d?$/) {
-# if($remote_ip eq "127.0.0.1") {
-# $result = "127.0.0.1";
-# } else {
-# my $PROC_NET_ROUTE= ('/proc/net/route');
-#
-# open(PROC_NET_ROUTE, "<$PROC_NET_ROUTE")
-# or die "Could not open $PROC_NET_ROUTE";
-#
-# my @ifs = <PROC_NET_ROUTE>;
-#
-# close(PROC_NET_ROUTE);
-#
-# # Eat header line
-# shift @ifs;
-# chomp @ifs;
-# foreach my $line(@ifs) {
-# my ($Iface,$Destination,$Gateway,$Flags,$RefCnt,$Use,$Metric,$Mask,$MTU,$Window,$IRTT)=split(/\s/, $line);
-# my $destination;
-# my $mask;
-# my ($d,$c,$b,$a)=unpack('a2 a2 a2 a2', $Destination);
-# $destination= sprintf("%d.%d.%d.%d", hex($a), hex($b), hex($c), hex($d));
-# ($d,$c,$b,$a)=unpack('a2 a2 a2 a2', $Mask);
-# $mask= sprintf("%d.%d.%d.%d", hex($a), hex($b), hex($c), hex($d));
-# if(new NetAddr::IP($remote_ip)->within(new NetAddr::IP($destination, $mask))) {
-# # destination matches route, save mac and exit
-# $result= &get_ip($Iface);
-# last;
-# }
-# }
-# }
-# } else {
-# daemon_log("0 WARNING: get_local_ip_for_remote_ip() was called with a non-ip parameter: '$remote_ip'", 1);
-# }
-# return $result;
-#}
-
-
sub send_msg_to_target {
my ($msg, $address, $encrypt_key, $msg_header, $session_id) = @_ ;
my $error = 0;
$header = "";
}
- # Patch the source ip
- if($msg =~ /<source>0\.0\.0\.0:\d*?<\/source>/) {
- my $remote_ip = &get_local_ip_for_remote_ip(sprintf("%s", $address =~ /^([0-9\.]*?):.*$/));
- $msg =~ s/<source>(0\.0\.0\.0):(\d*?)<\/source>/<source>$remote_ip:$2<\/source>/s;
- }
+ # Memorize own source address
+ my $own_source_address = &get_local_ip_for_remote_ip(sprintf("%s", $address =~ /^([0-9\.]*?):.*$/));
+ $own_source_address .= ":".$server_port;
+
+ # Patch 0.0.0.0 source to real address
+ $msg =~ s/<source>(0\.0\.0\.0):(\d*?)<\/source>/<source>$own_source_address<\/source>/s;
+ # Patch GOSA source to real address and add forward_to_gosa tag
+ $msg =~ s/<source>GOSA<\/source>/<source>$own_source_address<\/source> <forward_to_gosa>$own_source_address,$session_id<\/forward_to_gosa>/ ;
# encrypt xml msg
my $crypted_msg = &encrypt_msg($msg, $encrypt_key);
# opensocket
my $socket = &open_socket($address);
if( !$socket ) {
- daemon_log("$session_id WARNING: cannot send ".$header."msg to $address , host not reachable", 3);
+ daemon_log("$session_id ERROR: Cannot open socket to host '$address'. Message processing aborted!", 1);
$error++;
}
if( $error == 0 ) {
# send xml msg
- print $socket $crypted_msg."\n";
-
+ print $socket $crypted_msg.";$own_source_address\n";
daemon_log("$session_id INFO: send ".$header."msg to $address", 5);
- daemon_log("$session_id DEBUG: message:\n$msg", 9);
+ daemon_log("$session_id DEBUG: message:\n$msg", 12);
}
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);
}
}
}
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);
}
}
}
sub update_jobdb_status_for_send_msgs {
- my ($answer, $error) = @_;
+ my ($session_id, $answer, $error) = @_;
if( $answer =~ /<jobdb_id>(\d+)<\/jobdb_id>/ ) {
+ &daemon_log("$session_id DEBUG: try to update job status", 138);
my $jobdb_id = $1;
+
+ $answer =~ /<header>(.*)<\/header>/;
+ my $job_header = $1;
+
+ $answer =~ /<target>(.*)<\/target>/;
+ my $job_target = $1;
- # sending msg faild
+ # Sending msg failed
if( $error ) {
- if (not $answer =~ /<header>trigger_action_reinstall<\/header>/) {
+
+ # Set jobs to done, jobs do not need to deliver their message in any case
+ if (($job_header eq "trigger_action_localboot")
+ ||($job_header eq "trigger_action_lock")
+ ||($job_header eq "trigger_action_halt")
+ ) {
+ my $sql_statement = "UPDATE $job_queue_tn SET status='done' WHERE id=$jobdb_id";
+ my $res = $job_db->update_dbentry($sql_statement);
+
+ # Reactivate jobs, jobs need to deliver their message
+ } elsif (($job_header eq "trigger_action_activate")
+ ||($job_header eq "trigger_action_update")
+ ||($job_header eq "trigger_action_reinstall")
+ ||($job_header eq "trigger_activate_new")
+ ) {
+ 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";
my $res = $job_db->update_dbentry($sql_statement);
}
- # sending msg was successful
+ # Sending msg was successful
} else {
- my $sql_statement = "UPDATE $job_queue_tn ".
- "SET status='done' ".
- "WHERE id=$jobdb_id AND status='processed'";
- my $res = $job_db->update_dbentry($sql_statement);
- }
+ # Set jobs localboot, lock, activate, halt, reboot and wake to done
+ # jobs reinstall, update, inst_update do themself setting to done
+ if (($job_header eq "trigger_action_localboot")
+ ||($job_header eq "trigger_action_lock")
+ ||($job_header eq "trigger_action_activate")
+ ||($job_header eq "trigger_action_halt")
+ ||($job_header eq "trigger_action_reboot")
+ ||($job_header eq "trigger_action_wake")
+ ||($job_header eq "trigger_wake")
+ ) {
+
+ my $sql_statement = "UPDATE $job_queue_tn ".
+ "SET status='done' ".
+ "WHERE id=$jobdb_id AND status='processed'";
+ my $res = $job_db->update_dbentry($sql_statement);
+ } else {
+ &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.", 138);
}
}
+sub reactivate_job_with_delay {
+ my ($session_id, $target, $header, $delay) = @_ ;
+ # Sometimes the client is still booting or does not wake up, in this case reactivate the job (if it exists) with a delay of n sec
+
+ 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' 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);
+ return;
+}
+
sub sig_handler {
my ($kernel, $signal) = @_[KERNEL, ARG0] ;
my ($msg, $msg_hash, $module);
my $error = 0;
- # hole neue msg aus @msgs_to_decrypt
- my $next_msg = shift @msgs_to_decrypt;
-
- # entschlüssle sie
+ # fetch new msg out of @msgs_to_decrypt
+ my $tmp_next_msg = shift @msgs_to_decrypt;
+ my ($next_msg, $msg_source) = split(/;/, $tmp_next_msg);
# msg is from a new client or gosa
($msg, $msg_hash, $module) = &input_from_unknown_host($next_msg, $session_id);
+
# msg is from a gosa-si-server
- if(( !$msg ) || ( !$msg_hash ) || ( !$module )){
- ($msg, $msg_hash, $module) = &input_from_known_server($next_msg, $heap->{'remote_ip'}, $session_id);
+ 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
+ ($msg, $msg_hash, $module) = &input_from_known_server($next_msg, $heap->{'remote_ip'}, $session_id);
+ }
+ else
+ {
+ ($msg, $msg_hash, $module) = &input_from_known_server($next_msg, $msg_source, $session_id);
+ }
}
# msg is from a gosa-si-client
if(( !$msg ) || ( !$msg_hash ) || ( !$module )){
- ($msg, $msg_hash, $module) = &input_from_known_client($next_msg, $heap->{'remote_ip'}, $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 )){
- # 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 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 } ) {
- my $host_name = $hit->{'hostname'};
- my $host_key = $hit->{'hostkey'};
- my $ping_msg = "<xml> <header>gosa_ping</header> <source>$server_address</source> <target>$host_name</target></xml>";
- my $error = &send_msg_to_target($ping_msg, $host_name, $host_key, "gosa_ping", $session_id);
- &update_jobdb_status_for_send_msgs($ping_msg, $error);
+ # If an incoming msg could not be decrypted (maybe a wrong key), decide if msg comes from a client
+ # 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$/ && $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'";
+ daemon_log("$session_id DEBUG: $update_statement", 7);
+ my $upadte_res = $known_server_db->exec_statement($update_statement);
+ $kernel->yield("register_at_foreign_servers");
+ }
+ 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 = "<xml> <header>gosa_ping</header> <source>$server_address</source><target>$msg_source</target></xml>";
+ 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);
+ }
+ 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!", 1);
+ daemon_log("$session_id DEBUG: Aborted message: $tmp_next_msg", 11);
}
- $error++;
+
+ $error++
}
if (not $done) {
if ($target eq "GOSA" && $source eq "GOSA") {
$done = 1;
- &daemon_log("$session_id DEBUG: target and source is 'GOSA' -> process here", 7);
+ &daemon_log("$session_id DEBUG: target and source is 'GOSA' -> process '$header' here", 11);
}
}
if ($source eq "GOSA") {
$msg =~ s/<\/xml>/<forward_to_gosa>$local_address,$session_id<\/forward_to_gosa><\/xml>/;
}
- &daemon_log("$session_id DEBUG: target is own address without forward_to_gosa-tag -> process here", 7);
+ &daemon_log("$session_id DEBUG: target is own address without forward_to_gosa-tag -> process '$header' here", 11);
}
}
- # 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<\/target>/<target>$hostname<\/target>/;
- my $local_address = &get_local_ip_for_remote_ip($target_ip).":$server_port";
- if ($source eq "GOSA") {
- $msg =~ s/<\/xml>/<forward_to_gosa>$local_address,$session_id<\/forward_to_gosa><\/xml>/;
- }
- &daemon_log("$session_id DEBUG: target is a client address in known_clients -> process here", 7);
-
- } else {
- $not_found_in_known_clients_db = 1;
- }
- }
-
- # target ist own address with forward_to_gosa-tag not pointing to myself -> process here
+ # target is 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];
my $gosa_at;
my ($gosa_at, $gosa_session_id) = split(/,/, $forward_to_gosa);
if ($gosa_at ne $local_address) {
$done = 1;
- &daemon_log("$session_id DEBUG: target is own address with forward_to_gosa-tag not pointing to myself -> process here", 7);
+ &daemon_log("$session_id DEBUG: target is own address with forward_to_gosa-tag not pointing to myself -> process '$header' here", 11);
}
}
}
+ # Target is a client address and there is a processing function within a plugin -> process loaclly
+ if (not $done)
+ {
+ # Check if target is a client address
+ $sql = "SELECT * FROM $known_clients_tn WHERE (hostname='$target' OR macaddress LIKE '$target')";
+ $res = $known_clients_db->select_dbentry($sql);
+ if ((keys(%$res) > 0) )
+ {
+ my $hostname = $res->{1}->{'hostname'};
+ my $reduced_header = $header;
+ $reduced_header =~ s/gosa_//;
+ # Check if there is a processing function within a plugin
+ if (exists $known_functions->{$reduced_header})
+ {
+ $msg =~ s/<target>\S*<\/target>/<target>$hostname<\/target>/;
+ $done = 1;
+ &daemon_log("$session_id DEBUG: Target is client address with processing function within a plugin -> process '$header' here", 11);
+ }
+ }
+ }
+
+ # If header has a 'job_' prefix, do always process message locally
+ # which means put it into job queue
+ if ((not $done) && ($header =~ /job_/))
+ {
+ $done = 1;
+ &daemon_log("$session_id DEBUG: Header has a 'job_' prefix. Put it into job queue. -> process '$header' here", 11);
+ }
+
# 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 a 'job_' or a 'gosa_' message comes from a foreign server, fake module from
+ # ServerPackages to GosaPackages so gosa-si-server knows how to process this kind of messages
if ($header =~ /^gosa_/ || $header =~ /^job_/) {
$module = "GosaPackages";
}
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
if(exists $heap->{'client'}) {
$msg = &encrypt_msg($msg, $GosaPackages_key);
$heap->{'client'}->put($msg);
- &daemon_log("$session_id INFO: incoming '$header' message forwarded to GOsa", 5);
+ &daemon_log("$session_id DEBUG: incoming '$header' message forwarded to GOsa", 11);
}
$done = 1;
- &daemon_log("$session_id DEBUG: target is own address with forward_to_gosa-tag pointing at myself -> forward to gosa", 7);
+ &daemon_log("$session_id DEBUG: target is own address with forward_to_gosa-tag pointing at myself -> forward '$header' to gosa", 11);
}
}
}
+ # target is a client address in known_clients -> forward to client
+ 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;
+ &daemon_log("$session_id DEBUG: target is a client address in known_clients -> forward '$header' to client", 11);
+ my $hostkey = $res->{1}->{'hostkey'};
+ my $hostname = $res->{1}->{'hostname'};
+ $msg =~ s/<target>\S*<\/target>/<target>$hostname<\/target>/;
+ $msg =~ s/<header>gosa_/<header>/;
+ 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 '$hostname': $msg", 1);
+ }
+ }
+ else
+ {
+ $not_found_in_known_clients_db = 1;
+ }
+ }
+
# target is a client address in foreign_clients -> forward to registration server
if (not $done) {
$sql = "SELECT * FROM $foreign_clients_tn WHERE (hostname='$target' OR macaddress LIKE '$target')";
if ($source eq "GOSA") {
$msg =~ s/<\/xml>/<forward_to_gosa>$local_address,$session_id<\/forward_to_gosa><\/xml>/;
}
- &send_msg_to_target($msg, $regserver, $regserver_key, $header, $session_id);
+ my $error= &send_msg_to_target($msg, $regserver, $regserver_key, $header, $session_id);
+ if ($error) {
+ &daemon_log("$session_id ERROR: some problems occurred while trying to send msg to registration server: $msg", 1);
+ }
}
$done = 1;
- &daemon_log("$session_id DEBUG: target is a client address in foreign_clients -> forward to registration server", 7);
+ &daemon_log("$session_id DEBUG: target is a client address in foreign_clients -> forward '$header' to registration server", 11);
} else {
$not_found_in_foreign_clients_db = 1;
}
&send_msg_to_target($msg, $target, $hostkey, $header, $session_id);
$done = 1;
- &daemon_log("$session_id DEBUG: target is a server address -> forward to server", 7);
+ &daemon_log("$session_id DEBUG: target is a server address -> forward '$header' to server", 11);
} else {
$not_found_in_known_server_db = 1;
}
if ( $not_found_in_foreign_clients_db
&& $not_found_in_known_server_db
&& $not_found_in_known_clients_db) {
+ &daemon_log("$session_id DEBUG: target is not in foreign_clients_db, known_server_db or known_clients_db, maybe it is a complete new one -> process '$header' here", 11);
+ if ($header =~ /^gosa_/ || $header =~ /^job_/) {
+ $module = "GosaPackages";
+ }
my $res = $incoming_db->add_dbentry( {table=>$incoming_tn,
primkey=>[],
headertag=>$header,
sessionid=>$session_id,
} );
$done = 1;
- &daemon_log("$session_id DEBUG: target is not in foreign_clients_db, known_server_db or known_clients_db, maybe it is a complete new one -> process here", 7);
+ $kernel->yield('watch_for_next_tasks');
}
sub next_task {
- my ($session, $heap, $task) = @_[SESSION, HEAP, ARG0];
+ my ($session, $heap, $task) = @_[SESSION, HEAP, ARG0, ARG1];
my $running_task = POE::Wheel::Run->new(
Program => sub { process_task($session, $heap, $task) },
StdioFilter => POE::Filter::Reference->new(),
sub handle_task_done {
my ( $kernel, $heap, $task_id ) = @_[ KERNEL, HEAP, ARG0 ];
delete $heap->{task}->{$task_id};
+ if (exists $heap->{ldap_handle}->{$task_id}) {
+ &release_ldap_handle($heap->{ldap_handle}->{$task_id});
+ }
}
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);
######################
# 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 =~ /<header>(\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);
}
}
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];
my $host_name = $hit->{hostname};
my $host_key = $hit->{hostkey};
my $error = &send_msg_to_target($answer, $host_name, $host_key, $answer_header, $session_id);
- &update_jobdb_status_for_send_msgs($answer, $error);
+ &update_jobdb_status_for_send_msgs($session_id, $answer, $error);
}
}
my $host_key = $hit->{hostkey};
$answer =~ s/<target>\S+<\/target>/<target>$host_name<\/target>/g;
my $error = &send_msg_to_target($answer, $host_name, $host_key, $answer_header, $session_id);
- &update_jobdb_status_for_send_msgs($answer, $error);
+ &update_jobdb_status_for_send_msgs($session_id, $answer, $error);
}
}
if( defined $session_id ) {
$add_on = ".session_id=$session_id";
}
+ my $header = ($1) if $answer =~ /<header>(\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;
my $header;
if( defined $1 ) { $header = $1; }
my $error = &send_msg_to_target($answer, $server_address, $GosaPackages_key, $header, $session_id);
- &update_jobdb_status_for_send_msgs($answer, $error);
+ &update_jobdb_status_for_send_msgs($session_id, $answer, $error);
}
# 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'";
my $query_res = $known_clients_db->select_dbentry( $sql_statement );
my $found_ip_flag = 0;
$answer =~ s/$answer_target/$host_name/g;
daemon_log("$session_id INFO: found host '$host_name', associated to '$answer_target'", 5);
my $error = &send_msg_to_target($answer, $host_name, $host_key, $answer_header, $session_id);
- &update_jobdb_status_for_send_msgs($answer, $error);
+ &update_jobdb_status_for_send_msgs($session_id, $answer, $error);
$found_ip_flag++ ;
}
+
+ # Looking for macaddress in foreign_clients
if ($found_ip_flag == 0) {
my $sql = "SELECT * FROM $foreign_clients_tn WHERE macaddress LIKE '$answer_target'";
my $res = $foreign_clients_db->select_dbentry($sql);
if (defined $reg_server_key) {
$answer =~ s/$answer_target/$host_name/g;
my $error = &send_msg_to_target($answer, $reg_server, $reg_server_key, $answer_header, $session_id);
- &update_jobdb_status_for_send_msgs($answer, $error);
+ &update_jobdb_status_for_send_msgs($session_id, $answer, $error);
$found_ip_flag++ ;
}
}
}
+
+ # No mac to ip matching found
if( $found_ip_flag == 0) {
- daemon_log("$session_id WARNING: no host found in known_clients with mac address '$answer_target'", 3);
+ daemon_log("$session_id WARNING: no host found in known_clients or foreign_clients with mac address '$answer_target'", 3);
+ &reactivate_job_with_delay($session_id, $answer_target, $answer_header, 30);
}
# Answer is for one specific host
next;
}
my $error = &send_msg_to_target($answer, $answer_target, $encrypt_key, $answer_header,$session_id);
- &update_jobdb_status_for_send_msgs($answer, $error);
+ &update_jobdb_status_for_send_msgs($session_id, $answer, $error);
}
}
}
$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);
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 $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);
+ $kernel->delay_set('watch_for_done_jobs',$job_queue_loop_delay);
}
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</header>%') AND (status='processing') AND (siserver='localhost'))";
};
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;
}
if ($progress ne $result->{'progress'} ) {
# Updating progress and result
- my $update_statement = "UPDATE $job_queue_tn SET modified='1', progress='".$result->{'progress'}."', result='$act_status' WHERE macaddress='$macaddress' AND siserver='localhost'";
+ my $update_statement = "UPDATE $job_queue_tn SET modified='1', progress='".$result->{'progress'}."', result='$act_status' WHERE macaddress LIKE '$macaddress' AND siserver='localhost'";
my $update_res = $job_db->update_dbentry($update_statement);
}
if ($progress eq 100) {
} else {
$done_statement .= "status='done'";
}
- $done_statement .= " WHERE macaddress='$macaddress' AND siserver='localhost'";
+ $done_statement .= " WHERE macaddress LIKE '$macaddress' AND siserver='localhost'";
my $done_res = $job_db->update_dbentry($done_statement);
}
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 $sql_statement = "SELECT * FROM $job_queue_tn WHERE (modified='1')";
my $res = $job_db->select_dbentry( $sql_statement );
# if db contains no jobs which should be update, do nothing
$watch_for_new_jobs_in_progress = 1;
my ($kernel,$heap) = @_[KERNEL, HEAP];
- # check gosa job quaeue for jobs with executable timestamp
+ # check gosa job queue for jobs with executable timestamp
my $timestamp = &get_time();
- my $sql_statement = "SELECT * FROM $job_queue_tn WHERE status='waiting' AND (CAST(timestamp AS UNSIGNED)) < $timestamp ORDER BY timestamp";
+ my $sql_statement = "SELECT * FROM $job_queue_tn WHERE siserver='localhost' AND status='waiting' AND (CAST(timestamp AS UNSIGNED)) < $timestamp ORDER BY timestamp";
my $res = $job_db->exec_statement( $sql_statement );
# Merge all new jobs that would do the same actions
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='".&get_time(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;
$job_msg =~ /<header>(\S+)<\/header>/;
my $header = $1 ;
- my $func_error = &send_msg_to_target($job_msg, $server_address, $GosaPackages_key, $header, "J");
+ 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', activate_new
+ if (($header =~ /gosa_trigger_action_reinstall/)
+ || ($header =~ /gosa_trigger_activate_new/)
+ || ($header =~ /gosa_trigger_action_update/)) {
+ my $sql_statement = "UPDATE $job_queue_tn SET status='processing' WHERE id=$jobdb_id";
+ my $dbres = $job_db->update_dbentry($sql_statement);
+ }
- # update status in job queue to 'processing'
- $sql_statement = "UPDATE $job_queue_tn SET status='processing' WHERE id=$jobdb_id";
- my $res = $job_db->update_dbentry($sql_statement);
-# TODO: abfangen ob alles in ordnung ist oder nicht, wenn nicht error schmeißen
+ # ... '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->exec_statement($sql_statement);
+ }
+
# We don't want parallel processing
last;
foreach my $entry (@entries) {
my @receivers= $entry->get_value("memberUid");
foreach my $receiver (@receivers) {
- $receiver_h{$1} = 0;
+ $receiver_h{$receiver} = 0;
}
}
}
if ($mesg->code) {
daemon_log("M ERROR: unable to translate group '$group_name' to user list for message delivery: $mesg->error", 1);
}
+ &release_ldap_handle($ldap_handle);
# ldap handle error ?
} else {
daemon_log("M ERROR: unable to translate group '$group_name' to user list for message delivery: no ldap handle available", 1);
# 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
# 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);
- # reciver is logged in nowhere
+ # receiver is logged in nowhere
if (not ref(@$res[0]) eq "ARRAY") { next; }
+ # receiver ist logged in at a client registered at local server
my $send_succeed = 0;
foreach my $hit (@$res) {
my $receiver_host = @$hit[0];
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);
}
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'});
$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);
my $sql = "SELECT * FROM $incoming_tn";
my $res = $incoming_db->select_dbentry($sql);
-
+
while ( my ($hit_num, $hit) = each %$res) {
my $headertag = $hit->{'headertag'};
if ($headertag =~ /^answer_(\d+)/) {
next;
}
my $message_id = $hit->{'id'};
+ my $session_id = $hit->{'sessionid'};
+ &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);
}
sub get_ldap_handle {
my ($session_id) = @_;
my $heap;
- my $ldap_handle;
if (not defined $session_id ) { $session_id = 0 };
if ($session_id =~ /[^0-9]*/) { $session_id = 0 };
- 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) or daemon_log("$session_id ERROR: Bind to LDAP $ldap_uri as $ldap_admin_dn failed!");
-
+ my ($package, $file, $row, $subroutine, $hasArgs, $wantArray, $evalText, $isRequire) = caller(1);
+ my $caller_text = "subroutine $subroutine";
+ if ($subroutine eq "(eval)") {
+ $caller_text = "eval block within file '$file' for '$evalText'";
+ }
+ 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 in $ldap_retry_sec seconds.", 1);
+ sleep($ldap_retry_sec);
+ goto get_handle;
} else {
- my $session_reference = $global_kernel->ID_id_to_session($session_id);
- if( defined $session_reference ) {
- $heap = $session_reference->get_heap();
- }
-
- if (not defined $heap) {
- daemon_log("$session_id DEBUG: cannot get heap for session_id '$session_id'", 7);
- return;
- }
-
- # TODO: This "if" is nonsense, because it doesn't prove that the
- # 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) or daemon_log("$session_id ERROR: Bind to LDAP $ldap_uri as $ldap_admin_dn failed!");
- $heap->{ldap_handle} = $ldap_handle;
- #}
+ 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);
return $ldap_handle;
}
+sub release_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("$session_id DEBUG: Released a ldap handle!", 42);
+ return;
+}
+
+
sub change_fai_state {
- my ($st, $targets, $session_id) = @_;
- $session_id = 0 if not defined $session_id;
- # Set FAI state to localboot
- my %mapActions= (
- reboot => '',
- update => 'softupdate',
- localboot => 'localboot',
- reinstall => 'install',
- rescan => '',
- wake => '',
- memcheck => 'memcheck',
- sysinfo => 'sysinfo',
- install => 'install',
- );
+ my ($st, $targets, $session_id) = @_;
+ $session_id = 0 if not defined $session_id;
+ # Set FAI state to localboot
+ my %mapActions= (
+ reboot => '',
+ update => 'softupdate',
+ localboot => 'localboot',
+ reinstall => 'install',
+ rescan => '',
+ wake => '',
+ memcheck => 'memcheck',
+ sysinfo => 'sysinfo',
+ install => 'install',
+ );
- # Return if this is unknown
- if (!exists $mapActions{ $st }){
- daemon_log("$session_id ERROR: unknown action '$st', can not translate ot FAIstate", 1);
- return;
- }
+ # Return if this is unknown
+ if (!exists $mapActions{ $st }){
+ daemon_log("$session_id ERROR: unknown action '$st', can not translate ot FAIstate", 1);
+ return;
+ }
- my $state= $mapActions{ $st };
+ my $state= $mapActions{ $st };
- my $ldap_handle = &get_ldap_handle($session_id);
- if( defined($ldap_handle) ) {
+ # Build search filter for hosts
+ my $search= "(&(objectClass=GOhard)";
+ foreach (@{$targets}){
+ $search.= "(macAddress=$_)";
+ }
+ $search.= ")";
- # Build search filter for hosts
- my $search= "(&(objectClass=GOhard)";
- foreach (@{$targets}){
- $search.= "(macAddress=$_)";
- }
- $search.= ")";
+ # If there's any host inside of the search string, procress them
+ if (!($search =~ /macAddress/)){
+ daemon_log("$session_id ERROR: no macAddress found in filter statement for LDAP search: '$search'", 1);
+ return;
+ }
- # If there's any host inside of the search string, procress them
- if (!($search =~ /macAddress/)){
- daemon_log("$session_id ERROR: no macAddress found in filter statement for LDAP search: '$search'", 1);
- return;
- }
+ my $ldap_handle = &get_ldap_handle($session_id);
+ # Perform search for Unit Tag
+ my $mesg = $ldap_handle->search(
+ base => $ldap_base,
+ scope => 'sub',
+ attrs => ['dn', 'FAIstate', 'objectClass'],
+ filter => "$search"
+ );
- # Perform search for Unit Tag
- my $mesg = $ldap_handle->search(
- base => $ldap_base,
- scope => 'sub',
- attrs => ['dn', 'FAIstate', 'objectClass'],
- filter => "$search"
- );
+ if ($mesg->count) {
+ my @entries = $mesg->entries;
+ if (0 == @entries) {
+ daemon_log("$session_id ERROR: ldap search failed: ldap_base=$ldap_base, filter=$search", 1);
+ }
- if ($mesg->count) {
- my @entries = $mesg->entries;
- if (0 == @entries) {
- daemon_log("$session_id ERROR: ldap search failed: ldap_base=$ldap_base, filter=$search", 1);
- }
-
- foreach my $entry (@entries) {
- # Only modify entry if it is not set to '$state'
- if ($entry->get_value("FAIstate") ne "$state"){
- daemon_log("$session_id INFO: Setting FAIstate to '$state' for ".$entry->dn, 5);
- my $result;
- my %tmp = map { $_ => 1 } $entry->get_value("objectClass");
- if (exists $tmp{'FAIobject'}){
- if ($state eq ''){
- $result= $ldap_handle->modify($entry->dn, changes => [
- delete => [ FAIstate => [] ] ]);
- } else {
- $result= $ldap_handle->modify($entry->dn, changes => [
- replace => [ FAIstate => $state ] ]);
- }
- } elsif ($state ne ''){
- $result= $ldap_handle->modify($entry->dn, changes => [
- add => [ objectClass => 'FAIobject' ],
- add => [ FAIstate => $state ] ]);
- }
-
- # Errors?
- if ($result->code){
- 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);
- }
- }
- } else {
- daemon_log("$session_id ERROR: LDAP search failed: ldap_base=$ldap_base, filter=$search", 1);
- }
+ foreach my $entry (@entries) {
+ # Only modify entry if it is not set to '$state'
+ if ($entry->get_value("FAIstate") ne "$state"){
+ daemon_log("$session_id INFO: Setting FAIstate to '$state' for ".$entry->dn, 5);
+ my $result;
+ my %tmp = map { $_ => 1 } $entry->get_value("objectClass");
+ if (exists $tmp{'FAIobject'}){
+ if ($state eq ''){
+ $result= $ldap_handle->modify($entry->dn, changes => [ delete => [ FAIstate => [] ] ]);
+ } else {
+ $result= $ldap_handle->modify($entry->dn, changes => [ replace => [ FAIstate => $state ] ]);
+ }
+ } elsif ($state ne ''){
+ $result= $ldap_handle->modify($entry->dn, changes => [ add => [ objectClass => 'FAIobject' ], add => [ FAIstate => $state ] ]);
+ }
- # if no ldap handle defined
- } else {
- daemon_log("$session_id ERROR: no LDAP handle defined for update FAIstate", 1);
- }
+ # Errors?
+ if ($result->code){
+ 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'", 42);
+ }
+ }
+ } else {
+ daemon_log("$session_id ERROR: LDAP search failed: ldap_base=$ldap_base, filter=$search", 1);
+ }
+ &release_ldap_handle($ldap_handle, $session_id);
return;
}
# If there's any host inside of the search string, procress them
if (!($search =~ /macAddress/)){
+ &release_ldap_handle($ldap_handle);
return;
}
daemon_log("$session_id INFO: Setting gotoMode to '$state' for ".$entry->dn, 5);
my $result;
- $result= $ldap_handle->modify($entry->dn, changes => [
- replace => [ gotoMode => $state ] ]);
+ $result= $ldap_handle->modify($entry->dn, changes => [replace => [ gotoMode => $state ] ]);
# Errors?
if ($result->code){
}
}
+ &release_ldap_handle($ldap_handle, $session_id);
+ return;
}
my $result;
if (not defined $session_id) { $session_id = 0; }
- my $ldap_handle = &get_ldap_handle();
+ my $ldap_handle = &get_ldap_handle($session_id);
if(defined($ldap_handle)) {
daemon_log("$session_id INFO: create_fai_server_db: start", 5);
my $mesg= $ldap_handle->search(
}
}
daemon_log("$session_id INFO: create_fai_server_db: finished", 5);
+ &release_ldap_handle($ldap_handle);
# TODO: Find a way to post the 'create_packages_list_db' event
if(not defined($dont_create_packages_list)) {
- &create_packages_list_db(undef, undef, $session_id);
+ &create_packages_list_db(undef, $session_id);
}
}
- $ldap_handle->disconnect;
return $result;
}
sub run_create_fai_release_db {
- my ($session, $heap, $table_name) = @_[SESSION, HEAP, ARG0];
+ my ($kernel, $session, $heap, $table_name) = @_[KERNEL, SESSION, HEAP, ARG0];
my $session_id = $session->ID;
my $task = POE::Wheel::Run->new(
Program => sub { &create_fai_release_db($table_name, $session_id) },
# used for logging
if (not defined $session_id) { $session_id = 0; }
- my $ldap_handle = &get_ldap_handle();
+ my $ldap_handle = &get_ldap_handle($session_id);
if(defined($ldap_handle)) {
daemon_log("$session_id INFO: create_fai_release_db: start",5);
my $mesg= $ldap_handle->search(
attrs => [],
filter => "(&(objectClass=organizationalUnit)(ou=fai))",
);
- if($mesg->{'resultCode'} == 0 &&
- $mesg->count != 0) {
+ if(($mesg->code == 0) && ($mesg->count != 0))
+ {
+ daemon_log("$session_id DEBUG: create_fai_release_db: count " . $mesg->count,138);
+
# Walk through all possible FAI container ou's
my @sql_list;
my $timestamp= &get_time();
}
}
- daemon_log("$session_id DEBUG: 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: 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);
}
daemon_log("$session_id INFO: create_fai_release_db: finished",5);
}
- $ldap_handle->disconnect;
return $result;
}
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) {
foreach my $entry (@{$mesg->{entries}}) {
if($entry->exists('cn')) {
my $tmp_dn= $entry->dn();
+ $tmp_dn= substr( $tmp_dn, 0, length($tmp_dn)
+ - length($fai_base) - 1 );
# Skip classname and ou dn parts for class
- my $tmp_release = ($1) if $tmp_dn =~ /^[^,]+,[^,]+,(.*?),$fai_base$/;
+ my $tmp_release = ($1) if $tmp_dn =~ /^[^,]+,[^,]+,(.*?)$/;
# Skip classes without releases
if((!defined($tmp_release)) || length($tmp_release)==0) {
}
} elsif (!$entry->exists('cn')) {
my $tmp_dn= $entry->dn();
- my $tmp_release = ($1) if $tmp_dn =~ /^(.*?),$fai_base$/;
+ $tmp_dn= substr( $tmp_dn, 0, length($tmp_dn)
+ - length($fai_base) - 1 );
+ my $tmp_release = ($1) if $tmp_dn =~ /^(.*?)$/;
# Skip classes without releases
if((!defined($tmp_release)) || length($tmp_release)==0) {
sub session_run_done {
my ( $kernel, $heap, $task_id ) = @_[ KERNEL, HEAP, ARG0 ];
delete $heap->{task}->{$task_id};
+ if (exists $heap->{ldap_handle}->{$task_id}) {
+ &release_ldap_handle($heap->{ldap_handle}->{$task_id});
+ }
+ delete $heap->{ldap_handle}->{$task_id};
}
sub create_sources_list {
- my $session_id = shift;
- my $ldap_handle = &main::get_ldap_handle;
+ my $session_id = shift || 0;
my $result="/tmp/gosa_si_tmp_sources_list";
# Remove old file
&main::daemon_log("$session_id DEBUG: remove an old version of '$result'", 7);
}
- my $fh;
- open($fh, ">$result");
+ open(my $fh, ">", "$result");
if (not defined $fh) {
&main::daemon_log("$session_id DEBUG: cannot open '$result' for writing", 7);
return undef;
}
if(defined($main::ldap_server_dn) and length($main::ldap_server_dn) > 0) {
+ my $ldap_handle = &get_ldap_handle($session_id);
my $mesg=$ldap_handle->search(
base => $main::ldap_server_dn,
scope => 'base',
}
}
}
+ &release_ldap_handle($ldap_handle);
} else {
if (defined $main::ldap_server_dn){
&main::daemon_log("$session_id ERROR: something wrong with ldap_server_dn '$main::ldap_server_dn', abort create_sources_list", 1);
sub run_create_packages_list_db {
my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
my $session_id = $session->ID;
-
my $task = POE::Wheel::Run->new(
Priority => +20,
- Program => sub {&create_packages_list_db(undef, undef, $session_id)},
+ Program => sub {&create_packages_list_db(undef, $session_id)},
StdoutEvent => "session_run_result",
StderrEvent => "session_run_debug",
CloseEvent => "session_run_done",
sub create_packages_list_db {
- my ($ldap_handle, $sources_file, $session_id) = @_;
+ my ($sources_file, $session_id) = @_;
# it should not be possible to trigger a recreation of packages_list_db
# while packages_list_db is under construction, so set flag packages_list_under_construction
}
if (not defined $session_id) { $session_id = 0; }
- if (not defined $ldap_handle) {
- $ldap_handle= &get_ldap_handle();
- if (not defined $ldap_handle) {
- daemon_log("$session_id ERROR: no ldap_handle available to create_packages_list_db", 1);
- unlink($packages_list_under_construction);
- return;
- }
- }
if (not defined $sources_file) {
&main::daemon_log("$session_id INFO: no sources_file given for creating packages list so trigger creation of it", 5);
$sources_file = &create_sources_list($session_id);
my $line;
- open(CONFIG, "<$sources_file") or do {
+ open(my $CONFIG, "<", "$sources_file") or do {
daemon_log( "$session_id ERROR: create_packages_list_db: Failed to open '$sources_file'", 1);
unlink($packages_list_under_construction);
return;
};
# Read lines
- while ($line = <CONFIG>){
+ while ($line = <$CONFIG>){
# Unify
chop($line);
$line =~ s/^\s+//;
&parse_package_info( $baseurl, $dist, $section, $session_id );
}
}
+ else {
+ daemon_log("$session_id ERROR: cannot parse line '$line'", 1);
+ }
}
- close (CONFIG);
-
+ close ($CONFIG);
if(keys(%repo_dirs)) {
find(\&cleanup_and_extract, keys( %repo_dirs ));
# This function should do some intensive task to minimize the db-traffic
sub strip_packages_list_statements {
- my @existing_entries= @{$packages_list_db->exec_statement("SELECT * FROM $main::packages_list_tn")};
+ my @existing_entries= @{$packages_list_db->exec_statement("SELECT * FROM $main::packages_list_tn")};
my @new_statement_list=();
my $hash;
my $insert_hash;
my $update_hash;
my $delete_hash;
+ my $known_packages_hash;
my $local_timestamp=get_time();
foreach my $existing_entry (@existing_entries) {
(! (@{$hash->{$distribution}->{$package}->{$version}}[4] eq $description))
) {
@{$update_hash->{$distribution}->{$package}->{$version}} = ($distribution,$package,$version,$section,$description,undef);
+ } else {
+ # package is already present in database. cache this knowledge for later use
+ @{$known_packages_hash->{$distribution}->{$package}->{$version}} = ($distribution,$package,$version,$section,$description,$template);
}
} else {
# Insert a non-existing entry to db
}
}
- # TODO: Check for orphaned entries
+ # Check for orphaned entries
+ foreach my $existing_entry (@existing_entries) {
+ my $distribution= @{$existing_entry}[0];
+ my $package= @{$existing_entry}[1];
+ my $version= @{$existing_entry}[2];
+ my $section= @{$existing_entry}[3];
+
+ if(
+ exists($insert_hash->{$distribution}->{$package}->{$version}) ||
+ exists($update_hash->{$distribution}->{$package}->{$version}) ||
+ exists($known_packages_hash->{$distribution}->{$package}->{$version})
+ ) {
+ next;
+ } else {
+ # Insert entry to delete hash
+ @{$delete_hash->{$distribution}->{$package}->{$version}} = ($distribution,$package,$version,$section);
+ }
+ }
- # unroll the insert_hash
+ # unroll the insert hash
foreach my $distribution (keys %{$insert_hash}) {
foreach my $package (keys %{$insert_hash->{$distribution}}) {
foreach my $version (keys %{$insert_hash->{$distribution}->{$package}}) {
next;
}
push @new_statement_list,
- "UPDATE $main::packages_list_tn SET $set WHERE"
- ." distribution = '$distribution'"
- ." AND package = '$package'"
- ." AND version = '$version'";
+ "UPDATE $main::packages_list_tn SET $set WHERE"
+ ." distribution = '$distribution'"
+ ." AND package = '$package'"
+ ." AND version = '$version'";
}
}
}
+
+ # unroll the delete hash
+ foreach my $distribution (keys %{$delete_hash}) {
+ foreach my $package (keys %{$delete_hash->{$distribution}}) {
+ foreach my $version (keys %{$delete_hash->{$distribution}->{$package}}) {
+ my $section = @{$delete_hash->{$distribution}->{$package}->{$version}}[3];
+ push @new_statement_list, "DELETE FROM $main::packages_list_tn WHERE distribution='$distribution' AND package='$package' AND version='$version' AND section='$section'";
+ }
+ }
+ }
+
+ unshift(@new_statement_list, "VACUUM");
@packages_list_statements = @new_statement_list;
}
$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 );
}
# 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'", 5);
+ daemon_log("$session_id DEBUG: run command: gunzip -cd '$dest' > '$dest.in'", 266);
unlink($dest);
- daemon_log("$session_id DEBUG: delete file '$dest'", 5);
+ daemon_log("$session_id DEBUG: delete file '$dest'", 266);
} else {
- daemon_log("$session_id ERROR: create_packages_list_db: get_packages: fetching '$url' failed!", 1);
+ daemon_log("$session_id ERROR: create_packages_list_db: get_packages: fetching '$url' into '$dest' failed!", 1);
}
return 0;
}
my ($path, $dist, $srv_path, $session_id)= @_;
if (not defined $session_id) { $session_id = 0;}
my ($package, $version, $section, $description);
- my $PACKAGES;
my $timestamp = &get_time();
if(not stat("$path.in")) {
return;
}
- open($PACKAGES, "<$path.in");
+ open(my $PACKAGES, "<", "$path.in");
if(not defined($PACKAGES)) {
daemon_log("$session_id ERROR: create_packages_list_db: parse_package: cannot open '$path.in'",1);
return;
if( -f "$dir/DEBIAN/templates" ) {
- daemon_log("DEBUG: Found debconf templates in '$package' - $newver", 7);
+ daemon_log("0 DEBUG: Found debconf templates in '$package' - $newver", 266);
my $tmpl= ""; {
local $/=undef;
- open FILE, "$dir/DEBIAN/templates";
- $tmpl = &encode_base64(<FILE>);
- close FILE;
+ open(my $FILE, "$dir/DEBIAN/templates");
+ $tmpl = &encode_base64(<$FILE>);
+ close($FILE);
}
rmtree("$dir/DEBIAN/templates");
}
+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];
- # hole alle bekannten server aus known_server_db
- my $server_sql = "SELECT * FROM $known_server_tn";
- my $server_res = $known_server_db->exec_statement($server_sql);
+ # Update status and update-time of all si-server with expired update_time and
+ # 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 ";
+ my $block_res = $known_server_db->exec_statement($block_statement);
- # no entries in known_server_db
- if (not ref(@$server_res[0]) eq "ARRAY") {
- # TODO
- }
+ # 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'";
+ my $fetch_res = $known_server_db->exec_statement($fetch_statement);
- # detect already connected clients
+ # Detect already connected clients. Will be added to registration msg later.
my $client_sql = "SELECT * FROM $known_clients_tn";
my $client_res = $known_clients_db->exec_statement($client_sql);
- # send my server details to all other gosa-si-server within the network
- foreach my $hit (@$server_res) {
+ # Send registration messag to all fetched si-server
+ foreach my $hit (@$fetch_res) {
my $hostname = @$hit[0];
my $hostkey = &create_passwd;
- # add already connected clients to registration message
+ # Add already connected clients to registration message
my $myhash = &create_xml_hash('new_server', $server_address, $hostname);
&add_content2xml_hash($myhash, 'key', $hostkey);
map(&add_content2xml_hash($myhash, 'client', @{$_}[0].",".@{$_}[4]), @$client_res);
- # add locally loaded gosa-si modules to registration message
+ # Add locally loaded gosa-si modules to registration message
my $loaded_modules = {};
while (my ($package, $pck_info) = each %$known_modules) {
- next if ((!defined(@$pck_info[2])) || (!(ref (@$pck_info[2]) eq 'HASH')));
- foreach my $act_module (keys(%{@$pck_info[2]})) {
- $loaded_modules->{$act_module} = "";
- }
- }
-
+ next if ((!defined(@$pck_info[2])) || (!(ref (@$pck_info[2]) eq 'HASH')));
+ foreach my $act_module (keys(%{@$pck_info[2]})) {
+ $loaded_modules->{$act_module} = "";
+ }
+ }
map(&add_content2xml_hash($myhash, "loaded_modules", $_), keys(%$loaded_modules));
- # add macaddress to registration message
+ # Add macaddress to registration message
my ($host_ip, $host_port) = split(/:/, $hostname);
my $local_ip = &get_local_ip_for_remote_ip($host_ip);
my $network_interface= &get_interface_for_ip($local_ip);
my $host_mac = &get_mac_for_interface($network_interface);
&add_content2xml_hash($myhash, 'macaddress', $host_mac);
- # build registration message and send it
+ # Build registration message and send it
my $foreign_server_msg = &create_xml_string($myhash);
my $error = &send_msg_to_target($foreign_server_msg, $hostname, $ServerPackages_key, "new_server", 0);
}
-
- $kernel->delay_set("register_at_foreign_servers", $foreign_servers_register_delay);
- return;
+
+
+ # After n sec perform a check of all server registration processes
+ $kernel->delay_set("control_server_registration", 2);
+
+ return;
+}
+
+
+sub control_server_registration {
+ my ($kernel) = $_[KERNEL];
+
+ # Check if all registration processes succeed or not
+ my $select_statement = "SELECT * FROM $known_server_tn WHERE status='new_server'";
+ my $select_res = $known_server_db->exec_statement($select_statement);
+
+ # If at least one registration process failed, maybe in case of a race condition
+ # with a foreign registration process
+ if (@$select_res > 0)
+ {
+ # 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'";
+ my $update_res = $known_server_db->exec_statement($update_statement);
+
+ # Set a random delay to avoid the registration race condition
+ my $new_foreign_servers_register_delay = int(rand(4))+1;
+ $kernel->delay_set("register_at_foreign_servers", $new_foreign_servers_register_delay);
+ }
+ # If all registration processes succeed
+ else
+ {
+ $kernel->delay_set("register_at_foreign_servers", $foreign_servers_register_delay);
+ }
+
+ return;
}
"f|foreground" => \$foreground,
"v|verbose+" => \$verbose,
"no-arp+" => \$no_arp,
- );
+ "d=s" => \$debug_parts,
+ ) or &usage("", 1);
# read and set config parameters
&check_cmdline_param ;
# Do something useful - put our PID into the pid_file
if( 0 != $pid ) {
- open( LOCK_FILE, ">$pid_file" );
- print LOCK_FILE "$pid\n";
- close( LOCK_FILE );
+ open( my $LOCK_FILE, ">", "$pid_file" );
+ print $LOCK_FILE "$pid\n";
+ close( $LOCK_FILE );
if( !$foreground ) {
exit( 0 )
};
} else {
$server_status = "developmental" ;
}
-
-# Prepare log file
+# Prepare log file and set permissions
$root_uid = getpwnam('root');
$adm_gid = getgrnam('adm');
-chmod(0640, $log_file);
+open(my $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");
daemon_log("status: $server_status", 1);
daemon_log($server_status_hash->{$server_status}.": $server_revision", 1);
-# connect to incoming_db
-unlink($incoming_file_name);
-$incoming_db = GOSA::DBmysql->new($incoming_file_name);
-$incoming_db->create_table($incoming_tn, \@incoming_col_names);
+# Buildup data bases
+{
+ no strict "refs";
-# connect to gosa-si job queue
-unlink($job_queue_file_name); ## just for debugging
-$job_db = GOSA::DBmysql->new($job_queue_file_name);
-$job_db->create_table($job_queue_tn, \@job_queue_col_names);
-chmod(0660, $job_queue_file_name);
-chown($root_uid, $adm_gid, $job_queue_file_name);
+ if ($db_module eq "DBmysql") {
-# connect to known_clients_db
-unlink($known_clients_file_name); ## just for debugging
-$known_clients_db = GOSA::DBmysql->new($known_clients_file_name);
-$known_clients_db->create_table($known_clients_tn, \@known_clients_col_names);
-chmod(0660, $known_clients_file_name);
-chown($root_uid, $adm_gid, $known_clients_file_name);
+ daemon_log("0 INFO: importing database module '$db_module'", 1);
-# connect to foreign_clients_db
-unlink($foreign_clients_file_name);
-$foreign_clients_db = GOSA::DBmysql->new($foreign_clients_file_name);
-$foreign_clients_db->create_table($foreign_clients_tn, \@foreign_clients_col_names);
-chmod(0660, $foreign_clients_file_name);
-chown($root_uid, $adm_gid, $foreign_clients_file_name);
+ # connect to incoming_db
+ $incoming_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
-# connect to known_server_db
-unlink($known_server_file_name);
-$known_server_db = GOSA::DBmysql->new($known_server_file_name);
-$known_server_db->create_table($known_server_tn, \@known_server_col_names);
-chmod(0660, $known_server_file_name);
-chown($root_uid, $adm_gid, $known_server_file_name);
+ # connect to gosa-si job queue
+ $job_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
-# connect to login_usr_db
-unlink($login_users_file_name);
-$login_users_db = GOSA::DBmysql->new($login_users_file_name);
-$login_users_db->create_table($login_users_tn, \@login_users_col_names);
-chmod(0660, $login_users_file_name);
-chown($root_uid, $adm_gid, $login_users_file_name);
+ # connect to known_clients_db
+ $known_clients_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
-# connect to fai_server_db
-unlink($fai_server_file_name);
-$fai_server_db = GOSA::DBmysql->new($fai_server_file_name);
-$fai_server_db->create_table($fai_server_tn, \@fai_server_col_names);
-chmod(0660, $fai_server_file_name);
-chown($root_uid, $adm_gid, $fai_server_file_name);
+ # connect to foreign_clients_db
+ $foreign_clients_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
-# connect to fai_release_db
-unlink($fai_release_file_name);
-$fai_release_db = GOSA::DBmysql->new($fai_release_file_name);
-$fai_release_db->create_table($fai_release_tn, \@fai_release_col_names);
-chmod(0660, $fai_release_file_name);
-chown($root_uid, $adm_gid, $fai_release_file_name);
+ # connect to known_server_db
+ $known_server_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
-# connect to packages_list_db
-#unlink($packages_list_file_name);
-unlink($packages_list_under_construction);
-$packages_list_db = GOSA::DBmysql->new($packages_list_file_name);
-$packages_list_db->create_table($packages_list_tn, \@packages_list_col_names);
-chmod(0660, $packages_list_file_name);
-chown($root_uid, $adm_gid, $packages_list_file_name);
+ # connect to login_usr_db
+ $login_users_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
-# connect to messaging_db
-unlink($messaging_file_name);
-$messaging_db = GOSA::DBmysql->new($messaging_file_name);
-$messaging_db->create_table($messaging_tn, \@messaging_col_names);
-chmod(0660, $messaging_file_name);
-chown($root_uid, $adm_gid, $messaging_file_name);
+ # connect to fai_server_db
+ $fai_server_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
+ # connect to fai_release_db
+ $fai_release_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
-# create xml object used for en/decrypting
-$xml = new XML::Simple();
+ # connect to packages_list_db
+ $packages_list_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
+ # connect to messaging_db
+ $messaging_db = ("GOSA::".$db_module)->new($main::mysql_database, $main::mysql_host, $main::mysql_username, $main::mysql_password);
-# 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);
- }
- }
+ } elsif ($db_module eq "DBsqlite") {
- daemon_log("0 INFO: found foreign server via DNS ".join(", ", @tmp_servers), 5);
+ daemon_log("0 INFO: importing database module '$db_module'", 1);
- foreach my $server (@tmp_servers) {
- unshift(@foreign_server_list, $server);
+ # connect to incoming_db
+ unlink($incoming_file_name);
+ $incoming_db = GOSA::DBsqlite->new($incoming_file_name);
+ chmod(0640, $incoming_file_name);
+ chown($root_uid, $adm_gid, $incoming_file_name);
+
+ # connect to gosa-si job queue
+ $job_db = GOSA::DBsqlite->new($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);
+ $known_clients_db = GOSA::DBsqlite->new($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(0640, $foreign_clients_file_name);
+ chown($root_uid, $adm_gid, $foreign_clients_file_name);
+
+ # connect to known_server_db
+ 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);
+
+ # connect to login_usr_db
+ #unlink($login_users_file_name);
+ $login_users_db = GOSA::DBsqlite->new($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(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(0640, $fai_release_file_name);
+ chown($root_uid, $adm_gid, $fai_release_file_name);
+
+ # connect to packages_list_db
+ unlink($packages_list_under_construction);
+ $packages_list_db = GOSA::DBsqlite->new($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(0640, $messaging_file_name);
+ chown($root_uid, $adm_gid, $messaging_file_name);
}
-} else {
- daemon_log("0 INFO: DNS lookup for server registration is disabled", 5);
}
+# Creating tables
-# 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 $act_timestamp = &get_time();
-foreach my $foreign_server (@foreign_server_list) {
+daemon_log("0 INFO: creating tables in database with '$db_module'", 1);
- # 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_jet_registered',
- hostkey=>"none",
- loaded_modules => "none",
- timestamp=>$act_timestamp,
- } );
-}
+$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);
+$fai_server_db->create_table($fai_server_tn, \@fai_server_col_names);
+$login_users_db->create_table($login_users_tn, \@login_users_col_names);
+$known_server_db->create_table($known_server_tn, \@known_server_col_names);
+$foreign_clients_db->create_table($foreign_clients_tn, \@foreign_clients_col_names);
+$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();
# 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
+while (my ($module, @mod_info) = each %$known_modules)
+{
+ while (my ($plugin, $functions) = each %{$mod_info[0][2]})
+ {
+ while (my ($function, $nothing) = each %$functions )
+ {
+ $known_functions->{$function} = $nothing;
+ }
+ }
+}
+
# Prepare for using Opsi
if ($opsi_enabled eq "true") {
use JSON::RPC::Client;
Alias => "TCP_SERVER",
Port => $server_port,
ClientInput => sub {
- my ($kernel, $input) = @_[KERNEL, ARG0];
- push(@tasks, $input);
+ my ($kernel, $input, $heap, $session) = @_[KERNEL, ARG0, HEAP, SESSION];
+ my $session_id = $session->ID;
+ if ($input =~ /;([\d\.]+):([\d]+)$/)
+ {
+ # 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
+ {
+ my $remote_ip = $heap->{'remote_ip'};
+ &daemon_log("$session_id DEBUG: incoming message from '$remote_ip'", 11);
+ }
push(@msgs_to_decrypt, $input);
$kernel->yield("msg_to_decrypt");
},
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,
}
);
-daemon_log("start socket for incoming xml messages at port '$server_port' ", 1);
+daemon_log("0 INFO: start socket for incoming xml messages at port '$server_port' ", 1);
# create session for repeatedly checking the job queue for jobs
POE::Session->create(
inline_states => {
_start => \&session_start,
register_at_foreign_servers => \®ister_at_foreign_servers,
+ control_server_registration => \&control_server_registration,
sig_handler => \&sig_handler,
next_task => \&next_task,
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,