X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-server;h=1dd69157831df62552ae5277a4f56412f38b6b34;hb=7067bdf5cb4d4f7fc5a303c9005c183baeccff67;hp=9ae65c92c88212c9b74cdaf20b246a490fdbcb9e;hpb=06cc2476d62963c92a7c314e9e135a56b1bf9b4b;p=gosa.git diff --git a/gosa-si/gosa-si-server b/gosa-si/gosa-si-server index 9ae65c92c..1dd691578 100755 --- a/gosa-si/gosa-si-server +++ b/gosa-si/gosa-si-server @@ -8,7 +8,8 @@ # DESCRIPTION: # # OPTIONS: --- -# REQUIREMENTS: libconfig-inifiles-perl libcrypt-rijndael-perl libxml-simple-perl libipc-shareable-perl libdata-dumper-simple-perl +# REQUIREMENTS: libconfig-inifiles-perl libcrypt-rijndael-perl libxml-simple-perl +# libdata-dumper-simple-perl libdbd-sqlite3-perl libnet-ldap-perl # BUGS: --- # NOTES: # AUTHOR: (Andreas Rettenberger), @@ -28,6 +29,9 @@ use Time::HiRes qw( gettimeofday ); use Fcntl; use IO::Socket::INET; +use IO::Handle; +use IO::Select; +use Symbol qw(qualify_to_ref); use Crypt::Rijndael; use MIME::Base64; use Digest::MD5 qw(md5 md5_hex md5_base64); @@ -36,10 +40,9 @@ use Data::Dumper; use Sys::Syslog qw( :DEFAULT setlogsock); use Cwd; use File::Spec; -use IPC::Shareable qw( :lock); -IPC::Shareable->clean_up_all; use GOSA::GosaSupportDaemon; use GOSA::DBsqlite; +use threads; my $modules_path = "/usr/lib/gosa-si/modules"; use lib "/usr/lib/gosa-si/modules"; @@ -48,7 +51,7 @@ my (%cfg_defaults, $foreground, $verbose, $ping_timeout); my ($bus, $msg_to_bus, $bus_cipher); my ($server, $server_mac_address, $server_events); my ($gosa_server, $job_queue_timeout, $job_queue_table_name, $job_queue_file_name); -my ($known_daemons, $shmda, $known_clients, $shmcl, $known_modules); +my ($known_modules, $known_clients_file_name, $known_server_file_name); my ($max_clients); my ($pid_file, $procid, $pid, $log_file); my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout); @@ -87,23 +90,14 @@ $no_bus = 0; $no_arp = 0; # name of table for storing gosa jobs -$job_queue_table_name = 'jobs'; +our $job_queue_table_name = 'jobs'; +our $job_db; # holds all other gosa-sd as well as the gosa-sd-bus -our $known_daemons = {}; -our $shmda = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, - exclusive => 1, - mode => 0666, - destroy => 1, - }); -# holds all registrated clients -our $known_clients = {}; -our $shmcl = tie($known_clients, 'IPC::Shareable', undef, {create => 1, - exclusive => 1, - mode => 0666, - destroy => 1, - }); +our $known_server_db; +# holds all registrated clients +our $known_clients_db; %cfg_defaults = ("general" => @@ -114,16 +108,18 @@ our $shmcl = tie($known_clients, 'IPC::Shareable', undef, {create => 1, "child_timeout" => [\$child_timeout, 180], "job_queue_timeout" => [\$job_queue_timeout, undef], "job_queue_file_name" => [\$job_queue_file_name, '/var/lib/gosa-si/jobs.db'], + "known_clients_file_name" => [\$known_clients_file_name, '/var/lib/gosa-si/known_clients.db' ], + "known_server_file_name" => [\$known_server_file_name, '/var/lib/gosa-si/known_server.db'], }, "bus" => {"bus_activ" => [\$bus_activ, "on"], "bus_passwd" => [\$bus_passwd, ""], - "bus_ip" => [\$bus_ip, ""], + "bus_ip" => [\$bus_ip, "0.0.0.0"], "bus_port" => [\$bus_port, "20080"], }, "server" => {"server_activ" => [\$server_activ, "on"], - "server_ip" => [\$server_ip, ""], + "server_ip" => [\$server_ip, "0.0.0.0"], "server_port" => [\$server_port, "20081"], "server_passwd" => [\$server_passwd, ""], "max_clients" => [\$max_clients, 100], @@ -134,7 +130,7 @@ our $shmcl = tie($known_clients, 'IPC::Shareable', undef, {create => 1, }, "gosa" => {"gosa_activ" => [\$gosa_activ, "on"], - "gosa_ip" => [\$gosa_ip, ""], + "gosa_ip" => [\$gosa_ip, "0.0.0.0"], "gosa_port" => [\$gosa_port, "20082"], "gosa_passwd" => [\$gosa_passwd, "none"], }, @@ -175,7 +171,7 @@ sub read_configfile { if( -r $cfg_file ) { $cfg = Config::IniFiles->new( -file => $cfg_file ); } else { - print STDERR "Couldn't read config file!"; + print STDERR "Couldn't read config file!\n"; } } else { $cfg = Config::IniFiles->new() ; @@ -197,7 +193,7 @@ sub read_configfile { # RETURNS: nothing # DESCRIPTION: function for logging #=============================================================================== -sub daemon_log { +sub daemon_log : locked { # log into log_file my( $msg, $level ) = @_; if(not defined $msg) { return } @@ -209,11 +205,26 @@ sub daemon_log { return } chomp($msg); if($level <= $verbose){ - print LOG_HANDLE "$level $msg\n"; - if(defined $foreground) { print $msg."\n" } + 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", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); + $month = $monthnames[$month]; + $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; + $year+=1900; + my $name = $0; + $name =~ s/\.\///; + + 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 ); } -# close( LOG_HANDLE ); #log into syslog # my ($msg, $level, $facility) = @_; # if(not defined $msg) {return} @@ -299,34 +310,6 @@ sub check_pid { } } - -#=== FUNCTION ================================================================ -# NAME: get_ip_and_mac -# PARAMETERS: nothing -# RETURNS: (ip, mac) -# DESCRIPTION: executes /sbin/ifconfig and parses the output, the first occurence -# of a inet address is returned as well as the mac address in the line -# above the inet address -#=============================================================================== -sub get_ip_and_mac { - my $ip = "0.0.0.0.0"; # Defualt-IP - my $mac = "00:00:00:00:00:00"; # Default-MAC - my @ifconfig = qx(/sbin/ifconfig); - foreach(@ifconfig) { - if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) { - $mac = "$1:$2:$3:$4:$5:$6"; - next; - } - if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) { - $ip = "$1.$2.$3.$4"; - last; - } - } - return ($ip, $mac); -} - - - #=== FUNCTION ================================================================ # NAME: import_modules # PARAMETERS: module_path - string - abs. path to the directory the modules @@ -349,18 +332,16 @@ sub import_modules { } eval { require $file; }; if ($@) { - daemon_log("ERROR: gosa-sd could not load module $file", 1); + daemon_log("ERROR: gosa-si-server could not load module $file", 1); daemon_log("$@", 5); - next; - } - my $mod_name = $1; - #my $module_tag_hash = eval( $mod_name.'::get_module_tags()' ); - - my $info = eval($mod_name.'::get_module_info()'); - my ($input_address, $input_key, $input, $input_active, $input_type) = @{$info}; - $known_modules->{$mod_name} = $info; + } else { + my $mod_name = $1; + my $info = eval($mod_name.'::get_module_info()'); + my ($input_address, $input_key, $input, $input_active, $input_type) = @{$info}; + $known_modules->{$mod_name} = $info; - daemon_log("module $mod_name loaded", 1); + daemon_log("module $mod_name loaded", 1); + } } # for debugging @@ -380,23 +361,8 @@ sub import_modules { #=============================================================================== sub sig_int_handler { my ($signal) = @_; - if($server){ - close($server); - daemon_log("daemon server closed", 1); - } - if( -p $arp_fifo_path ) { - close $arp_fifo ; - unlink($arp_fifo_path) ; - daemon_log("ARP_FIFO closed", 1) ; - } - - if($gosa_server){ - close($gosa_server); - daemon_log("gosa server closed", 1); - } - print STDERR "$signal\n"; - + daemon_log("shutting down gosa-si-server", 1); exit(1); } $SIG{INT} = \&sig_int_handler; @@ -519,19 +485,17 @@ sub get_processing_child { $answer = $tmp; } } - - #&print_known_daemons(); - #&print_known_clients(); - daemon_log("processing of msg finished", 5); if (defined $answer) { print $PARENT_wr $answer."\n"; - daemon_log("with answer: $answer", 5); - daemon_log(" ", 5); + print $PARENT_wr "ENDMESSAGE\n"; + my $len_answer = length $answer; + daemon_log("with answer: length of answer: $len_answer", 7); + daemon_log("\n$answer", 7); } else { print $PARENT_wr "done"."\n"; - daemon_log(" ", 5); + print $PARENT_wr "ENDMESSAGE\n"; } redo; } @@ -591,25 +555,25 @@ sub read_from_socket { # RETURNS: nothing # DESCRIPTION: nomen est omen #=============================================================================== -sub print_known_daemons { - my ($tmp) = @_ ; - print "####################################\n"; - print "# status of known_daemons\n"; - $shmda->shlock(LOCK_EX); - my @hosts = keys %$known_daemons; - foreach my $host (@hosts) { - my $status = $known_daemons->{$host}->{status} ; - my $passwd = $known_daemons->{$host}->{passwd}; - my $timestamp = $known_daemons->{$host}->{timestamp}; - print "$host\n"; - print "\tstatus: $status\n"; - print "\tpasswd: $passwd\n"; - print "\ttimestamp: $timestamp\n"; - } - $shmda->shunlock(LOCK_EX); - print "####################################\n"; - return; -} +#sub print_known_daemons { +# my ($tmp) = @_ ; +# print "####################################\n"; +# print "# status of known_daemons\n"; +# $shmda->shlock(LOCK_EX); +# my @hosts = keys %$known_daemons; +# foreach my $host (@hosts) { +# my $status = $known_daemons->{$host}->{status} ; +# my $passwd = $known_daemons->{$host}->{passwd}; +# my $timestamp = $known_daemons->{$host}->{timestamp}; +# print "$host\n"; +# print "\tstatus: $status\n"; +# print "\tpasswd: $passwd\n"; +# print "\ttimestamp: $timestamp\n"; +# } +# $shmda->shunlock(LOCK_EX); +# print "####################################\n"; +# return; +#} #=== FUNCTION ================================================================ @@ -618,16 +582,16 @@ sub print_known_daemons { # RETURNS: nothing # DESCRIPTION: creates a dummy entry for hostname in known_daemons #=============================================================================== -sub create_known_daemon { - my ($hostname) = @_; - $shmda->shlock(LOCK_EX); - $known_daemons->{$hostname} = {}; - $known_daemons->{$hostname}->{status} = "none"; - $known_daemons->{$hostname}->{passwd} = "none"; - $known_daemons->{$hostname}->{timestamp} = "none"; - $shmda->shunlock(LOCK_EX); - return; -} +#sub create_known_daemon { +# my ($hostname) = @_; +# $shmda->shlock(LOCK_EX); +# $known_daemons->{$hostname} = {}; +# $known_daemons->{$hostname}->{status} = "none"; +# $known_daemons->{$hostname}->{passwd} = "none"; +# $known_daemons->{$hostname}->{timestamp} = "none"; +# $shmda->shunlock(LOCK_EX); +# return; +#} #=== FUNCTION ================================================================ @@ -639,50 +603,50 @@ sub create_known_daemon { # RETURNS: nothing # DESCRIPTION: nome est omen and updates each time the timestamp of hostname #=============================================================================== -sub add_content2known_daemons { - my $arg = { - hostname => undef, status => undef, passwd => undef, - mac_address => undef, events => undef, - @_ }; - my $hostname = $arg->{hostname}; - my $status = $arg->{status}; - my $passwd = $arg->{passwd}; - my $mac_address = $arg->{mac_address}; - my $events = $arg->{events}; - - if (not defined $hostname) { - daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); - return; - } - - 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+=1; - $month = $month < 10 ? $month = "0".$month : $month; - $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; - $year+=1900; - my $t = "$year$month$monthday$hours$minutes$seconds"; - - $shmda->shlock(LOCK_EX); - if (defined $status) { - $known_daemons->{$hostname}->{status} = $status; - } - if (defined $passwd) { - $known_daemons->{$hostname}->{passwd} = $passwd; - } - if (defined $mac_address) { - $known_daemons->{$hostname}->{mac_address} = $mac_address; - } - if (defined $events) { - $known_daemons->{$hostname}->{events} = $events; - } - $known_daemons->{$hostname}->{timestamp} = $t; - $shmda->shlock(LOCK_EX); - return; -} +#sub add_content2known_daemons { +# my $arg = { +# hostname => undef, status => undef, passwd => undef, +# mac_address => undef, events => undef, +# @_ }; +# my $hostname = $arg->{hostname}; +# my $status = $arg->{status}; +# my $passwd = $arg->{passwd}; +# my $mac_address = $arg->{mac_address}; +# my $events = $arg->{events}; +# +# if (not defined $hostname) { +# daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); +# return; +# } +# +# 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+=1; +# $month = $month < 10 ? $month = "0".$month : $month; +# $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; +# $year+=1900; +# my $t = "$year$month$monthday$hours$minutes$seconds"; +# +# $shmda->shlock(LOCK_EX); +# if (defined $status) { +# $known_daemons->{$hostname}->{status} = $status; +# } +# if (defined $passwd) { +# $known_daemons->{$hostname}->{passwd} = $passwd; +# } +# if (defined $mac_address) { +# $known_daemons->{$hostname}->{mac_address} = $mac_address; +# } +# if (defined $events) { +# $known_daemons->{$hostname}->{events} = $events; +# } +# $known_daemons->{$hostname}->{timestamp} = $t; +# $shmda->shlock(LOCK_EX); +# return; +#} #=== FUNCTION ================================================================ @@ -694,41 +658,41 @@ sub add_content2known_daemons { # RETURNS: nothing # DESCRIPTION: nome est omen and updates each time the timestamp of hostname #=============================================================================== -sub update_known_daemons { - my $arg = { - hostname => undef, status => undef, passwd => undef, - @_ }; - my $hostname = $arg->{hostname}; - my $status = $arg->{status}; - my $passwd = $arg->{passwd}; - - if (not defined $hostname) { - daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); - return; - } - - 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+=1; - $month = $month < 10 ? $month = "0".$month : $month; - $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; - $year+=1900; - my $t = "$year$month$monthday$hours$minutes$seconds"; - - $shmda->shlock(LOCK_EX); - if (defined $status) { - $known_daemons->{$hostname}->{status} = $status; - } - if (defined $passwd) { - $known_daemons->{$hostname}->{passwd} = $passwd; - } - $known_daemons->{$hostname}->{timestamp} = $t; - $shmda->shunlock(LOCK_EX); - return; -} +#sub update_known_daemons { +# my $arg = { +# hostname => undef, status => undef, passwd => undef, +# @_ }; +# my $hostname = $arg->{hostname}; +# my $status = $arg->{status}; +# my $passwd = $arg->{passwd}; +# +# if (not defined $hostname) { +# daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); +# return; +# } +# +# 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+=1; +# $month = $month < 10 ? $month = "0".$month : $month; +# $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; +# $year+=1900; +# my $t = "$year$month$monthday$hours$minutes$seconds"; +# +# $shmda->shlock(LOCK_EX); +# if (defined $status) { +# $known_daemons->{$hostname}->{status} = $status; +# } +# if (defined $passwd) { +# $known_daemons->{$hostname}->{passwd} = $passwd; +# } +# $known_daemons->{$hostname}->{timestamp} = $t; +# $shmda->shunlock(LOCK_EX); +# return; +#} #=== FUNCTION ================================================================ @@ -737,31 +701,31 @@ sub update_known_daemons { # RETURNS: nothing # DESCRIPTION: nomen est omen #=============================================================================== -sub print_known_clients { - - print "####################################\n"; - print "# status of known_clients\n"; - $shmcl->shlock(LOCK_EX); - my @hosts = keys %$known_clients; - if (@hosts) { - foreach my $host (@hosts) { - my $status = $known_clients->{$host}->{status} ; - my $passwd = $known_clients->{$host}->{passwd}; - my $timestamp = $known_clients->{$host}->{timestamp}; - my $mac_address = $known_clients->{$host}->{mac_address}; - my $events = $known_clients->{$host}->{events}; - print "$host\n"; - print "\tstatus: $status\n"; - print "\tpasswd: $passwd\n"; - print "\ttimestamp: $timestamp\n"; - print "\tmac_address: $mac_address\n"; - print "\tevents: $events\n"; - } - } - $shmcl->shunlock(LOCK_EX); - print "####################################\n"; - return; -} +#sub print_known_clients { +# +# print "####################################\n"; +# print "# status of known_clients\n"; +# $shmcl->shlock(LOCK_EX); +# my @hosts = keys %$known_clients; +# if (@hosts) { +# foreach my $host (@hosts) { +# my $status = $known_clients->{$host}->{status} ; +# my $passwd = $known_clients->{$host}->{passwd}; +# my $timestamp = $known_clients->{$host}->{timestamp}; +# my $mac_address = $known_clients->{$host}->{mac_address}; +# my $events = $known_clients->{$host}->{events}; +# print "$host\n"; +# print "\tstatus: $status\n"; +# print "\tpasswd: $passwd\n"; +# print "\ttimestamp: $timestamp\n"; +# print "\tmac_address: $mac_address\n"; +# print "\tevents: $events\n"; +# } +# } +# $shmcl->shunlock(LOCK_EX); +# print "####################################\n"; +# return; +#} #=== FUNCTION ================================================================ @@ -772,159 +736,58 @@ sub print_known_clients { #=============================================================================== sub create_known_client { my ($hostname) = @_; - $shmcl->shlock(LOCK_EX); - $known_clients->{$hostname} = {}; - $known_clients->{$hostname}->{status} = "none"; - $known_clients->{$hostname}->{passwd} = "none"; - $known_clients->{$hostname}->{timestamp} = "none"; - $known_clients->{$hostname}->{mac_address} = "none"; - $known_clients->{$hostname}->{events} = "none"; - $shmcl->shunlock(LOCK_EX); - return; -} - - -#=== FUNCTION ================================================================ -# NAME: add_content2known_clients -# PARAMETERS: hostname - string - ip address and port of host (required) -# status - string - (optional) -# passwd - string - (optional) -# mac_address - string - (optional) -# events - string - event of client, executable skripts -# under /etc/gosac/events -# RETURNS: nothing -# DESCRIPTION: nome est omen and updates each time the timestamp of hostname -#=============================================================================== -sub add_content2known_clients { - my $arg = { - hostname => undef, status => undef, passwd => undef, - mac_address => undef, events => undef, - @_ }; - my $hostname = $arg->{hostname}; - my $status = $arg->{status}; - my $passwd = $arg->{passwd}; - my $mac_address = $arg->{mac_address}; - my $events = $arg->{events}; - - if (not defined $hostname) { - daemon_log("ERROR: function add_content2known_clients is not invoked with requiered parameter 'hostname'", 1); - return; - } - - 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+=1; - $month = $month < 10 ? $month = "0".$month : $month; - $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; - $year+=1900; - my $t = "$year$month$monthday$hours$minutes$seconds"; - - $shmcl->shlock(LOCK_EX); - if (defined $status) { - $known_clients->{$hostname}->{status} = $status; - } - if (defined $passwd) { - $known_clients->{$hostname}->{passwd} = $passwd; - } - if (defined $mac_address) { - $known_clients->{$hostname}->{mac_address} = $mac_address; - } - if (defined $events) { - $known_clients->{$hostname}->{events} = $events; - } - $known_clients->{$hostname}->{timestamp} = $t; - $shmcl->shlock(LOCK_EX); - return; -} - -#=== FUNCTION ================================================================ -# NAME: -# PARAMETERS: -# RETURNS: -# DESCRIPTION: -#=============================================================================== -sub clean_up_known_clients { - my ($address) = @_ ; - - if (not exists $known_clients->{$address}) { - daemon_log("cannot prune known_clients from $address, client not known", 5); - return; + my $entry = { table=>'known_clients', + hostname=>$hostname, + status=>'none', + hostkey=>'none', + timestamp=>'none', + macaddress=>'none', + events=>'none', + }; + my $res = $known_clients_db->add_dbentry($entry); + if ($res > 0) { + daemon_log("ERROR: cannot add entry to known_clients.db: $res", 1); } - delete $known_clients->{$address}; - - # send bus a msg that address was deleted from known_clients - my $out_hash = &create_xml_hash('delete_client', $server_address, $bus_address, $address); - &send_msg_hash2bus($out_hash); - - daemon_log("client $address deleted from known_clients because of multiple down time", 3); - return; -} - - -#=== FUNCTION ================================================================ -# NAME: update_known_clients -# PARAMETERS: hostname - string - ip address and port of host (required) -# status - string - (optional) -# passwd - string - (optional) -# client - string - ip address and port of client (optional) -# RETURNS: nothing -# DESCRIPTION: nome est omen and updates each time the timestamp of hostname -#=============================================================================== -sub update_known_clients { - my $arg = { - hostname => undef, status => undef, passwd => undef, - mac_address => undef, events => undef, - @_ }; - my $hostname = $arg->{hostname}; - my $status = $arg->{status}; - my $passwd = $arg->{passwd}; - my $mac_address = $arg->{mac_address}; - my $events = $arg->{events}; - - if (not defined $hostname) { - daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); - return; - } - - 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+=1; - $month = $month < 10 ? $month = "0".$month : $month; - $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; - $year+=1900; - my $t = "$year$month$monthday$hours$minutes$seconds"; - - $shmcl->shlock(LOCK_EX); - if (defined $status) { - $known_clients->{$hostname}->{status} = $status; - } - if (defined $passwd) { - $known_clients->{$hostname}->{passwd} = $passwd; - } - if (defined $mac_address) { - $known_clients->{$hostname}->{mac_address} = $mac_address; - } - if (defined $events) { - $known_clients->{$hostname}->{events} = $events; - } - $known_clients->{$hostname}->{timestamp} = $t; - $shmcl->shunlock(LOCK_EX); - return; + return; } - - - - - +#sub sysreadline(*;$) { +# my ($hd, $timeout) = @_; +# +# $hd = qualify_to_ref($hd, caller()); +# my $infinitely_patient = (@_ == 1 || $timeout < 0); +# my $start_time = time(); +# my $selector = IO::Select->new(); +# $selector->add($hd); +# my $line = ""; +# +#SLEEP: +# until( at_eol($line)) { +# if (not $infinitely_patient) { +# return $line if time() > ($start_time + $timeout); +# } +# next SLEEP unless $selector->can_read(1.0); +#INPUT_READY: +# while( $selector->can_read(0.0)) { +# my $was_blocking = $hd->blocking(0); +#CHAR: while (sysread($hd, my $nextbyte, 1)) { +# $line .= $nextbyte; +# last CHAR if $nextbyte eq "\n"; +# +# } +# $hd->blocking($was_blocking); +# next SLEEP unless at_eol($line); +# last INPUT_READY; +# } +# } +# return $line; +#} +# +#sub at_eol($) { +# $_[0] =~ /\n\z/ ; +#} #==== MAIN = main ============================================================== @@ -945,31 +808,58 @@ GetOptions("h|help" => \&usage, $SIG{CHLD} = 'IGNORE'; -# restart daemon log file -if(-e $log_file ) { unlink $log_file } -daemon_log(" ", 1); -daemon_log("$0 started!", 1); +# forward error messages to logfile +if( ! $foreground ) { + open(STDERR, '>>', $log_file); + open(STDOUT, '>>', $log_file); +} -# Just fork, if we"re not in foreground mode -if( ! $foreground ) { $pid = fork(); } -else { $pid = $$; } +# Just fork, if we are not in foreground mode +if( ! $foreground ) { + chdir '/' or die "Can't chdir to /: $!"; + $pid = fork; + setsid or die "Can't start a new session: $!"; + umask 0; +} else { + $pid = $$; +} # 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 ); - if( !$foreground ) { exit( 0 ) }; + close( LOCK_FILE ); + if( !$foreground ) { + exit( 0 ) + }; } +daemon_log(" ", 1); +daemon_log("$0 started!", 1); + +# delete old DBsqlite lock files +system('rm -f /tmp/gosa_si_lock*'); + +# connect to gosa-si job queue +my @job_col_names = ("id", "timestamp", "status", "result", "headertag", "targettag", "xmlmessage", "macaddress"); +$job_db = GOSA::DBsqlite->new($job_queue_file_name); +$job_db->create_table('jobs', \@job_col_names); + +# connect to known_clients_db +my @clients_col_names = ('hostname', 'status', 'hostkey', 'timestamp', 'macaddress', 'events'); +$known_clients_db = GOSA::DBsqlite->new($known_clients_file_name); +$known_clients_db->create_table('known_clients', \@clients_col_names); + +# connect to known_server_db +my @server_col_names = ('hostname', 'status', 'hostkey', 'timestamp'); +$known_server_db = GOSA::DBsqlite->new($known_server_file_name); +$known_server_db->create_table('known_server', \@server_col_names); + # import all modules &import_modules; # check wether all modules are gosa-si valid passwd check -# connect to gosa-si job queue -my $job_db = GOSA::DBsqlite->new($job_queue_file_name); - # create reading and writing vectors my $rbits = my $wbits = my $ebits = ""; @@ -996,7 +886,6 @@ while( my ($mod_name, $info) = each %$known_modules ) { #} # - ################################## #everything ready, okay, lets start ################################## @@ -1025,28 +914,28 @@ while(1) { } - if($arp_activ eq "on" && vec($rout, fileno $arp_fifo, 1)) { - my $in_msg = <$arp_fifo>; - chomp($in_msg); - print "arp_activ: msg: $in_msg\n"; - my $act_passwd = $known_daemons->{$bus_address}->{passwd}; - print "arp_activ: arp_passwd: $act_passwd\n"; - - my $in_msg_hash = $xml->XMLin($in_msg, ForceArray=>1); - - my $target = &get_content_from_xml_hash($in_msg_hash, 'target'); - - if ($target eq $server_address) { - print "arp_activ: forward to server\n"; - my $arp_cipher = &create_ciphering($act_passwd); - my $crypted_msg = &encrypt_msg($in_msg, $arp_cipher); - &activating_child($crypted_msg, $server_ip); - } else { - print "arp_activ: send to bus\n"; - &send_msg_hash2address($in_msg_hash, $bus_address); - } - print "\n"; - } +# if($arp_activ eq "on" && vec($rout, fileno $arp_fifo, 1)) { +# my $in_msg = <$arp_fifo>; +# chomp($in_msg); +# print "arp_activ: msg: $in_msg\n"; +# my $act_passwd = $known_daemons->{$bus_address}->{passwd}; +# print "arp_activ: arp_passwd: $act_passwd\n"; +# +# my $in_msg_hash = $xml->XMLin($in_msg, ForceArray=>1); +# +# my $target = &get_content_from_xml_hash($in_msg_hash, 'target'); +# +# if ($target eq $server_address) { +# print "arp_activ: forward to server\n"; +# my $arp_cipher = &create_ciphering($act_passwd); +# my $crypted_msg = &encrypt_msg($in_msg, $arp_cipher); +# &activating_child($crypted_msg, $server_ip); +# } else { +# print "arp_activ: send to bus\n"; +# &send_msg_hash2address($in_msg_hash, $bus_address); +# } +# print "\n"; +# } # check input fhd of all modules @@ -1071,8 +960,6 @@ while(1) { daemon_log("cannot read from $actual_ip", 5); } } - #close($client); - } } @@ -1082,34 +969,30 @@ while(1) { if (vec($rout, fileno $fhd, 1) ) { daemon_log("process child $pid is ready to read", 5); - - $fhd->blocking(1); - my $in_msg = <$fhd>; - $fhd->blocking(0); - my $part_in_msg; - while ($part_in_msg = <$fhd>) { - if (not defined $part_in_msg) { + + my $in_msg; + while (1) { + my $part_in_msg = <$fhd>; + if( $part_in_msg eq "ENDMESSAGE\n") { last; } $in_msg .= $part_in_msg; } chomp($in_msg); - - daemon_log("process child read: $in_msg", 5); + if (not defined $in_msg) { next; } elsif ($in_msg =~ "done") { + daemon_log("process child read: $in_msg", 7); delete $busy_child{$pid}; $free_child{$pid} = $child_hash; - + } else { + daemon_log("process child read:", 7); + daemon_log("\n$in_msg", 8); # send computed answer back to connected client my $act_client = $busy_child{$pid}{client_ref}; print $act_client $in_msg."\n"; - - #my $act_pipe = $busy_child{$pid}{pipe_rd}; - sleep(10); - close ($act_client); delete $busy_child{$pid}; $free_child{$pid} = $child_hash; @@ -1130,57 +1013,61 @@ while(1) { my $timestamp = "$year$month$monthday$hours$minutes$seconds"; - my $sql = "SELECT * FROM '$job_queue_table_name' WHERE status='waiting' AND timestamp<'$timestamp'"; - my $res = $job_db->exec_statement($sql); - foreach my $msg (@{$res}) { - - my $jobdb_id = @{$msg}[0]; - my $job_msg_hash = &transform_msg2hash(@{$msg}[6]); + my $res = $job_db->select_dbentry( { table=>$job_queue_table_name, status=>'waiting', timestamp=>$timestamp } ); + + while( my ($id, $hit) = each %{$res} ) { + + my $jobdb_id = $hit->{id}; + my $macaddress = $hit->{macaddress}; + my $job_msg_hash = &transform_msg2hash($hit->{xmlmessage}); my $out_msg_hash = $job_msg_hash; - - # hole mac address und suche die entsprechende ip addresse - my $target; - my @hostnames = keys %{$known_clients}; - foreach my $hostname (@hostnames) { - if ($known_clients->{$hostname}->{mac_address} eq $job_msg_hash->{mac}[0]) { - $target = $hostname; - last; - } - } + my $res_hash = $known_clients_db->select_dbentry( {table=>'known_clients', macaddress=>$macaddress} ); + # expect macaddress is unique!!!!!! + my $target = $res_hash->{1}->{hostname}; if (not defined $target) { &daemon_log("ERROR: no host found for mac address: $job_msg_hash->{mac}[0]", 1); + &daemon_log("xml message: $hit->{xmlmessage}", 5); + my $update_hash = { table=>$job_queue_table_name, + update=> [ { status=>['error'], result=>["no host found for mac address"] } ], + where=> [ { id=>[$jobdb_id] } ], + }; + my $res = $job_db->update_dbentry($update_hash); + next; } # add target - print "select: target: $target\n"; &add_content2xml_hash($out_msg_hash, "target", $target); # add new header my $out_header = $job_msg_hash->{header}[0]; $out_header =~ s/job_/gosa_/; - print "select: header: $out_header\n"; delete $out_msg_hash->{header}; &add_content2xml_hash($out_msg_hash, "header", $out_header); # add sqlite_id &add_content2xml_hash($out_msg_hash, "jobdb_id", $jobdb_id); -# my $out_msg = &create_xml_string($out_msg_hash); -# -# # encrypt msg as a GosaPackage module -# my $cipher = &create_ciphering($gosa_passwd); -# my $crypted_out_msg = &encrypt_msg($out_msg, $cipher); + my $out_msg = &create_xml_string($out_msg_hash); + + # encrypt msg as a GosaPackage module + my $cipher = &create_ciphering($gosa_passwd); + my $crypted_out_msg = &encrypt_msg($out_msg, $cipher); my $error = &send_msg_hash2address($out_msg_hash, "$gosa_ip:$gosa_port", $gosa_passwd); if ($error == 0) { - my $sql = "UPDATE '$job_queue_table_name' SET status='processing', target='$target' WHERE id='$jobdb_id'"; + my $sql = "UPDATE '$job_queue_table_name' SET status='processing', targettag='$target' WHERE id='$jobdb_id'"; my $res = $job_db->exec_statement($sql); + } else { + my $update_hash = { table=>$job_queue_table_name, + update=> [ { status=>'error' } ], + where=> [ { id=>$jobdb_id } ], + }; + my $res = $job_db->update_dbentry($update_hash); } - }