Code

add xml-message gosa_count_jobdb to GosaPackages
[gosa.git] / gosa-si / modules / ServerPackages.pm
index 846eed111f3acbc65ec3c8868647b89d553be24e..ceb9268257eeaee5302622ae0bacf1380a79a385 100644 (file)
@@ -3,7 +3,7 @@ package ServerPackages;
 use Exporter;
 @ISA = ("Exporter");
 
-# Each module has to have a function 'process_incoming_msg'. This function works as a interface to gosa-sd and recieves the msg hash from gosa-sd. 'process_incoming_function checks, wether it has a function to process the incoming msg and forward the msg to it. 
+# Each module has to have a function 'process_incoming_msg'. This function works as a interface to gosa-sd and receives the msg hash from gosa-sd. 'process_incoming_function checks, wether it has a function to process the incoming msg and forward the msg to it. 
 
 
 use strict;
@@ -11,21 +11,28 @@ use warnings;
 use GOSA::GosaSupportDaemon;
 use IO::Socket::INET;
 use XML::Simple;
+use Data::Dumper;
 use Net::LDAP;
+use Socket qw/PF_INET SOCK_DGRAM inet_ntoa sockaddr_in/;
 
 BEGIN{}
 END {}
 
-
-my ($server_activ, $server_port, $server_passwd, $max_clients, $ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password);
+my ($known_clients_file_name);
+my ($server_activ, $server_ip, $server_mac_address, $server_port, $server_passwd, $max_clients, $ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password);
 my ($bus_activ, $bus_passwd, $bus_ip, $bus_port);
 my $server;
+my $network_interface;
 my $no_bus;
 my (@ldap_cfg, @pam_cfg, @nss_cfg, $goto_admin, $goto_secret);
 
+
 my %cfg_defaults =
-("server" =>
+(
+"server" =>
     {"server_activ" => [\$server_activ, "on"],
+    "server_ip" => [\$server_ip, "0.0.0.0"],
+    "server_mac_address" => [\$server_mac_address, ""],
     "server_port" => [\$server_port, "20081"],
     "server_passwd" => [\$server_passwd, ""],
     "max_clients" => [\$max_clients, 100],
@@ -44,17 +51,12 @@ my %cfg_defaults =
 
 ### START #####################################################################
 
-
 # read configfile and import variables
 &read_configfile();
 
-# detect own ip and mac address
-my ($server_ip, $server_mac_address) = &get_ip_and_mac(); 
-if (not defined $server_ip) {
-    die "EXIT: ip address of $0 could not be detected";
-}
-&main::daemon_log("server ip address detected: $server_ip", 1);
-&main::daemon_log("server mac address detected: $server_mac_address", 1);
+# detect interfaces and mac address
+$network_interface= &get_interface_for_ip($server_ip);
+$server_mac_address= &get_mac($network_interface); 
 
 # complete addresses
 my $server_address = "$server_ip:$server_port";
@@ -63,44 +65,16 @@ my $bus_address = "$bus_ip:$bus_port";
 # create general settings for this module
 my $xml = new XML::Simple();
 
-# open server socket
-if($server_activ eq "on"){
-    &main::daemon_log(" ", 1);
-    $server = IO::Socket::INET->new(LocalPort => $server_port,
-            Type => SOCK_STREAM,
-            Reuse => 1,
-            Listen => 20,
-            ); 
-    if(not defined $server){
-        &main::daemon_log("cannot be a tcp server at $server_port : $@");
-    } else {
-        &main::daemon_log("start server: $server_address", 1);
-    }
-}
-
 # register at bus
 if ($main::no_bus > 0) {
     $bus_activ = "off"
 }
 if($bus_activ eq "on") {
-    &main::daemon_log(" ", 1);
     &register_at_bus();
 }
 
 ### functions #################################################################
 
-#sub get_module_tags {
-#    
-#    # lese config file aus dort gibt es eine section Basic
-#    # dort stehen drei packettypen, für die sich das modul anmelden kann, gosa-admin-packages, 
-#    #   server-packages, client-packages
-#    my %tag_hash = (gosa_admin_packages => "yes", 
-#                    server_packages => "yes", 
-#                    client_packages => "yes",
-#                    );
-#    return \%tag_hash;
-#}
-
 
 sub get_module_info {
     my @info = ($server_address,
@@ -164,32 +138,126 @@ sub read_configfile {
 
 }
 
+#===  FUNCTION  ================================================================
+#         NAME:  get_interface_for_ip
+#   PARAMETERS:  ip address (i.e. 192.168.0.1)
+#      RETURNS:  array: list of interfaces if ip=0.0.0.0, matching interface if found, undef else
+#  DESCRIPTION:  Uses proc fs (/proc/net/dev) to get list of interfaces.
+#===============================================================================
+sub get_interface_for_ip {
+       my $result;
+       my $ip= shift;
+       if ($ip && length($ip) > 0) {
+               my @ifs= &get_interfaces();
+               if($ip eq "0.0.0.0") {
+                       $result = "all";
+               } else {
+                       foreach (@ifs) {
+                               my $if=$_;
+                               if(get_ip($if) eq $ip) {
+                                       $result = $if;
+                               }
+                       }       
+               }
+       }       
+       return $result;
+}
 
 #===  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
+#         NAME:  get_interfaces 
+#   PARAMETERS:  none
+#      RETURNS:  (list of interfaces) 
+#  DESCRIPTION:  Uses proc fs (/proc/net/dev) to get list of interfaces.
 #===============================================================================
-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);
+sub get_interfaces {
+       my @result;
+       my $PROC_NET_DEV= ('/proc/net/dev');
+
+       open(PROC_NET_DEV, "<$PROC_NET_DEV")
+               or die "Could not open $PROC_NET_DEV";
+
+       my @ifs = <PROC_NET_DEV>;
+
+       close(PROC_NET_DEV);
+
+       # Eat first two line
+       shift @ifs;
+       shift @ifs;
+
+       chomp @ifs;
+       foreach my $line(@ifs) {
+               my $if= (split /:/, $line)[0];
+               $if =~ s/^\s+//;
+               push @result, $if;
+       }
+
+       return @result;
 }
 
+#===  FUNCTION  ================================================================
+#         NAME:  get_mac 
+#   PARAMETERS:  interface name (i.e. eth0)
+#      RETURNS:  (mac address) 
+#  DESCRIPTION:  Uses ioctl to get mac address directly from system.
+#===============================================================================
+sub get_mac {
+       my $ifreq= shift;
+       my $result;
+       if ($ifreq && length($ifreq) > 0) { 
+               if($ifreq eq "all") {
+                       $result = "00:00:00:00:00:00";
+               } else {
+                       my $SIOCGIFHWADDR= 0x8927;     # man 2 ioctl_list
+
+                       # A configured MAC Address should always override a guessed value
+                       if ($server_mac_address and length($server_mac_address) > 0) {
+                               $result= $server_mac_address;
+                       }
+
+                       socket SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('ip')
+                               or die "socket: $!";
+
+                       if(ioctl SOCKET, $SIOCGIFHWADDR, $ifreq) {
+                               my ($if, $mac)= unpack 'h36 H12', $ifreq;
+
+                               if (length($mac) > 0) {
+                                       $mac=~ m/^([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/;
+                                       $mac= sprintf("%s:%s:%s:%s:%s:%s", $1, $2, $3, $4, $5, $6);
+                                       $result = $mac;
+                               }
+                       }
+               }
+       }
+       return $result;
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_ip 
+#   PARAMETERS:  interface name (i.e. eth0)
+#      RETURNS:  (ip address) 
+#  DESCRIPTION:  Uses ioctl to get ip address directly from system.
+#===============================================================================
+sub get_ip {
+       my $ifreq= shift;
+       my $result= "";
+       my $SIOCGIFADDR= 0x8915;       # man 2 ioctl_list
+       my $proto= getprotobyname('ip');
+
+       socket SOCKET, PF_INET, SOCK_DGRAM, $proto
+               or die "socket: $!";
+
+       if(ioctl SOCKET, $SIOCGIFADDR, $ifreq) {
+               my ($if, $sin)    = unpack 'a16 a16', $ifreq;
+               my ($port, $addr) = sockaddr_in $sin;
+               my $ip            = inet_ntoa $addr;
+
+               if ($ip && length($ip) > 0) {
+                       $result = $ip;
+               }
+       }
+
+       return $result;
+}
 
 #===  FUNCTION  ================================================================
 #         NAME:  open_socket
@@ -198,23 +266,23 @@ sub get_ip_and_mac {
 #      RETURNS:  socket IO::Socket::INET
 #  DESCRIPTION:  open a socket to PeerAddr
 #===============================================================================
-sub open_socket {
-    my ($PeerAddr, $PeerPort) = @_ ;
-    if(defined($PeerPort)){
-        $PeerAddr = $PeerAddr.":".$PeerPort;
-    }
-    my $socket;
-    $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
-            Porto => "tcp" ,
-            Type => SOCK_STREAM,
-            Timeout => 5,
-            );
-    if(not defined $socket) {
-        return;
-    }
-    &main::daemon_log("open_socket to: $PeerAddr", 7);
-    return $socket;
-}
+#sub open_socket {
+#    my ($PeerAddr, $PeerPort) = @_ ;
+#    if(defined($PeerPort)){
+#        $PeerAddr = $PeerAddr.":".$PeerPort;
+#    }
+#    my $socket;
+#    $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
+#            Porto => "tcp" ,
+#            Type => SOCK_STREAM,
+#            Timeout => 5,
+#            );
+#    if(not defined $socket) {
+#        return;
+#    }
+#    &main::daemon_log("open_socket to: $PeerAddr", 7);
+#    return $socket;
+#}
 
 #===  FUNCTION  ================================================================
 #         NAME:  register_at_bus
@@ -224,17 +292,26 @@ 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);
 
+
+    print STDERR ">>>>>>>>>>>>>>>>>>>>>>>>1\n";    
+
+    # 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,
+                                                } );
+    print STDERR ">>>>>>>>>>>>>>>>>>>>>>>>2\n";    
     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;
 }
@@ -251,62 +328,104 @@ sub process_incoming_msg {
         &main::daemon_log("function 'process_incoming_msg': got no msg", 7);
     }
 
+    &main::daemon_log("ServerPackages: incoming msg: \n$crypted_msg", 8);
+
     $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
     $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 $host="0.0.0.0";
+       if($1 && $2 && $3 && $4) {
+               $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
+       }
+
+    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'} ); 
+        my $sql_statement= "SELECT * FROM known_server";
+        my $query_res = $main::known_server_db->select_dbentry( $sql_statement ); 
+        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'} ); 
+        my $sql_statement= "SELECT * FROM known_clients";
+        my $query_res = $main::known_clients_db->select_dbentry( $sql_statement ); 
+        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: $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);
+        &main::daemon_log("$@", 8);
         return;
     }
 
@@ -314,13 +433,8 @@ sub process_incoming_msg {
     my $header = @{$msg_hash->{header}}[0]; 
     my $source = @{$msg_hash->{source}}[0];
 
-    &main::daemon_log("recieve '$header' at ServerPackages from $host", 1);
-#    &main::daemon_log("ServerPackages: msg from host:", 5);
-#    &main::daemon_log("\t$host", 5);
-#    &main::daemon_log("ServerPackages: header from msg:", 5);
-#    &main::daemon_log("\t$header", 5);
-    &main::daemon_log("ServerPackages: msg to process:", 5);
-    &main::daemon_log("\t$msg", 5);
+    &main::daemon_log("receive '$header' at ServerPackages from $host", 1);
+    &main::daemon_log("ServerPackages: msg to process: \n$msg", 5);
 
     my @targets = @{$msg_hash->{target}};
     my $len_targets = @targets;
@@ -329,45 +443,62 @@ 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:", 7);
-        &main::daemon_log("\t$target", 7);
-
-        if ($target eq $server_address) {
-            # 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) }
-            elsif ($header eq 'who_has_i_do') { &who_has_i_do($msg_hash)}
-            elsif ($header eq 'update_status') { &update_status($msg_hash) }
-            elsif ($header eq 'got_ping') { &got_ping($msg_hash)}
-            elsif ($header eq 'get_load') { &execute_actions($msg_hash)}
-            else { &main::daemon_log("ERROR: ServerPackages: no function assigned to this msg", 5) }
-
-        
-       } elsif ($target eq "*") {
-            # msg is for all clients
-
-            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);
-            }           
-        } else {
-            # msg is for one host
+        &main::daemon_log("SeverPackages: msg is for: $target", 7);
+
+        # 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) }
+        elsif ($header eq 'who_has_i_do') { &who_has_i_do($msg_hash)}
+        elsif ($header eq 'update_status') { &update_status($msg_hash) }
+        elsif ($header eq 'got_ping') { &got_ping($msg_hash)}
+        elsif ($header eq 'get_load') { &execute_actions($msg_hash)}
+        else { 
+            if ($target eq "*") {
+                # msg is for all clients
+                my $sql_statement = "SELECT * FROM known_clients";
+                my $query_res = $main::known_clients_db->select_dbentry( $sql_statement ); 
+                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);
+                }
 
-            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 $host_key;
+
+
+                if( not defined $host_key ) { 
+                    my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$target'";
+                    my $query_res = $main::known_clients_db->select_dbentry( $sql_statement );
+                    if( 1 == keys %{$query_res} ) {
+                        $host_key = $query_res->{1}->{host_key};
+                    }
+                } 
+
+                if( not defined $host_key ) {
+                    my $sql_statement = "SELECT * FROM known_server WHERE hostname='$target'";
+                    my $query_res = $main::known_server_db->select_dbentry( $sql_statement );
+                    if( 1 == keys %{$query_res} ) {
+                        $host_key = $query_res->{1}->{host_key};
+                    }
+                }
+
+                if( not defined $host_key ) { 
+                    &main::daemon_log("ERROR: ServerPackages: target '".$target.
+                            "' is not known neither in known_clients nor in known_server",1);
+                } else {
+                    &send_msg_hash2address($msg_hash, $target, $host_key);
+                }               
             }
         }
+
+    } elsif ($len_targets > 1 ) {
+        # we have more than one target 
+        # TODO to be implemented
     }
 
     return ;
@@ -406,21 +537,55 @@ sub got_ping {
 sub new_passwd {
     my ($msg_hash) = @_;
 
-    my $source = @{$msg_hash->{source}}[0];
-    my $passwd = @{$msg_hash->{new_passwd}}[0];
+    my $header = @{$msg_hash->{header}}[0];
+    my $source_name = @{$msg_hash->{source}}[0];
+    my $source_key = @{$msg_hash->{new_passwd}}[0];
+    my $query_res;
+
+    # check known_clients_db
+    my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$source_name'";
+    $query_res = $main::known_clients_db->select_dbentry( $sql_statement );
+    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;
+    }
 
-    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);
+    # 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;
+}
 
-    } elsif (exists $main::known_clients->{$source}) {
-        &main::add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
 
-    } else {
-        &main::daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1)   
-    }
+sub send_msg_hash {
+    my ($hash, $host_name, $host_key);
 
+    
+    my $answer = &send_msg_hash2address($hash, $host_name, $host_key);
+    
     return;
 }
 
@@ -439,7 +604,7 @@ sub here_i_am {
     my $out_hash;
 
     # number of known clients
-    my $nu_clients = keys %$main::known_clients;
+    my $nu_clients = keys %{ $main::known_clients_db->select_dbentry( {table=>'known_clients'} ) };
 
     # check wether client address or mac address is already known
     if (exists $main::known_clients->{$source}) {
@@ -465,20 +630,41 @@ 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];
-    &main::create_known_client($source);
-    &main::add_content2known_clients(hostname=>$source, events=>$events, mac_address=>$mac_address, 
-                                status=>"registered", passwd=>$new_passwd);
-
+    
+    # add entry to known_clients_db
+    my $res = $main::known_clients_db->add_dbentry( {table=>'known_clients', 
+                                                primkey=>'hostname',
+                                                hostname=>$source,
+                                                events=>$events,
+                                                macaddress=>$mac_address,
+                                                status=>'registered',
+                                                hostkey=>$new_passwd,
+                                                timestamp=>&get_time,
+                                                } );
+
+    if ($res != 0)  {
+        &main::daemon_log("ERROR: cannot add entry to known_clients: $res");
+        return;
+    }
+    
     # return acknowledgement to client
     $out_hash = &create_xml_hash("registered", $server_address, $source);
-    &send_msg_hash2address($out_hash, $source);
+    &send_msg_hash2address($out_hash, $source, $new_passwd);
 
     # notify registered client to bus
-    $out_hash = &create_xml_hash("new_client", $server_address, $bus_address, $source);
-    #&main::send_msg_hash2bus($out_hash);
-    &send_msg_hash2address($out_hash, $bus_address);
+    if( $bus_activ eq "on") {
+        # fetch actual bus key
+        my $query_res = $main::known_server_db->select_dbentry( {table=>'known_server'} );
+        my $hostkey = $query_res->{1}->{hostkey};
+        
+        # send update msg to bus
+        $out_hash = &create_xml_hash("new_client", $server_address, $bus_address, $source);
+        &send_msg_hash2address($out_hash, $bus_address, $hostkey);
+        
+        &main::daemon_log("send bus msg that client '$source' has registerd at server '$server_address'", 3);
+    }
 
     # give the new client his ldap config
     &new_ldap_config($source);
@@ -543,20 +729,29 @@ sub who_has_i_do {
 sub new_ldap_config {
     my ($address) = @_ ;
     
-    if (not exists $main::known_clients->{$address}) {
-        &main::daemon_log("ERROR: $address does not exist in known_clients, cannot send him his ldap config", 1);
-        return;
+    my $res = $main::known_clients_db->select_dbentry( { table=>'known_clients', hostname=>$address } );
+
+    # check hit
+    my $hit_counter = keys %{$res};
+    if( not $hit_counter == 1 ) {
+        &main::daemon_log("ERROR: more or no hit found in known_clients_db by query by '$address'", 1);
     }
-    
-    my $mac_address = $main::known_clients->{$address}->{"mac_address"};
-    if (not defined $mac_address) {
+
+    my $macaddress = $res->{1}->{macaddress};
+    my $hostkey = $res->{1}->{hostkey};
+
+    if (not defined $macaddress) {
         &main::daemon_log("ERROR: no mac address found for client $address", 1);
         return;
     }
 
     # Build LDAP connection
-    my $ldap;
-    $ldap= Net::LDAP->new($ldap_uri);
+    my $ldap = Net::LDAP->new($ldap_uri);
+    if( not defined $ldap ) {
+        &main::daemon_log("ERROR: cannot connect to ldap: $ldap_uri", 1);
+        return;
+    } 
+
 
     # Bind to a directory with dn and password
     my $mesg= $ldap->bind($ldap_admin_dn, $ldap_admin_password);
@@ -565,12 +760,16 @@ sub new_ldap_config {
     $mesg = $ldap->search( base   => $ldap_base,
                    scope  => 'sub',
                    attrs => ['dn', 'gotoLdapServer'],
-                   filter => "(&(objectClass=GOhard)(macaddress=$mac_address))");
+                   filter => "(&(objectClass=GOhard)(macaddress=$macaddress))");
     $mesg->code && die $mesg->error;
 
     # Sanity check
     if ($mesg->count != 1) {
-           &main::daemon_log("WARNING: client mac address $mac_address not found/not unique", 1);
+           &main::daemon_log("WARNING: client mac address $macaddress not found/not unique in ldap search", 1);
+        &main::daemon_log("\tbase: $ldap_base", 1);
+        &main::daemon_log("\tscope: sub", 1);
+        &main::daemon_log("\tattrs: dn, gotoLdapServer", 1);
+        &main::daemon_log("\tfilter: (&(objectClass=GOhard)(macaddress=$macaddress))", 1);
            return;
     }
 
@@ -591,7 +790,7 @@ sub new_ldap_config {
 
             # Sanity check
            if ($mesg->count != 1) {
-                   &main::daemon_log("WARNING: no LDAP information found for client mac $mac_address", 1);
+                   &main::daemon_log("WARNING: no LDAP information found for client mac $macaddress", 1);
                    return;
            }
 
@@ -623,7 +822,7 @@ sub new_ldap_config {
     }
 
     # Send information
-    send_msg("new_ldap_config", $server_address, $address, \%data);
+    send_msg("new_ldap_config", $server_address, $address, \%data, $hostkey);
 
     return;
 }