From 2052d150f05495b25d4c41248a7c2420619d73b0 Mon Sep 17 00:00:00 2001 From: rettenbe Date: Thu, 10 Jan 2008 13:09:28 +0000 Subject: [PATCH] switch known_server from shared memory to sqliteDB git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@8289 594d385d-05f5-0310-b6e9-bd551577e9d8 --- gosa-si/gosa-si-server | 41 ++-- gosa-si/modules/DBsqlite.pm | 78 ++++++-- gosa-si/modules/GosaSupportDaemon.pm | 84 +------- gosa-si/modules/ServerPackages.pm | 289 +++++++++++++++++---------- 4 files changed, 265 insertions(+), 227 deletions(-) diff --git a/gosa-si/gosa-si-server b/gosa-si/gosa-si-server index 2d4b84d48..6f54d2d06 100755 --- a/gosa-si/gosa-si-server +++ b/gosa-si/gosa-si-server @@ -94,22 +94,15 @@ our $job_db; # holds all other gosa-sd as well as the gosa-sd-bus our $known_server_db; -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_db; -#our $known_clients = {}; -#our $shmcl = tie($known_clients, 'IPC::Shareable', undef, {create => 1, +#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_db; %cfg_defaults = ("general" => @@ -121,7 +114,7 @@ our $known_clients_db; "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/kown_server.db'], + "known_server_file_name" => [\$known_server_file_name, '/var/lib/gosa-si/known_server.db'], }, "bus" => {"bus_activ" => [\$bus_activ, "on"], @@ -628,16 +621,16 @@ sub read_from_socket { # 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 ================================================================ @@ -1006,7 +999,9 @@ $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 = (); +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; diff --git a/gosa-si/modules/DBsqlite.pm b/gosa-si/modules/DBsqlite.pm index db717fa7d..840bce0d6 100644 --- a/gosa-si/modules/DBsqlite.pm +++ b/gosa-si/modules/DBsqlite.pm @@ -54,28 +54,68 @@ sub add_dbentry { } # check wether primkey is unique in table, otherwise return errorflag 3 - if ( defined $primkey ) { - my $res = @{ $obj->{dbh}->selectall_arrayref( "SELECT * FROM $table WHERE $primkey='$arg->{$primkey}'") }; - if ($res != 0) { - return 3; - } - } - - # fetch column names of table - my $col_names = $obj->get_table_columns($table); - - # assign values to column name variables - my @add_list; - foreach my $col_name (@{$col_names}) { + my $res = @{ $obj->{dbh}->selectall_arrayref( "SELECT * FROM $table WHERE $primkey='$arg->{$primkey}'") }; + if ($res == 0) { + # fetch column names of table + my $col_names = $obj->get_table_columns($table); + + # assign values to column name variables + my @add_list; + foreach my $col_name (@{$col_names}) { # use function parameter for column values - if (exists $arg->{$col_name}) { - push(@add_list, $arg->{$col_name}); + if (exists $arg->{$col_name}) { + push(@add_list, $arg->{$col_name}); + } + } + + my $sql_statement = " INSERT INTO $table VALUES ('".join("', '", @add_list)."')"; + my $db_res = $obj->{dbh}->do($sql_statement); + if( $db_res != 1 ) { + return 1; + } else { + return 0; } - } - my $sql_statement = " INSERT INTO $table VALUES ('".join("', '", @add_list)."')"; - my $db_res = $obj->{dbh}->do($sql_statement); - return 0; + } else { + my $update_hash = { table=>$table }; + $update_hash->{where} = [ { $primkey=>[ $arg->{$primkey} ] } ]; + $update_hash->{update} = [ {} ]; + while( my ($pram, $val) = each %{$arg} ) { + if( $pram eq 'table' ) { next; } + if( $pram eq 'primkey' ) { next; } + $update_hash->{update}[0]->{$pram} = [$val]; + } + my $db_res = &update_dbentry( $obj, $update_hash ); + if( $db_res != 1 ) { + return 1; + } else { + return 0; + } + + } +# # check wether primkey is unique in table, otherwise return errorflag 3 +# if ( defined $primkey ) { +# my $res = @{ $obj->{dbh}->selectall_arrayref( "SELECT * FROM $table WHERE $primkey='$arg->{$primkey}'") }; +# if ($res != 0) { +# return 3; +# } +# } +# +# # fetch column names of table +# my $col_names = $obj->get_table_columns($table); +# +# # assign values to column name variables +# my @add_list; +# foreach my $col_name (@{$col_names}) { +# # use function parameter for column values +# if (exists $arg->{$col_name}) { +# push(@add_list, $arg->{$col_name}); +# } +# } +# +# my $sql_statement = " INSERT INTO $table VALUES ('".join("', '", @add_list)."')"; +# my $db_res = $obj->{dbh}->do($sql_statement); +# return 0; } diff --git a/gosa-si/modules/GosaSupportDaemon.pm b/gosa-si/modules/GosaSupportDaemon.pm index 46f3d0904..bb3a30581 100644 --- a/gosa-si/modules/GosaSupportDaemon.pm +++ b/gosa-si/modules/GosaSupportDaemon.pm @@ -33,46 +33,6 @@ sub daemon_log { } -##=== FUNCTION ================================================================ -## NAME: logging -## PARAMETERS: level - string - default 'info' -## msg - string - -## facility - string - default 'LOG_DAEMON' -## RETURNS: nothing -## DESCRIPTION: function for logging -##=============================================================================== -#my $log_file = $main::log_file; -#my $verbose = $main::verbose; -#my $foreground = $main::forground; -#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); -# if($level <= $verbose){ -# print LOG_HANDLE "$level $msg\n"; -# if(defined $foreground) { print $msg."\n" } -# } -# } -# close( LOG_HANDLE ); -##log into syslog -## my ($msg, $level, $facility) = @_; -## if(not defined $msg) {return} -## if(not defined $level) {$level = "info"} -## if(not defined $facility) {$facility = "LOG_DAEMON"} -## openlog($0, "pid,cons,", $facility); -## syslog($level, $msg); -## closelog; -## return; -#} - - #=== FUNCTION ================================================================ # NAME: create_xml_hash # PARAMETERS: header - string - message header (required) @@ -90,9 +50,6 @@ sub create_xml_hash { target => [$target], $header => [$header_value], }; - #daemon_log("create_xml_hash:", 7), - #chomp(my $tmp = Dumper $hash); - #daemon_log("\t$tmp", 7); return $hash } @@ -121,19 +78,6 @@ sub send_msg_hash2address { # generate xml string my $msg_xml = &create_xml_string($msg_hash); - # fetch the appropriated passwd from hash - if(not defined $passwd) { - if(exists $main::known_daemons->{$address}) { - $passwd = $main::known_daemons->{$address}->{passwd}; - } elsif(exists $main::known_clients->{$address}) { - $passwd = $main::known_clients->{$address}->{passwd}; - - } else { - daemon_log("$address not known, neither as server nor as client", 1); - return 1; - } - } - # create ciphering object my $act_cipher = &create_ciphering($passwd); @@ -143,21 +87,7 @@ sub send_msg_hash2address { # opensocket my $socket = &open_socket($address); if(not defined $socket){ - daemon_log("cannot send '$header'-msg to $address , server not reachable", - 5); - -# if (exists $main::known_clients->{$address}) { -# if ($main::known_clients->{$address}->{status} eq "down") { -# # if status of not reachable client is already 'down', -# # then delete client from known_clients -# &clean_up_known_clients($address); -# -# } else { -# # update status to 'down' -# &update_known_clients(hostname=>$address, status=>"down"); -# -# } -# } + daemon_log("cannot send '$header'-msg to $address , server not reachable", 5); return 1; } @@ -167,19 +97,7 @@ sub send_msg_hash2address { close $socket; daemon_log("send '$header'-msg to $address", 1); - daemon_log("$msg_xml", 5); - - #daemon_log("crypted message:",7); - #daemon_log("\t$crypted_msg", 7); - - # update status of client in known_clients with last send msg -# if(exists $main::known_daemons->{$address}) { -# #&update_known_daemons(); -# } elsif(exists $main::known_clients->{$address}) { -# &main::update_known_clients(hostname=>$address, status=>$header); -# } - return 0; } diff --git a/gosa-si/modules/ServerPackages.pm b/gosa-si/modules/ServerPackages.pm index a1432ad00..ea9632d1e 100644 --- a/gosa-si/modules/ServerPackages.pm +++ b/gosa-si/modules/ServerPackages.pm @@ -26,9 +26,7 @@ my (@ldap_cfg, @pam_cfg, @nss_cfg, $goto_admin, $goto_secret); my %cfg_defaults = -("general" => - {"known_clients_file_name" => [\$known_clients_file_name, '/var/lib/gosa-si/known_clients.db' ], - }, +( "server" => {"server_activ" => [\$server_activ, "on"], "server_port" => [\$server_port, "20081"], @@ -83,8 +81,8 @@ if($server_activ eq "on"){ } } -# connect to known_clients_db -#my $known_clients_db = GOSA::DBsqlite->new($known_clients_file_name); +# TODO +# füge den server selbst zu known_server hinzu, msgs können nämlich auch von sich selbst kommen (gosa!!!) # register at bus @@ -233,17 +231,31 @@ sub open_socket { #=============================================================================== sub register_at_bus { - # create known_daemons entry - &main::create_known_daemon($bus_address); - &main::add_content2known_daemons(hostname=>$bus_address, status=>"register_at_bus", passwd=>$bus_passwd); + # add bus to known_server_db + my $res = $main::known_server_db->add_dbentry( {table=>'known_server', + primkey=>'hostname', + hostname=>$bus_address, + status=>'bus', + hostkey=>$bus_passwd, + timestamp=>&get_time, + } ); +# if ($res == 3) { +# my $update_hash = { table=>'known_server' }; +# $update_hash->{where} = [ { hostname=>[$bus_address] } ]; +# $update_hash->{update} = [ { +# hostkey=>[$bus_passwd], +# timestamp=>[&get_time], +# } ]; +# $res = $main::known_server_db->update_dbentry( $update_hash ); +# } my $msg_hash = &create_xml_hash("here_i_am", $server_address, $bus_address); my $answer = ""; - $answer = &send_msg_hash2address($msg_hash, $bus_address); + $answer = &send_msg_hash2address($msg_hash, $bus_address, $bus_passwd); if ($answer == 0) { &main::daemon_log("register at bus: $bus_address", 1); } else { - &main::daemon_log("unable to send 'register'-msg to bus: $bus_address", 1); + &main::daemon_log("unable to send 'register'-msg to bus '$bus_address': $answer", 1); } return; } @@ -266,56 +278,89 @@ sub process_incoming_msg { $crypted_msg = $1; my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5); - # collect addresses from possible incoming clients - my @valid_keys; - my @host_keys = keys %$main::known_daemons; - foreach my $host_key (@host_keys) { - if($host_key =~ "^$host") { - push(@valid_keys, $host_key); - } - } - my @client_keys = keys %$main::known_clients; - foreach my $client_key (@client_keys) { - if($client_key =~ "^$host"){ - push(@valid_keys, $client_key); + my $msg; + my $msg_hash; + my $host_name; + my $host_key; + + # check wether incoming msg is a new msg + $host_name = $server_address; + $host_key = $server_passwd; + &main::daemon_log("ServerPackage: host_name: $host_name", 7); + &main::daemon_log("ServerPackage: host_key: $host_key", 7); + eval{ + my $key_cipher = &create_ciphering($host_key); + $msg = &decrypt_msg($crypted_msg, $key_cipher); + $msg_hash = &transform_msg2hash($msg); + }; + if($@) { + &main::daemon_log("ServerPackage: deciphering raise error", 7); + &main::daemon_log("$@", 8); + $msg = undef; + $msg_hash = undef; + $host_name = undef; + $host_key = undef; + } + + # check wether incoming msg is from a known_server + if( not defined $msg ) { + my $query_res = $main::known_server_db->select_dbentry( {table=>'known_server'} ); + while( my ($hit_num, $hit) = each %{ $query_res } ) { + $host_name = $hit->{hostname}; + if( not $host_name =~ "^$host") { + next; + } + $host_key = $hit->{hostkey}; + &main::daemon_log("ServerPackage: host_name: $host_name", 7); + &main::daemon_log("ServerPackage: host_key: $host_key", 7); + eval{ + my $key_cipher = &create_ciphering($host_key); + $msg = &decrypt_msg($crypted_msg, $key_cipher); + $msg_hash = &transform_msg2hash($msg); + }; + if($@) { + &main::daemon_log("ServerPackage: deciphering raise error", 7); + &main::daemon_log("$@", 8); + $msg = undef; + $msg_hash = undef; + $host_name = undef; + $host_key = undef; + } else { + last; + } } } - push(@valid_keys, $server_address); - - my $l = @valid_keys; - my $msg_hash; - my $msg_flag = 0; - my $msg = ""; - # determine the correct passwd for deciphering of the incoming msgs - foreach my $host_key (@valid_keys) { - eval{ + # check wether incoming msg is from a known_client + if( not defined $msg ) { + my $query_res = $main::known_clients_db->select_dbentry( {table=>'known_clients'} ); + while( my ($hit_num, $hit) = each %{ $query_res } ) { + $host_name = $hit->{hostname}; + if( not $host_name =~ "^$host") { + next; + } + $host_key = $hit->{hostkey}; + &main::daemon_log("ServerPackage: host_name: $host_name", 7); &main::daemon_log("ServerPackage: host_key: $host_key", 7); - my $key_passwd; - if (exists $main::known_daemons->{$host_key}) { - $key_passwd = $main::known_daemons->{$host_key}->{passwd}; - } elsif (exists $main::known_clients->{$host_key}) { - $key_passwd = $main::known_clients->{$host_key}->{passwd}; - } elsif ($host_key eq $server_address) { - $key_passwd = $server_passwd; - } - &main::daemon_log("ServerPackage: key_passwd: $key_passwd", 7); - my $key_cipher = &create_ciphering($key_passwd); - $msg = &decrypt_msg($crypted_msg, $key_cipher); - &main::daemon_log("ServerPackages: decrypted msg: \n$msg", 7); - $msg_hash = $xml->XMLin($msg, ForceArray=>1); - #my $tmp = printf Dumper $msg_hash; - #&main::daemon_log("DEBUG: ServerPackages: xml hash: $tmp", 7); - }; - if($@) { - &main::daemon_log("ServerPackage: key raise error: $@", 7); - $msg_flag += 1; - } else { - last; + eval{ + my $key_cipher = &create_ciphering($host_key); + $msg = &decrypt_msg($crypted_msg, $key_cipher); + $msg_hash = &transform_msg2hash($msg); + }; + if($@) { + &main::daemon_log("ServerPackage: deciphering raise error", 7); + &main::daemon_log("$@", 8); + $msg = undef; + $msg_hash = undef; + $host_name = undef; + $host_key = undef; + } else { + last; + } } - } - - if($msg_flag >= $l) { + } + + if( not defined $msg ) { &main::daemon_log("WARNING: ServerPackage do not understand the message:", 5); &main::daemon_log("$@", 7); return; @@ -335,16 +380,11 @@ sub process_incoming_msg { } elsif ($len_targets == 1){ # we have only one target symbol - my $target = $targets[0]; &main::daemon_log("SeverPackages: msg is for: $target", 7); - # msg is for server if ($target eq $server_address) { - - # msg is a event - - # msg is a hard implemented function + # msg is for server if ($header eq 'new_passwd'){ &new_passwd($msg_hash)} elsif ($header eq 'here_i_am') { &here_i_am($msg_hash)} elsif ($header eq 'who_has') { &who_has($msg_hash) } @@ -354,28 +394,40 @@ sub process_incoming_msg { elsif ($header eq 'get_load') { &execute_actions($msg_hash)} else { &main::daemon_log("ERROR: ServerPackages: no function assigned to this msg", 5) } - - # msg is for all clients } elsif ($target eq "*") { - my @target_addresses = keys(%$main::known_clients); - foreach my $target_address (@target_addresses) { - if ($target_address eq $source) { next; } - $msg_hash->{target} = [$target_address]; - &send_msg_hash2address($msg_hash, $target_address); - } - - # msg is for one host + # msg is for all clients + my $query_res = $main::known_clients_db->select_dbentry( {table=>'known_clients'} ); + while( my ($hit_num, $hit) = each %{ $query_res } ) { + $host_name = $hit->{hostname}; + $host_key = $hit->{hostkey}; + $msg_hash->{target} = [$host_name]; + &send_msg_hash2address($msg_hash, $host_name, $host_key); + } + return; + } else { - if (exists $main::known_clients->{$target}) { - &send_msg_hash2address($msg_hash, $target); - } elsif (exists $main::known_daemons->{$target}) { - # target is known - &send_msg_hash2address($msg_hash, $target); - } else { - # target is not known - &main::daemon_log("ERROR: ServerPackages: target $target is not known neither in known_clients nor in known_daemons", 1); + # msg is for one host + my $query_res = $main::known_clients_db->select_dbentry( {table=>'known_clients', hostname=>$target} ); + if( 1 == keys %{$query_res} ) { + $host_key = $query_res->{1}->{host_key}; + &send_msg_hash2address($msg_hash, $target, $host_key); + return; } + + my $query_res = $main::known_server_db->select_dbentry( {table=>'known_server', hostname=>$target} ); + if( 1 == keys %{$query_res} ) { + $host_key = $query_res->{1}->{host_key}; + &send_msg_hash2address($msg_hash, $target, $host_key); + return; + } + + &main::daemon_log("ERROR: ServerPackages: target '$target' is not known neither in known_clients nor in known_server",1); + return; } + + } elsif ($len_targets > 1 ) { + # we have more than one target + return; } return ; @@ -414,21 +466,54 @@ sub got_ping { sub new_passwd { my ($msg_hash) = @_; - my $source = @{$msg_hash->{source}}[0]; - my $passwd = @{$msg_hash->{new_passwd}}[0]; - - if (exists $main::known_daemons->{$source}) { - &main::add_content2known_daemons(hostname=>$source, status=>"new_passwd", passwd=>$passwd); - my $hash = &create_xml_hash("confirm_new_passwd", $server_address, $source); - &send_msg_hash2address($hash, $source); + my $header = @{$msg_hash->{header}}[0]; + my $source_name = @{$msg_hash->{source}}[0]; + my $source_key = @{$msg_hash->{new_passwd}}[0]; + my $query_res; - } elsif (exists $main::known_clients->{$source}) { - &main::add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd); + # check known_clients_db + $query_res = $main::known_clients_db->select_dbentry( {table=>'known_clients', hostname=>$source_name} ); + if( 1 == keys %{$query_res} ) { + my $update_hash = { table=>'known_clients' }; + $update_hash->{where} = [ { hostname=>[$source_name] } ]; + $update_hash->{update} = [ { + hostkey=>[$source_key], + timestamp=>[&get_time], + } ]; + my $res = $main::known_clients_db->update_dbentry( $update_hash ); + + my $hash = &create_xml_hash("confirm_new_passwd", $server_address, $source_name); + &send_msg_hash2address($hash, $source_name, $source_key); + return; + } - } else { - &main::daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1) + # check known_server_db + $query_res = $main::known_server_db->select_dbentry( {table=>'known_server', hostname=>$source_name } ); + if( 1 == keys %{$query_res} ) { + my $update_hash = { table=>'known_server' }; + $update_hash->{where} = [ { hostname=>[$source_name] } ]; + $update_hash->{update} = [ { + hostkey=>[$source_key], + timestamp=>[&get_time], + } ]; + my $res = $main::known_server_db->update_dbentry( $update_hash ); + + my $hash = &create_xml_hash("confirm_new_passwd", $server_address, $source_name); + &send_msg_hash2address($hash, $source_name, $source_key); + return; } + &main::daemon_log("ERROR: $source_name not known for '$header'-msg", 1); + return; +} + + +sub send_msg_hash { + my ($hash, $host_name, $host_key); + + + my $answer = &send_msg_hash2address($hash, $host_name, $host_key); + return; } @@ -473,7 +558,7 @@ sub here_i_am { # new client accepted my $new_passwd = @{$msg_hash->{new_passwd}}[0]; - # create known_daemons entry + # create entry in known_clients my $events = @{$msg_hash->{events}}[0]; # add entry to known_clients_db @@ -486,17 +571,17 @@ sub here_i_am { hostkey=>$new_passwd, timestamp=>&get_time, } ); - if ($res == 3) { - my $update_hash = { table=>'known_clients' }; - $update_hash->{where} = [ { hostname=>[$source] } ], - $update_hash->{update} = [ { events=>[$events], - macaddress=>[$mac_address], - status=>['registered'], - hostkey=>[$new_passwd], - timestamp=>[&get_time], - } ]; - $res = $main::known_clients_db->update_dbentry( $update_hash ); - } +# if ($res == 3) { +# my $update_hash = { table=>'known_clients' }; +# $update_hash->{where} = [ { hostname=>[$source] } ]; +# $update_hash->{update} = [ { events=>[$events], +# macaddress=>[$mac_address], +# status=>['registered'], +# hostkey=>[$new_passwd], +# timestamp=>[&get_time], +# } ]; +# $res = $main::known_clients_db->update_dbentry( $update_hash ); +# } if ($res != 1) { &main::daemon_log("ERROR: cannot add entry to known_clients: $res"); return; -- 2.30.2