Code

Don't use POE ATM
[gosa.git] / gosa-si / gosa-si-client
index 2dcb06781158df8d709996064b75af6138016373..54884536a63e2ec4b5c82870f9b74722b463bbfb 100755 (executable)
@@ -3,12 +3,12 @@
 #
 #         FILE:  gosa-server
 #
-#        USAGE:  ./gosasc
+#        USAGE:  gosa-si-client
 #
 #  DESCRIPTION:
 #
 #      OPTIONS:  ---
-# REQUIREMENTS:  ---
+# REQUIREMENTS:  libnetaddr-ip-perl
 #         BUGS:  ---
 #        NOTES:
 #       AUTHOR:   (Andreas Rettenberger), <rettenberger@gonicus.de>
@@ -35,17 +35,18 @@ use Data::Dumper;
 use Sys::Syslog qw( :DEFAULT setlogsock);
 use File::Spec;
 use Cwd;
-use GosaSupportDaemon;
+use NetAddr::IP;
+use GOSA::GosaSupportDaemon;
 
 
 my ($cfg_file, %cfg_defaults, $foreground, $verbose, $pid_file, $procid, $pid, $log_file);
 my ($server_address, $server_ip, $server_port, $server_domain, $server_passwd, $server_cipher, $server_timeout);
-my ($client_address, $client_ip, $client_port, $client_mac_address);
-my ($input_socket, $rbits, $wbits, $ebits, $xml, $known_hosts);
+my ($client_address, $client_ip, $client_port, $client_mac_address, $network_interface, $ldap_config, $pam_config, $nss_config);
+my ($input_socket, $rbits, $wbits, $ebits, $xml, $known_hosts, $ldap_enabled);
 my (@events);
 
 # default variables
-my $event_dir = "/etc/gosac/events";
+my $event_dir = "/usr/lib/gosa-si/client/events";
 $known_hosts = {};
 $foreground = 0 ;
 %cfg_defaults =
@@ -55,6 +56,11 @@ $foreground = 0 ;
     },
 "client" => 
     {"client_port" => [\$client_port, "20083"],
+     "client_ip" => [\$client_ip, "0.0.0.0"],
+     "ldap" => [\$ldap_enabled, 1],
+     "ldap_config" => [\$ldap_config, "/etc/ldap/ldap.conf"],
+     "pam_config" => [\$pam_config, "/etc/pam_ldap.conf"],
+     "nss_config" => [\$nss_config, "/etc/libnss_ldap.conf"],
     },
 "server" =>
     {"server_ip" => [\$server_ip, ""],
@@ -136,13 +142,12 @@ sub daemon_log {
 sub check_cmdline_param () {
     my $err_config;
     my $err_counter = 0;
-    if( not defined( $cfg_file)) {
-        #$err_config = "please specify a config file";
-        #$err_counter += 1;
-        my $cwd = getcwd;
-        my $name = "/etc/gosa-si/client.conf";
-        $cfg_file = File::Spec->catfile( $cwd, $name );
-        print STDERR "no conf file specified\n   try to use default: $cfg_file\n";        
+       if(not defined($cfg_file)) {
+               $cfg_file = "/etc/gosa-si/client.conf";
+               if(! -r $cfg_file) {
+                       $err_config = "please specify a config file";
+                       $err_counter += 1;
+               }
     }
     if( $err_counter > 0 ) {
         &usage( "", 1 );
@@ -201,32 +206,172 @@ sub check_pid {
     }
 }
 
+#===  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;
+                                       last;
+                                }
+                        }       
+                }
+        }       
+        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;
+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;
         }
-        if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
-            $ip = "$1.$2.$3.$4";
-            last;
+
+        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") {
+                       if(defined($server_ip)) {
+                               $result = &get_local_mac_for_remote_ip($server_ip);
+                       } else {
+                               $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 ($client_mac_address and length($client_mac_address) > 0) {
+                                $result= $client_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 ($ip, $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:  get_local_mac_for_remote_ip
+#   PARAMETERS:  none (takes server_ip from global variable)
+#      RETURNS:  (ip address from interface that is used for communication) 
+#  DESCRIPTION:  Uses ioctl to get routing table from system, checks which entry
+#                matches (defaultroute last).
+#===============================================================================
+sub get_local_mac_for_remote_ip {
+        my $ifreq= shift;
+        my $result= "00:00:00:00:00:00";
+        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($server_ip)->within(new NetAddr::IP($destination, $mask))) {
+                       # destination matches route, save mac and exit
+                       $result= &get_mac($Iface);
+                       last;
+               }
+       }
+
+
+        return $result;
+}
 
 #===  FUNCTION  ================================================================
 #         NAME:  usage
@@ -306,16 +451,16 @@ sub register_at_server {
 
     # detect all client accepted events
     opendir(DIR, $event_dir) 
-        or daemon_log("cannot find directory $event_dir!\ngosac starts without any accepting events!", 1);
+        or daemon_log("cannot find directory $event_dir!\ngosa-si-client starts without any accepting events!", 1);
     my $file_name;
-    @events = ();
+    my @events_list = ();
     while(defined($file_name = readdir(DIR))){
         if ($file_name eq "." || $file_name eq "..") {
             next;
         }
-        push(@events, $file_name);
+        push(@events_list, $file_name);
     }
-    my $events = join(",", @events);
+    my $events = join(",", @events_list);
     daemon_log("found events: $events", 1);
 
     # fill in all possible servers
@@ -335,18 +480,20 @@ sub register_at_server {
 
     my ($rout, $wout, $reg_server);
     foreach my $server (@servers) {
+
         # create msg hash
         my $register_hash = &create_xml_hash("here_i_am", $client_address, $server);
         &add_content2xml_hash($register_hash, "new_passwd", $new_server_passwd);
-        &add_content2xml_hash($register_hash, "client_mac_address", $client_mac_address);
+        &add_content2xml_hash($register_hash, "mac_address", $client_mac_address);
         &add_content2xml_hash($register_hash, "events", $events);
 
+        my $tmp = print Dumper $register_hash;
+
         # send xml hash to server with general server passwd
         my $answer = &send_msg_hash2address($register_hash, $server, $server_passwd);
-        
-        # sending fails, no sens to wait for response
-        if ($answer ne "done") { next; }
-    
+        if ($answer != 0) { next; }
+       
         # waiting for response
         daemon_log("waiting for response...\n", 5);
         my $nf = select($rout=$rbits, $wout=$wbits, undef, $server_timeout);
@@ -384,7 +531,7 @@ sub register_at_server {
                 daemon_log("ERROR: do not understand the incoming message:" , 5);  
                 daemon_log("$@", 7); 
             } else {
-                my $header = &get_content_from_xml_hash($msg_hash, "header");
+                my $header = @{$msg_hash->{header}}[0];
                 if($header eq "registered") {
                     $reg_server = $server;
                     last;
@@ -396,7 +543,7 @@ sub register_at_server {
                 }
             }
         }
-        # kommt antwort nicht, dann probiere es mit dem nächsten in der liste
+        # if no answer arrive, try next server in list
 
     }
     
@@ -422,19 +569,19 @@ sub register_at_server {
 #      RETURNS:
 #  DESCRIPTION:
 #===============================================================================
-sub create_xml_hash {
-    my ($header, $source, $target, $header_value) = @_;
-    my $hash = {
-            header => [$header],
-            source => [$source],
-            target => [$target],
-            $header => [$header_value],
-    };
-    daemon_log("create_xml_hash:", 7),
-    chomp(my $tmp = Dumper $hash);
-    daemon_log("\t$tmp\n", 7);
-    return $hash
-}
+#sub create_xml_hash {
+#    my ($header, $source, $target, $header_value) = @_;
+#    my $hash = {
+#            header => [$header],
+#            source => [$source],
+#            target => [$target],
+#            $header => [$header_value],
+#    };
+#    daemon_log("create_xml_hash:", 7),
+#    chomp(my $tmp = Dumper $hash);
+#    daemon_log("\t$tmp\n", 7);
+#    return $hash
+#}
 
 
 #===  FUNCTION  ================================================================
@@ -443,13 +590,13 @@ sub create_xml_hash {
 #      RETURNS:
 #  DESCRIPTION:
 #===============================================================================
-sub create_xml_string {
-    my ($xml_hash) = @_ ;
-    my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
-    $xml_string =~ s/[\n]+//g;
-    daemon_log("create_xml_string:\n\t$xml_string\n", 7);
-    return $xml_string;
-}
+#sub create_xml_string {
+#    my ($xml_hash) = @_ ;
+#    my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
+#    $xml_string =~ s/[\n]+//g;
+#    daemon_log("create_xml_string:\n\t$xml_string\n", 7);
+#    return $xml_string;
+#}
 
 
 #===  FUNCTION  ================================================================
@@ -458,15 +605,15 @@ sub create_xml_string {
 #      RETURNS:
 #  DESCRIPTION:
 #===============================================================================
-sub add_content2xml_hash {
-    my ($xml_ref, $element, $content) = @_;
-    if(not exists $$xml_ref{$element} ) {
-        $$xml_ref{$element} = [];
-    }
-    my $tmp = $$xml_ref{$element};
-    push(@$tmp, $content);
-    return;
-}
+#sub add_content2xml_hash {
+#    my ($xml_ref, $element, $content) = @_;
+#    if(not exists $$xml_ref{$element} ) {
+#        $$xml_ref{$element} = [];
+#    }
+#    my $tmp = $$xml_ref{$element};
+#    push(@$tmp, $content);
+#    return;
+#}
 
 
 #===  FUNCTION  ================================================================
@@ -478,14 +625,14 @@ sub add_content2xml_hash {
 #                function returns a string cause it is expected that these keys
 #                do just have one value, all other keys returns an array!!!
 #===============================================================================
-sub get_content_from_xml_hash {
-    my ($xml_ref, $element) = @_;
-    my $result = $xml_ref->{$element};
-    if( $element eq "header" || $element eq "target" || $element eq "source") {
-        return @$result[0];
-    }
-    return @$result;
-}
+#sub get_content_from_xml_hash {
+#    my ($xml_ref, $element) = @_;
+#    my $result = $xml_ref->{$element};
+#    if( $element eq "header" || $element eq "target" || $element eq "source") {
+#        return @$result[0];
+#    }
+#    return @$result;
+#}
 
 #    my ($xml_ref, $element) = @_;
 #    if (exists $xml_ref->{$element}) {
@@ -509,14 +656,14 @@ sub get_content_from_xml_hash {
 #      RETURNS:
 #  DESCRIPTION:
 #===============================================================================
-sub encrypt_msg {
-    my ($msg, $my_cipher) = @_;
-    if(not defined $my_cipher) { print "no cipher object\n"; }
-    $msg = "\0"x(16-length($msg)%16).$msg;
-    my $crypted_msg = $my_cipher->encrypt($msg);
-    chomp($crypted_msg = &encode_base64($crypted_msg));
-    return $crypted_msg;
-}
+#sub encrypt_msg {
+#    my ($msg, $my_cipher) = @_;
+#    if(not defined $my_cipher) { print "no cipher object\n"; }
+#    $msg = "\0"x(16-length($msg)%16).$msg;
+#    my $crypted_msg = $my_cipher->encrypt($msg);
+#    chomp($crypted_msg = &encode_base64($crypted_msg));
+#    return $crypted_msg;
+#}
 
 
 #===  FUNCTION  ================================================================
@@ -525,13 +672,13 @@ sub encrypt_msg {
 #      RETURNS:
 #  DESCRIPTION:
 #===============================================================================
-sub decrypt_msg {
-    my ($crypted_msg, $my_cipher) = @_ ;
-    $crypted_msg = &decode_base64($crypted_msg);
-    my $msg = $my_cipher->decrypt($crypted_msg); 
-    $msg =~ s/\0*//g;
-    return $msg;
-}
+#sub decrypt_msg {
+#    my ($crypted_msg, $my_cipher) = @_ ;
+#    $crypted_msg = &decode_base64($crypted_msg);
+#    my $msg = $my_cipher->decrypt($crypted_msg); 
+#    $msg =~ s/\0*//g;
+#    return $msg;
+#}
 
 
 #===  FUNCTION  ================================================================
@@ -540,17 +687,17 @@ sub decrypt_msg {
 #      RETURNS:  cipher object
 #  DESCRIPTION:  
 #===============================================================================
-sub create_ciphering {
-    my ($passwd) = @_;
-    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
-    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
-
-    #daemon_log("iv: $iv", 7);
-    #daemon_log("key: $passwd", 7);
-    my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
-    $my_cipher->set_iv($iv);
-    return $my_cipher;
-}
+#sub create_ciphering {
+#    my ($passwd) = @_;
+#    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
+#    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
+#
+#    #daemon_log("iv: $iv", 7);
+#    #daemon_log("key: $passwd", 7);
+#    my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
+#    $my_cipher->set_iv($iv);
+#    return $my_cipher;
+#}
 
 
 #===  FUNCTION  ================================================================
@@ -577,52 +724,52 @@ sub create_passwd {
 #      RETURNS:  nothing
 #  DESCRIPTION:  ????
 #===============================================================================
-sub send_msg_hash2address {
-    my ($msg_hash, $address, $passwd) = @_ ;
-
-    # fetch header for logging
-    my $header = @{$msg_hash->{header}}[0];
-
-    # generiere xml string
-    my $msg_xml = &create_xml_string($msg_hash);
-
-    # hole das entsprechende passwd aus dem hash
-    if(not defined $passwd) {
-        if(exists $known_hosts->{$address}) {
-            $passwd = $known_hosts->{$address}->{passwd};
-        } elsif ($address eq $server_address) {
-            $passwd = $server_passwd;
-        } else {
-            daemon_log("$address not known, neither as server nor as client", 1);
-            return "failed";
-        }
-    }
-
-    # erzeuge ein ciphering object
-    my $act_cipher = &create_ciphering($passwd);
-
-    # encrypt xml msg
-    my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
-
-    # öffne socket
-    my $socket = &open_socket($address);
-    if(not defined $socket){
-        daemon_log("cannot open socket to $address, server not reachable", 1);
-        daemon_log("cannot send '$header'-msg", 1);
-        return "failed";
-    }
-
-    # versende xml msg
-    print $socket $crypted_msg."\n";
-
-    # schließe socket
-    close $socket;
-
-    daemon_log("send '$header'-msg to $address", 5);
-    daemon_log("crypted_msg:\n\t$crypted_msg", 7);
-
-    return "done";
-}
+#sub send_msg_hash2address {
+#    my ($msg_hash, $address, $passwd) = @_ ;
+#
+#    # fetch header for logging
+#    my $header = @{$msg_hash->{header}}[0];
+#
+#    # generiere xml string
+#    my $msg_xml = &create_xml_string($msg_hash);
+#
+#    # hole das entsprechende passwd aus dem hash
+#    if(not defined $passwd) {
+#        if(exists $known_hosts->{$address}) {
+#            $passwd = $known_hosts->{$address}->{passwd};
+#        } elsif ($address eq $server_address) {
+#            $passwd = $server_passwd;
+#        } else {
+#            daemon_log("$address not known, neither as server nor as client", 1);
+#            return "failed";
+#        }
+#    }
+#
+#    # erzeuge ein ciphering object
+#    my $act_cipher = &create_ciphering($passwd);
+#
+#    # encrypt xml msg
+#    my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
+#
+#    # öffne socket
+#    my $socket = &open_socket($address);
+#    if(not defined $socket){
+#        daemon_log("cannot open socket to $address, server not reachable", 1);
+#        daemon_log("cannot send '$header'-msg", 1);
+#        return "failed";
+#    }
+#
+#    # versende xml msg
+#    print $socket $crypted_msg."\n";
+#
+#    # schließe socket
+#    close $socket;
+#
+#    daemon_log("send '$header'-msg to $address", 5);
+#    daemon_log("crypted_msg:\n\t$crypted_msg", 7);
+#
+#    return "done";
+#}
 
 
 #===  FUNCTION  ================================================================
@@ -821,12 +968,13 @@ sub process_incoming_msg {
         return;
     } 
 
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
+    my $header = @{$msg_hash->{header}}[0];
     
-    daemon_log("header from msg:", 1);
-    daemon_log("\t$header", 1);
-    daemon_log("msg to process:", 7);
-    daemon_log("\t$msg", 7);
+    daemon_log("receive '$header' from $host", 1);
+#    daemon_log("header from msg:", 1);
+#    daemon_log("\t$header", 1);
+#    daemon_log("msg to process:", 7);
+#    daemon_log("\t$msg", 7);
 
     #check whether msg to process is a event 
     opendir(DIR, $event_dir) 
@@ -855,9 +1003,7 @@ sub process_incoming_msg {
     close(DIR);
     daemon_log("could not assign the msg $header to an event", 5);
     
-
-
-    if ($header eq 'new_ldap_config') { &new_ldap_config($msg_hash)}
+    if ($header eq 'new_ldap_config') { if ($ldap_enabled == 1) {&new_ldap_config($msg_hash)}}
     elsif ($header eq 'ping') { &got_ping($msg_hash) }
     elsif ($header eq 'wake_up') { &execute_event($msg_hash)}
     elsif ($header eq 'new_passwd') { &new_passwd()}
@@ -926,10 +1072,104 @@ sub got_ping {
 
 sub new_ldap_config {
     my ($msg_hash) = @_ ;
+    my $element;
+    my @ldap_uris;
+    my $ldap_base;
+    my @ldap_options;
+    my @pam_options;
+    my @nss_options;
+    my $goto_admin;
+    my $goto_secret;
+
+    # Transform input into array
+    while ( my ($key, $value) = each(%$msg_hash) ) {
+       if ($key =~ /^(source|target|header)$/) {
+               next;
+       }
+
+       foreach $element (@$value) {
+               if ($key =~ /^ldap_uri$/) {
+                       push (@ldap_uris, $element);
+                       next;
+               }
+               if ($key =~ /^ldap_base$/) {
+                       $ldap_base= $element;
+                       next;
+               }
+               if ($key =~ /^goto_admin$/) {
+                       $goto_admin= $element;
+                       next;
+               }
+               if ($key =~ /^goto_secret$/) {
+                       $goto_secret= $element;
+                       next;
+               }
+               if ($key =~ /^ldap_cfg$/) {
+                       push (@ldap_options, "$element");
+                       next;
+               }
+               if ($key =~ /^pam_cfg$/) {
+                       push (@pam_options, "$element");
+                       next;
+               }
+               if ($key =~ /^nss_cfg$/) {
+                       push (@nss_options, "$element");
+                       next;
+               }
+       }
+    }
 
-    my @gotoLdapServer = &get_content_from_xml_hash($msg_hash, "new_ldap_config");
-    print Dumper @gotoLdapServer;
-
+    # Setup ldap.conf
+    my $file1;
+    my $file2;
+    open(file1, "> $ldap_config");
+    print file1 "# This file was automatically generated by gosa-si-client. Do not change.\n";
+    print file1 "URI";
+    foreach $element (@ldap_uris) {
+       print file1 " $element";
+    }
+    print file1 "\nBASE $ldap_base\n";
+    foreach $element (@ldap_options) {
+       print file1 "$element\n";
+    }
+    close (file1);
+    daemon_log("wrote $ldap_config", 5);
+
+    # Setup pam_ldap.conf / libnss_ldap.conf
+    open(file1, "> $pam_config");
+    open(file2, "> $nss_config");
+    print file1 "# This file was automatically generated by gosa-si-client. Do not change.\n";
+    print file2 "# This file was automatically generated by gosa-si-client. Do not change.\n";
+    print file1 "uri";
+    print file2 "uri";
+    foreach $element (@ldap_uris) {
+       print file1 " $element";
+       print file2 " $element";
+    }
+    print file1 "\nbase $ldap_base\n";
+    print file2 "\nbase $ldap_base\n";
+    foreach $element (@pam_options) {
+       print file1 "$element\n";
+    }
+    foreach $element (@nss_options) {
+       print file2 "$element\n";
+    }
+    close (file2);
+    daemon_log("wrote $nss_config", 5);
+    close (file1);
+    daemon_log("wrote $pam_config", 5);
+
+    # Create goto.secrets if told so
+    if (defined $goto_admin){
+           open(file1, "> /etc/goto/secret");
+           close(file1);
+           chown(0,0, "/etc/goto/secret");
+           chmod(0600, "/etc/goto/secret");
+           open(file1, "> /etc/goto/secret");
+           print file1 $goto_admin.":".$goto_secret."\n";
+           close(file1);
+           daemon_log("wrote /etc/goto/secret", 5);
+    }
 
     return;
 
@@ -938,7 +1178,7 @@ sub new_ldap_config {
 
 sub execute_event {
     my ($msg_hash)= @_;
-    my $configdir= '/etc/gosac/events/';
+    my $configdir= '/etc/gosa-si/client/events/';
     my $result;
 
     my $header = &get_content_from_xml_hash($msg_hash, 'header');
@@ -949,7 +1189,7 @@ sub execute_event {
     if((not defined $source)
             && (not defined $target)
             && (not defined $header)) {
-        daemon_log("ERROR: Entries missing in XML msg for gosa events under /etc/gosac/events");
+        daemon_log("ERROR: Entries missing in XML msg for gosa events under $configdir");
     } else {
         my $parameters="";
         my @params = &get_content_from_xml_hash($msg_hash, $header);
@@ -1013,9 +1253,17 @@ GetOptions("h|help" => \&usage,
 &read_configfile;
 &check_pid;
 
+if ( ! $foreground ) {
+       open STDIN, '/dev/null' or die "Can’t read /dev/null: $!";
+       open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
+       open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
+}
+
+
 # restart daemon log file
 if(-e $log_file ) { unlink $log_file }
-daemon_log("started!");
+daemon_log(" ", 1);
+daemon_log("$0 started!", 1);
 
 # Just fork, if we"re not in foreground mode
 if( ! $foreground ) { $pid = fork(); }
@@ -1030,10 +1278,13 @@ if( 0 != $pid ) {
 }
 
 # detect own ip and mac address
-($client_ip, $client_mac_address) = &get_ip_and_mac(); 
-if (not defined $client_ip) {
-    die "EXIT: ip address of $0 could not be detected";
-}
+$network_interface= &get_interface_for_ip($client_ip);
+$client_mac_address= &get_mac($network_interface);
+
+# ($client_ip, $client_mac_address) = &get_ip_and_mac(); 
+#if (not defined $client_ip) {
+#    die "EXIT: ip address of $0 could not be detected";
+#}
 daemon_log("client ip address detected: $client_ip", 1);
 daemon_log("client mac address detected: $client_mac_address", 1);
 
@@ -1047,6 +1298,7 @@ $client_address = $client_ip.":".$client_port;
 $xml = new XML::Simple();
 
 # create input socket
+daemon_log(" ", 1);
 $rbits = $wbits = $ebits = "";
 $input_socket = IO::Socket::INET->new(LocalPort => $client_port,
         Type => SOCK_STREAM,
@@ -1056,12 +1308,13 @@ $input_socket = IO::Socket::INET->new(LocalPort => $client_port,
 if(not defined $input_socket){
     daemon_log("cannot be a tcp server at $client_port : $@\n");
 } else {
-    daemon_log("start server:\n\t$server_ip:$client_port",1) ;
+    daemon_log("start client at $client_address",1) ;
     vec($rbits, fileno $input_socket, 1) = 1;
     vec($wbits, fileno $input_socket, 1) = 1;
 }
 
 # register at server
+daemon_log(" ", 1);
 &register_at_server();