From 09f0873a1f1cffb0cb13970adf6cc597f0fdeef0 Mon Sep 17 00:00:00 2001 From: rettenbe Date: Thu, 29 Nov 2007 09:09:35 +0000 Subject: [PATCH] "input device" gosa_fifo_in and goas_fifo_out added translate developer documentation to english git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@7933 594d385d-05f5-0310-b6e9-bd551577e9d8 --- contrib/daemon/gosa-sc | 6 - contrib/daemon/gosa-sc.cfg | 2 +- contrib/daemon/gosa-sd | 688 +++++++++++++++++++++++-------------- contrib/daemon/gosa-sd-bus | 383 +++++++++++---------- contrib/daemon/gosa-sd.cfg | 8 +- 5 files changed, 652 insertions(+), 435 deletions(-) diff --git a/contrib/daemon/gosa-sc b/contrib/daemon/gosa-sc index 89139bf19..d07edb6e2 100755 --- a/contrib/daemon/gosa-sc +++ b/contrib/daemon/gosa-sc @@ -289,8 +289,6 @@ sub register_at_server { push(@events, $file_name); } my $events = join(",", @events); - #print "debug: events: $events\n"; - # fill in all possible servers my @servers; @@ -357,9 +355,7 @@ sub register_at_server { daemon_log("cannot register at $server", 1); daemon_log("ERROR: do not understand the message:\n\t$crypted_msg" , 5); } else { - print "debug: register_at_server: incoming msg konnte geparst werden\n"; my $header = &get_content_from_xml_hash($msg_hash, "header"); - print "debug: header: $header\n"; if($header eq "registered") { $reg_server = $server; last; @@ -807,8 +803,6 @@ sub process_incoming_msg { #=============================================================================== sub update_status { my ($new_status) = @_ ; - #print "debug: update_status: client_address: $client_address\n"; - #print "debug: update_status: server_address: $server_address\n"; my $out_hash = &create_xml_hash("update_status", $client_address, $server_address); &add_content2xml_hash($out_hash, "update_status", $new_status); &send_msg_hash2address($out_hash, $server_address); diff --git a/contrib/daemon/gosa-sc.cfg b/contrib/daemon/gosa-sc.cfg index c243dc8a5..fc1b6a0f2 100644 --- a/contrib/daemon/gosa-sc.cfg +++ b/contrib/daemon/gosa-sc.cfg @@ -4,7 +4,7 @@ pid_file = /var/run/gosa-sc.pid [client] client_ip = 10.89.1.155 -client_port = 10010 +client_port = 10011 mac_address = 00:1B:77:04:8A:6C [server] diff --git a/contrib/daemon/gosa-sd b/contrib/daemon/gosa-sd index c5a6575e0..e88e441c2 100755 --- a/contrib/daemon/gosa-sd +++ b/contrib/daemon/gosa-sd @@ -8,7 +8,7 @@ # DESCRIPTION: # # OPTIONS: --- -# REQUIREMENTS: --- +# REQUIREMENTS: libconfig-inifiles-perl libcrypt-rijndael-perl libxml-simple-perl libipc-shareable-perl libdata-dumper-simple-perl # BUGS: --- # NOTES: # AUTHOR: (Andreas Rettenberger), @@ -19,12 +19,6 @@ #=============================================================================== -# TODO 2007-11-12: nachrichten senden an buss kann so nicht funktionieren, kind setzt $msg_to_bus, der elter testet aber, ob in $msg_to_bus was enthalten ist um es dorthin zu senden, so kann das nicht gehen, alternativ müsste das kind dem elter über die pipe die msg schicken und der elter müsste dann die variabel $msg_to_bus setzten, dann würde es so gehen -# wird als zu aufwändig vorerst verworfen, es wäre nötig global ein dic/2 arrays bereitzustellen, maximal child_max groß in dem dann die erzeugten pipe-enden beim forken zugewiesen werden. die namen müssten aber vorher festgelegt sein, damit der elter die bereits existierenden und die noch nicht oder wieder nicht existierenden pipes checken kann ob dort was anliegt. kurzum, das pipe-handling wäre sehr aufwändig zu programmieren, wenn also kein zeitlicher bedarf besteht, dann eher hinten anstellen. - -# TODO 2007-11-19: ich hab zwei hashes, known_daemons und known_clients. 1. known_daemons in known_server umändern, 2. lösung suchen für print known_daemons_hash usw. ich kann zwar den hash als parameter übergeben, aber nicht nicht zb. die shm variablen zum sperren des shm, evtl. anstatt hash nur einen key übergeben, bei dem dann hash und shm variablen abgelegt sind, allerdings müsste dieser hash dann auch wieder von überall aus erreichbar sein, evtl. zuviel speicher overhead, alternative bedeutet nur mehr tipparbeit - - use strict; use warnings; use Getopt::Long; @@ -52,6 +46,7 @@ my ($pid_file, $procid, $pid, $log_file); my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout); my ($xml); my ($arp_activ, $arp_fifo, $arp_fifo_path); +my ($gosa_activ, $gosa_fifo_in, $gosa_fifo_out); # specifies the verbosity of the daemon_log $verbose = 0 ; @@ -107,39 +102,39 @@ $shmcl = tie($known_clients, 'IPC::Shareable', undef, {create => 1, "arp" => {"arp_activ" => [\$arp_activ, "on"], "arp_fifo_path" => [\$arp_fifo_path, "/tmp/arp_fifo"], - - } + }, +"gosa" => + {"gosa_activ" => [\$gosa_activ, "on"], + "gosa_fifo_in" => [\$gosa_fifo_in, "/etc/gosad/fifo/gosa_fifo_in"], + "gosa_fifo_out" => [\$gosa_fifo_out, "/etc/gosa/fifo/gosa_fifo_out"], + }, ); + #=== FUNCTION ================================================================ # NAME: usage -# PARAMETERS: -# RETURNS: -# DESCRIPTION: nomen est omen +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: print out usage text to STDERR #=============================================================================== sub usage { - my( $text, $help ) = @_; - $text = undef if( "h" eq $text ); - (defined $text) && print STDERR "\n$text\n"; - if( (defined $help && $help) || (!defined $help && !defined $text) ) { - print STDERR << "EOF" ; + print STDERR << "EOF" ; usage: $0 [-hvf] [-c config] - -h : this (help) message - -c : config file - -f : foreground, process will not be forked to background - -v : be verbose (multiple to increase verbosity) + -h : this (help) message + -c : config file + -f : foreground, process will not be forked to background + -v : be verbose (multiple to increase verbosity) EOF - } - print "\n" ; + print "\n" ; } #=== FUNCTION ================================================================ # NAME: read_configfile # PARAMETERS: cfg_file - string - -# RETURNS: -# DESCRIPTION: +# RETURNS: nothing +# DESCRIPTION: read cfg_file and set variables #=============================================================================== sub read_configfile { my $cfg; @@ -160,13 +155,14 @@ sub read_configfile { } } + #=== FUNCTION ================================================================ # NAME: logging # PARAMETERS: level - string - default 'info' # msg - string - # facility - string - default 'LOG_DAEMON' -# RETURNS: -# DESCRIPTION: +# RETURNS: nothing +# DESCRIPTION: function for logging #=============================================================================== sub daemon_log { # log into log_file @@ -198,10 +194,10 @@ sub daemon_log { #=== FUNCTION ================================================================ -# NAME: check_cmdline_param -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: check_cmdline_param +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: validates commandline parameter #=============================================================================== sub check_cmdline_param () { my $err_config; @@ -224,10 +220,10 @@ sub check_cmdline_param () { #=== FUNCTION ================================================================ -# NAME: check_pid -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: check_pid +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: handels pid processing #=============================================================================== sub check_pid { $pid = -1; @@ -274,9 +270,9 @@ sub check_pid { #=== FUNCTION ================================================================ # NAME: sig_int_handler -# PARAMETERS: -# RETURNS: -# DESCRIPTION: nomen est omen +# PARAMETERS: signal - string - signal arose from system +# RETURNS: noting +# DESCRIPTION: handels tasks to be done befor signal becomes active #=============================================================================== sub sig_int_handler { my ($signal) = @_; @@ -287,9 +283,22 @@ sub sig_int_handler { if( -p $arp_fifo_path ) { close $arp_fifo ; unlink($arp_fifo_path) ; - daemon_log("FIFO closed", 1) ; + daemon_log("ARP_FIFO closed", 1) ; + } + + if (-p $gosa_fifo_in) { + close GOSA_FIFO_IN; + unlink($gosa_fifo_in); + daemon_log("GOSA_FIFO_IN closed",1); } + if (-p $gosa_fifo_out) { + close GOSA_FIFO_OUT; + unlink($gosa_fifo_out); + daemon_log("GOSA_FIFO_OUT closed",1); + } + + print "$signal\n"; exit(1); @@ -299,9 +308,10 @@ $SIG{INT} = \&sig_int_handler; #=== FUNCTION ================================================================ # NAME: activating_child -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg - string - incoming message +# host - string - host from which the incomming message comes +# RETURNS: nothing +# DESCRIPTION: handels the distribution of incoming messages to working childs #=============================================================================== sub activating_child { my ($msg, $host) = @_; @@ -310,22 +320,21 @@ sub activating_child { daemon_log("activating: childpid:$$child{'pid'}", 5); - #my $msg2write = $msg.".".$host."\n"; - print $pipe_wr $msg.".".$host."\n"; return; - } + #=== FUNCTION ================================================================ # NAME: get_processing_child -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: nothing +# RETURNS: child - hash - holding the process id and the references to the pipe +# handles pipe_wr and pipe_rd +# DESCRIPTION: handels the forking, reactivating and keeping alive tasks #=============================================================================== sub get_processing_child { my $child; - # schaue durch alle %busy_child{pipe_wr} ob irgendwo 'done' drinsteht, wenn ja, dann setze das kind von busy auf free um + # checking %busy_child{pipe_wr} if msg is 'done', then set child from busy to free while(my ($key, $val) = each(%busy_child)) { # test ob prozess noch existiert my $exitus_pid = waitpid($key, WNOHANG); @@ -335,7 +344,7 @@ sub get_processing_child { next; } - # test ob prozess noch arbeitet + # check wether process sitll works my $fh = $$val{'pipe_rd'}; $fh->blocking(0); my $child_answer; @@ -355,12 +364,12 @@ sub get_processing_child { } daemon_log("free child:$key", 5); } - # teste @free_child und @busy_child + # check @free_child and @busy_child my $free_len = scalar(keys(%free_child)); my $busy_len = scalar(keys(%busy_child)); daemon_log("free children $free_len, busy children $busy_len", 5); - # gibt es bereits ein freies kind, dann lass es arbeiten + # if there is a free child, let the child work if($free_len > 0){ my @keys = keys(%free_child); $child = $free_child{$keys[0]}; @@ -399,10 +408,9 @@ sub get_processing_child { vec( $rbits, fileno $PARENT_rd , 1 ) = 1; my $nf = select($rbits, undef, undef, $child_timeout); if($nf < 0 ) { - # wenn $nf < 1, error handling die "select(): $!\n"; } elsif (! $nf) { - # ist dieses kind nicht eines der letzenen $child_min, dann springe aus while schleife raus + # if already child_min childs are alive, then leave loop $free_len = scalar(keys(%free_child)); $busy_len = scalar(keys(%busy_child)); if($free_len + $busy_len >= $child_min) { @@ -412,9 +420,9 @@ sub get_processing_child { } } - # ansonsten + # a job for a child arise if ( vec $rbits, fileno $PARENT_rd, 1 ) { - # hole alles was in der pipe ist + # read everything from pipe my $msg = ""; $PARENT_rd->blocking(0); while(1) { @@ -429,7 +437,7 @@ sub get_processing_child { redo; } } - # kinder die die while-schleife verlassen haben sterben + # childs leaving the loop are allowed to die exit(0); @@ -456,9 +464,9 @@ sub get_processing_child { #=== FUNCTION ================================================================ # NAME: process_incoming_msg -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: crypted_msg - string - incoming crypted message +# RETURNS: nothing +# DESCRIPTION: handels the proceeded distribution to the appropriated functions #=============================================================================== sub process_incoming_msg { my ($crypted_msg) = @_; @@ -526,6 +534,8 @@ sub process_incoming_msg { # process incoming msg my $header = &get_content_from_xml_hash($msg_hash, "header"); + my $source = @{$msg_hash->{source}}[0]; + daemon_log("header from msg:", 1); daemon_log("\t$header", 1); daemon_log("msg to process:", 7); @@ -539,13 +549,12 @@ sub process_incoming_msg { } elsif ($len_targets == 1){ # we have only one target symbol - my $target = @targets[0]; + my $target = $targets[0]; daemon_log("msg is for:", 7); 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) } @@ -554,11 +563,10 @@ sub process_incoming_msg { elsif ($header eq 'got_ping') { &got_ping($msg_hash)} elsif ($header eq 'get_load') { &execute_actions($msg_hash)} else { daemon_log("ERROR: no function assigned to this msg", 5) } - } elsif ($target eq "*") { + + } elsif ($target eq "*") { # msg is for all clients - my $source = @{$msg_hash->{source}}[0]; - print "debug: process_incoming_msg: source: $source\n"; my @target_addresses = keys(%$known_clients); foreach my $target_address (@target_addresses) { if ($target_address eq $source) { next; } @@ -602,7 +610,7 @@ sub process_incoming_msg { } - &print_known_daemons_hash(); + &print_known_daemons(); &print_known_clients(); daemon_log(" ", 1); return; @@ -614,7 +622,7 @@ sub process_incoming_msg { # PARAMETERS: PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000 # [PeerPort] string necessary if port not appended by PeerAddr # RETURNS: socket IO::Socket::INET -# DESCRIPTION: +# DESCRIPTION: open a socket to PeerAddr #=============================================================================== sub open_socket { my ($PeerAddr, $PeerPort) = @_ ; @@ -650,8 +658,6 @@ sub read_from_socket { my $char; $len = sysread($socket, $char, 16); if($len != 16) { last } - #print "$char\n"; - #print " $len\n"; if($len != 16) { last } $result .= $char; } @@ -661,9 +667,12 @@ sub read_from_socket { #=== FUNCTION ================================================================ # NAME: create_xml_hash -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: header - string - message header (required) +# source - string - where the message come from (required) +# target - string - where the message should go to (required) +# [header_value] - string - something usefull (optional) +# RETURNS: hash - hash - nomen est omen +# DESCRIPTION: creates a key-value hash, all values are stored in a array #=============================================================================== sub create_xml_hash { my ($header, $source, $target, $header_value) = @_; @@ -673,18 +682,18 @@ 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); + #daemon_log("create_xml_hash:", 7), + #chomp(my $tmp = Dumper $hash); + #daemon_log("\t$tmp", 7); return $hash } #=== FUNCTION ================================================================ # NAME: create_xml_string -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: xml_hash - hash - hash from function create_xml_hash +# RETURNS: xml_string - string - xml string representation of the hash +# DESCRIPTION: transform the hash to a string using XML::Simple module #=============================================================================== sub create_xml_string { my ($xml_hash) = @_ ; @@ -698,9 +707,11 @@ sub create_xml_string { #=== FUNCTION ================================================================ # NAME: add_content2xml_hash -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: xml_ref - ref - reference to a hash from function create_xml_hash +# element - string - key for the hash +# content - string - value for the hash +# RETURNS: nothing +# DESCRIPTION: add key-value pair to xml_ref, if key alread exists, then append value to list #=============================================================================== sub add_content2xml_hash { my ($xml_ref, $element, $content) = @_; @@ -715,12 +726,14 @@ sub add_content2xml_hash { #=== FUNCTION ================================================================ # NAME: get_content_from_xml_hash -# PARAMETERS: -# RETURNS: +# PARAMETERS: xml_ref - ref - reference of the xml hash +# element - string - key of the value you want +# RETURNS: value - string - if key is either header, target or source +# value - list - for all other keys in xml hash # DESCRIPTION: #=============================================================================== sub get_content_from_xml_hash { - my ($xml_ref, $element) = @_; + my ($xml_ref, $element) = @_ ; my $result = $xml_ref->{$element}; if( $element eq "header" || $element eq "target" || $element eq "source") { return @$result[0]; @@ -731,9 +744,10 @@ sub get_content_from_xml_hash { #=== FUNCTION ================================================================ # NAME: encrypt_msg -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg - string - message to encrypt +# my_cipher - ref - reference to a Crypt::Rijndael object +# RETURNS: crypted_msg - string - crypted message +# DESCRIPTION: crypts the incoming message with the Crypt::Rijndael module #=============================================================================== sub encrypt_msg { my ($msg, $my_cipher) = @_; @@ -748,11 +762,13 @@ sub encrypt_msg { return $crypted_msg; } + #=== FUNCTION ================================================================ # NAME: decrypt_msg -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: crypted_msg - string - message to decrypt +# my_cipher - ref - reference to a Crypt::Rijndael object +# RETURNS: msg - string - decrypted message +# DESCRIPTION: decrypts the incoming message with the Crypt::Rijndael module #=============================================================================== sub decrypt_msg { my ($crypted_msg, $my_cipher) =@_; @@ -765,9 +781,9 @@ sub decrypt_msg { #=== FUNCTION ================================================================ # NAME: create_ciphering -# PARAMETERS: -# RETURNS: cipher object -# DESCRIPTION: +# PARAMETERS: passwd - string - used to create ciphering +# RETURNS: cipher - object +# DESCRIPTION: creates a Crypt::Rijndael::MODE_CBC object with passwd as key #=============================================================================== sub create_ciphering { my ($passwd) = @_; @@ -783,7 +799,7 @@ sub create_ciphering { #=== FUNCTION ================================================================ # NAME: send_msg_hash2address -# PARAMETERS: msg string - xml message +# PARAMETERS: msg_hash - hash - xml_hash created with function create_xml_hash # PeerAddr string - socket address to send msg # PeerPort string - socket port, if not included in socket address # RETURNS: nothing @@ -795,77 +811,94 @@ sub send_msg_hash2address { # fetch header for logging my $header = &get_content_from_xml_hash($msg_hash, "header"); - # generiere xml string + # generate xml string my $msg_xml = &create_xml_string($msg_hash); - # hole das entsprechende passwd aus dem hash + # fetch the appropriated passwd from hash if(not defined $passwd) { if(exists $known_daemons->{$address}) { $passwd = $known_daemons->{$address}->{passwd}; } elsif(exists $known_clients->{$address}) { $passwd = $known_clients->{$address}->{passwd}; + } else { daemon_log("$address not known, neither as server nor as client", 1); return; } } - # erzeuge ein ciphering object + # create ciphering object my $act_cipher = &create_ciphering($passwd); # encrypt xml msg my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher); - # öffne socket + # opensocket my $socket = &open_socket($address); if(not defined $socket){ daemon_log( "cannot send '$header'-msg to $address , server not reachable", 5); + + if ($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"); + + } return; } - # versende xml msg + # send xml msg print $socket $crypted_msg."\n"; - # schließe socket close $socket; daemon_log("send '$header'-msg to $address", 5); - daemon_log("crypted_msg:",7); - daemon_log("\t$crypted_msg", 7); - return + #daemon_log("crypted_msg:",7); + #daemon_log("\t$crypted_msg", 7); + + # update status of client in known_clients with last send msg + if(exists $known_daemons->{$address}) { + #&update_known_daemons(); + } elsif(exists $known_clients->{$address}) { + &update_known_clients(hostname=>$address, status=>$header); + } + + return; } #=== FUNCTION ================================================================ -# NAME: send_msg_hash2bus { -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: send_msg_hash2bus +# PARAMETERS: msg_hash - hash - xml_hash created with function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: ???? #=============================================================================== sub send_msg_hash2bus { - my($msg_hash, $target) = @_; + my($msg_hash) = @_; # fetch header for logging my $header = &get_content_from_xml_hash($msg_hash, "header"); - # generiere xml string + # generate xml string my $msg_xml = $xml->XMLout($msg_hash, RootName => 'xml'); # encrypt xml msg my $crypted_msg = &encrypt_msg($msg_xml, $bus_cipher); - # öffne socket + # open socket my $socket = &open_socket($bus_address); if(not defined $socket){ daemon_log( "cannot send '$header'-msg to $bus_address , bus not reachable", 5); return; } - # versende xml msg + # send xml msg print $socket $crypted_msg."\n"; - # schließe socket close $socket; @@ -881,15 +914,14 @@ sub send_msg_hash2bus { #=== FUNCTION ================================================================ # NAME: register_at_bus -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: creates an entry in known_daemons and send a 'here_i_am' msg to bus #=============================================================================== sub register_at_bus { - my ($tmp) = @_; # create known_daemons entry - &create_known_daemons_entry($bus_address); + &create_known_daemon($bus_address); &add_content2known_daemons(hostname=>$bus_address, status=>"register_at_bus", passwd=>$bus_passwd); my $msg_hash = &create_xml_hash("here_i_am", "$server_ip:$server_port", $bus_address); @@ -900,9 +932,9 @@ sub register_at_bus { #=== FUNCTION ================================================================ # NAME: new_passwd -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg_hash - ref - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message #=============================================================================== sub new_passwd { my ($msg_hash) = @_; @@ -918,21 +950,20 @@ sub new_passwd { } elsif (exists $known_clients->{$source}) { &add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd); - #my $hash = &create_xml_hash("confirm_new_passwd", "$server_ip:$server_port", "$source"); - #&send_msg_hash2address($hash, $source); } else { daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1) } - return + return; } + #=== FUNCTION ================================================================ -# NAME: make_ping -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: make ping +# PARAMETERS: address - string - address which should be pinged +# RETURNS: nothing +# DESCRIPTION: send ping message to address #=============================================================================== sub make_ping { my ($msg_hash) = @_; @@ -946,11 +977,12 @@ sub make_ping { return; } + #=== FUNCTION ================================================================ -# NAME: make_ping -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: got_ping +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message #=============================================================================== sub got_ping { my ($msg_hash) = @_; @@ -971,9 +1003,9 @@ sub got_ping { #=== FUNCTION ================================================================ # NAME: here_i_am -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message #=============================================================================== sub here_i_am { my ($msg_hash) = @_; @@ -1032,9 +1064,9 @@ sub here_i_am { #=== FUNCTION ================================================================ # NAME: who_has -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message #=============================================================================== sub who_has { my ($msg_hash) = @_ ; @@ -1047,12 +1079,9 @@ sub who_has { # scanning known_clients for search_pattern my @host_addresses = keys %$known_clients; my $known_clients_entries = length @host_addresses; - print "debug: who_has: $known_clients_entries entries in known_clients\n"; my $host_address; foreach my $host (@host_addresses) { - #print "debug: who_has: $host_address\n"; my $client_element = $known_clients->{$host}->{$search_pattern}; - print "debug: who_has: host $host with pattern $search_pattern and value $client_element\n"; if ($search_element eq $client_element) { $host_address = $host; last; @@ -1061,7 +1090,6 @@ sub who_has { # search was successful if (defined $host_address) { - print "debug: who_has: result: host $host_address has $search_pattern $search_element\n"; my $source = @{$msg_hash->{source}}[0]; my $out_msg = &create_xml_hash("who_has_i_do", $server_address, $source, "mac_address"); &add_content2xml_hash($out_msg, "mac_address", $search_element); @@ -1083,9 +1111,9 @@ sub who_has_i_do { #=== FUNCTION ================================================================ # NAME: update_status -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message #=============================================================================== sub update_status { my ($msg_hash) = @_; @@ -1093,27 +1121,28 @@ sub update_status { my $source = &get_content_from_xml_hash($msg_hash, "source"); my $new_status = (&get_content_from_xml_hash($msg_hash, "update_status"))[0]; - # find the source my $act_known_hash; if (exists $known_daemons->{$source}) { + &add_content2known_daemons(hostname=>$source, status=>$new_status); } elsif (exists $known_clients->{$source}) { - &add_content2known_clients(hostname=>$source, status=>$new_status); + &update_known_clients(hostname=>$source, status=>$new_status); + #&add_content2known_clients(hostname=>$source, status=>$new_status); } else { daemon_log("ERROR: got $header-msg, but cannot find $source in my hashes, unable to update status", 1); return; } - + return; } #=== FUNCTION ================================================================ # NAME: new_ldap_config -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: address - string - ip address and port of a host +# RETURNS: nothing +# DESCRIPTION: send to address the ldap configuration found for dn gotoLdapServer #=============================================================================== sub new_ldap_config { my ($address) = @_ ; @@ -1131,7 +1160,6 @@ sub new_ldap_config { # fetch dn my $goHard_cmd = "ldapsearch -x '(&(objectClass=goHard)(macAddress=00:11:22:33:44:57))' dn gotoLdapServer"; - #my $output= `$goHard_cmd 2>&1`; my $dn; my @gotoLdapServer; open (PIPE, "$goHard_cmd 2>&1 |"); @@ -1156,7 +1184,6 @@ sub new_ldap_config { # no gotoLdapServer found my $gosaGroupOfNames_cmd = "ldapsearch -x '(&(objectClass=gosaGroupOfNames)(member=$dn))' gotoLdapServer"; if (@gotoLdapServer == 0) { - #print "debug: new_ldap_config: gotoLdapServer ist leer\n"; open (PIPE, "$gosaGroupOfNames_cmd 2>&1 |"); while() { chomp $_; @@ -1181,9 +1208,7 @@ sub new_ldap_config { $_ =~ s/^\d://; } - #print "debug: new_ladp_config: dn: $dn\n"; my $t = join(" ", @gotoLdapServer); - #print "debug: new_ldap_config: gotoLdapServer: $t\n"; my $out_hash = &create_xml_hash("new_ldap_config", $server_address, $address); map(&add_content2xml_hash($out_hash, "new_ldap_config", $_), @gotoLdapServer); @@ -1193,6 +1218,13 @@ sub new_ldap_config { } +#=== FUNCTION ================================================================ +# NAME: execute_actions +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: invokes the script specified in msg_hash which is located under +# /etc/gosad/actions +#=============================================================================== sub execute_actions { my ($msg_hash) = @_ ; my $configdir= '/etc/gosad/actions/'; @@ -1232,24 +1264,24 @@ sub execute_actions { } # process the event result - print "debug: execute_actions: $header: $result\n"; + return; } #=== FUNCTION ================================================================ -# NAME: print_known_daemons_hash -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: print_known_daemons +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: nomen est omen #=============================================================================== -sub print_known_daemons_hash { - my ($hash) = @_; +sub print_known_daemons { + #my ($hash) = @_; print "####################################\n"; print "# status of known_daemons\n"; - my $hosts; - my $host_hash; + #my $hosts; + #my $host_hash; $shmda->shlock(LOCK_EX); my @hosts = keys %$known_daemons; foreach my $host (@hosts) { @@ -1258,9 +1290,9 @@ sub print_known_daemons_hash { my $passwd = $known_daemons->{$host}->{passwd}; my $timestamp = $known_daemons->{$host}->{timestamp}; print "$host\n"; - print "\t$status\n"; - print "\t$passwd\n"; - print "\t$timestamp\n"; + print "\tstatus: $status\n"; + print "\tpasswd: $passwd\n"; + print "\ttimestamp: $timestamp\n"; } $shmda->shunlock(LOCK_EX); print "####################################\n"; @@ -1268,18 +1300,137 @@ sub print_known_daemons_hash { } +#=== FUNCTION ================================================================ +# NAME: create_known_daemon +# PARAMETERS: hostname - string - key for the hash 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; +} + + +#=== FUNCTION ================================================================ +# NAME: add_content2known_daemons +# PARAMETERS: hostname - string - ip address and port of host (required) +# status - string - (optional) +# passwd - string - (optional) +# mac_address - string - mac address of host (optional) +# 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; +} + + +#=== FUNCTION ================================================================ +# NAME: update_known_daemons +# 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_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 ================================================================ # NAME: print_known_clients -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: nomen est omen #=============================================================================== sub print_known_clients { - my ($hash) = @_; + #my ($hash) = @_; print "####################################\n"; print "# status of known_clients\n"; - my $hosts; - my $host_hash; + #my $hosts; + #my $host_hash; $shmcl->shlock(LOCK_EX); my @hosts = keys %$known_clients; if (@hosts) { @@ -1292,7 +1443,7 @@ sub print_known_clients { print "$host\n"; print "\tstatus: $status\n"; print "\tpasswd: $passwd\n"; - print "\ttime: $timestamp\n"; + print "\ttimestamp: $timestamp\n"; print "\tmac_address: $mac_address\n"; print "\tevents: $events\n"; } @@ -1303,29 +1454,14 @@ sub print_known_clients { } -#=== FUNCTION ================================================================ -# NAME: create_known_daemons_entry -# PARAMETERS: -# RETURNS: -# DESCRIPTION: -#=============================================================================== -sub create_known_daemons_entry { - 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 ================================================================ # NAME: create_known_client -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: hostname - string - key for the hash known_clients +# RETURNS: nothing +# DESCRIPTION: creates a dummy entry for hostname in known_clients #=============================================================================== sub create_known_client { my ($hostname) = @_; @@ -1341,13 +1477,19 @@ sub create_known_client { } + + #=== FUNCTION ================================================================ -# NAME: add_content2known_daemons -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# 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_daemons { +sub add_content2known_clients { my $arg = { hostname => undef, status => undef, passwd => undef, mac_address => undef, events => undef, @@ -1359,7 +1501,7 @@ sub add_content2known_daemons { my $events = $arg->{events}; if (not defined $hostname) { - daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); + daemon_log("ERROR: function add_content2known_clients is not invoked with requiered parameter 'hostname'", 1); return; } @@ -1374,35 +1516,63 @@ sub add_content2known_daemons { $year+=1900; my $t = "$year$month$monthday$hours$minutes$seconds"; - $shmda->shlock(LOCK_EX); + $shmcl->shlock(LOCK_EX); if (defined $status) { - $known_daemons->{$hostname}->{status} = $status; + $known_clients->{$hostname}->{status} = $status; } if (defined $passwd) { - $known_daemons->{$hostname}->{passwd} = $passwd; + $known_clients->{$hostname}->{passwd} = $passwd; } if (defined $mac_address) { - $known_daemons->{$hostname}->{mac_address} = $mac_address; + $known_clients->{$hostname}->{mac_address} = $mac_address; } if (defined $events) { - $known_daemons->{$hostname}->{events} = $events; + $known_clients->{$hostname}->{events} = $events; } - $known_daemons->{$hostname}->{timestamp} = $t; - $shmda->shlock(LOCK_EX); + $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; + } + + 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: add_content2known_clients -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# 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 add_content2known_clients { +sub update_known_clients { my $arg = { hostname => undef, status => undef, passwd => undef, - mac_address => undef, events => undef, + mac_address => undef, events => undef, @_ }; my $hostname = $arg->{hostname}; my $status = $arg->{status}; @@ -1411,7 +1581,7 @@ sub add_content2known_clients { my $events = $arg->{events}; if (not defined $hostname) { - daemon_log("ERROR: function add_content2known_clients is not invoked with requiered parameter 'hostname'", 1); + daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); return; } @@ -1425,7 +1595,7 @@ sub add_content2known_clients { $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; @@ -1434,16 +1604,16 @@ sub add_content2known_clients { $known_clients->{$hostname}->{passwd} = $passwd; } if (defined $mac_address) { - $known_clients->{$hostname}->{mac_address} = $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); + $shmcl->shunlock(LOCK_EX); return; } - + #=== FUNCTION ================================================================ # NAME: open_fifo @@ -1454,8 +1624,8 @@ sub add_content2known_clients { sub open_fifo { my ($fifo_path) = @_ ; if( -p $fifo_path ) { - daemon_log("FIFO at $fifo_path already exists", 1); - return 0; + daemon_log("FIFO at $fifo_path already exists! Is being deleted!", 1); + unlink($fifo_path); } POSIX::mkfifo($fifo_path, 0666) or die "can't mkfifo $fifo_path: $!"; daemon_log( "FIFO started at $fifo_path", 1) ; @@ -1544,6 +1714,17 @@ if($arp_activ eq "on") { vec($rbits, fileno $arp_fifo, 1) = 1; } +# start gosa inferface fifo +if ($gosa_activ eq "on") { + &open_fifo($gosa_fifo_in); + sysopen(GOSA_FIFO_IN, $gosa_fifo_in, O_RDWR) or die "can't read from GOSA_FIFO_IN: $!" ; + vec($rbits, fileno GOSA_FIFO_IN, 1) = 1; + + &open_fifo($gosa_fifo_out); + sysopen(GOSA_FIFO_OUT, $gosa_fifo_out, O_RDWR) or die "can't read from GOSA_FIFO_IN: $!" ; + +} + ################################### #everything ready, okay, lets start @@ -1556,30 +1737,30 @@ while(1) { if($nf < 0 ) { } -# something is coming in - if(vec $rout, fileno $server, 1) { - my $client = $server->accept(); - my $other_end = getpeername($client); - if(not defined $other_end) { - daemon_log("client cannot be identified: $!"); - } else { - my ($port, $iaddr) = unpack_sockaddr_in($other_end); - my $actual_ip = inet_ntoa($iaddr); - daemon_log("accept client from $actual_ip", 5); - #my $in_msg = <$client>; - my $in_msg = &read_from_socket($client); - if(defined $in_msg){ - chomp($in_msg); - &activating_child($in_msg, $actual_ip); + # something is coming in + if($server_activ eq "on" && vec($rout, fileno $server, 1)) { + my $client = $server->accept(); + my $other_end = getpeername($client); + if(not defined $other_end) { + daemon_log("client cannot be identified: $!"); } else { - daemon_log("cannot read from $actual_ip", 5); + my ($port, $iaddr) = unpack_sockaddr_in($other_end); + my $actual_ip = inet_ntoa($iaddr); + daemon_log("accept client from $actual_ip", 5); + my $in_msg = &read_from_socket($client); + if(defined $in_msg){ + chomp($in_msg); + &activating_child($in_msg, $actual_ip); + } else { + daemon_log("cannot read from $actual_ip", 5); + } } + close($client); } - close($client); - } 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"; @@ -1600,18 +1781,27 @@ while(1) { print "\n"; } + if($gosa_activ eq "on" && vec($rout, fileno GOSA_FIFO_IN, 1)) { + my $in_msg = ; + chomp($in_msg); + print "gosa_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"; + } - -# something is going out - #if(vec $wbits, fileno $bus, 1){ - # print "msg leaving server to bus:$msg_to_bus\n"; - # print $bus $msg_to_bus."\n"; - # $msg_to_bus = ""; - - #} - } - - - - diff --git a/contrib/daemon/gosa-sd-bus b/contrib/daemon/gosa-sd-bus index 1dd9e8276..e3fd1a123 100755 --- a/contrib/daemon/gosa-sd-bus +++ b/contrib/daemon/gosa-sd-bus @@ -56,7 +56,7 @@ $shmkh = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, }, "bus" => {"bus_activ" => [\$bus_activ, "on"], - "bus_passwd" => [\$bus_passwd, "tester78901234567890123456789012"], + "bus_passwd" => [\$bus_passwd, "tester"], "bus_ip" => [\$bus_ip, "10.89.1.155"], "bus_port" => [\$bus_port, "10001"], "child_max" => [\$child_max, 10], @@ -68,8 +68,8 @@ $shmkh = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, #=== FUNCTION ================================================================ # NAME: read_configfile # PARAMETERS: cfg_file - string - -# RETURNS: -# DESCRIPTION: +# RETURNS: nothing +# DESCRIPTION: read cfg_file and set variables #=============================================================================== sub read_configfile { my $cfg; @@ -95,8 +95,8 @@ sub read_configfile { # PARAMETERS: level - string - default 'info' # msg - string - # facility - string - default 'LOG_DAEMON' -# RETURNS: -# DESCRIPTION: +# RETURNS: nothing +# DESCRIPTION: function for logging #=============================================================================== sub daemon_log { my( $msg, $level ) = @_; @@ -125,17 +125,15 @@ sub daemon_log { } #=== FUNCTION ================================================================ -# NAME: check_cmdline_param -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: check_cmdline_param +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: validates commandline parameter #=============================================================================== 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 = "gosa-sd-bus.cfg"; $cfg_file = File::Spec->catfile( $cwd, $name ); @@ -150,10 +148,10 @@ sub check_cmdline_param () { } #=== FUNCTION ================================================================ -# NAME: check_pid -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: check_pid +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: handels pid processing #=============================================================================== sub check_pid { $pid = -1; @@ -200,16 +198,12 @@ sub check_pid { #=== FUNCTION ================================================================ # NAME: usage -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: print out usage text to STDERR #=============================================================================== sub usage { - my( $text, $help ) = @_; - $text = undef if( "h" eq $text ); - (defined $text) && print STDERR "\n$text\n"; - if( (defined $help && $help) || (!defined $help && !defined $text) ) { - print STDERR << "EOF" ; + print STDERR << "EOF" ; usage: $0 [-hvf] [-c config] -h : this (help) message @@ -217,16 +211,15 @@ usage: $0 [-hvf] [-c config] -f : foreground, process will not be forked to background -v : be verbose (multiple to increase verbosity) EOF - } - print "\n" ; + print "\n" ; } #=== FUNCTION ================================================================ # NAME: sig_int_handler -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: signal - string - signal arose from system +# RETURNS: noting +# DESCRIPTION: handels tasks to be done befor signal becomes active #=============================================================================== sub sig_int_handler { my ($signal) = @_; @@ -243,34 +236,33 @@ $SIG{INT} = \&sig_int_handler; #=== FUNCTION ================================================================ # NAME: activating_child -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg - string - incoming message +# host - string - host from which the incomming message comes +# RETURNS: nothing +# DESCRIPTION: handels the distribution of incoming messages to working childs #=============================================================================== sub activating_child { my ($msg, $host) = @_; my $child = &get_processing_child(); my $pipe_wr = $$child{'pipe_wr'}; - daemon_log("activating: childpid: $$child{'pid'}", 5); - print $pipe_wr $msg.".".$host."\n"; return; - } #=== FUNCTION ================================================================ # NAME: get_processing_child -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: nothing +# RETURNS: child - hash - holding the process id and the references to the pipe +# handles pipe_wr and pipe_rd +# DESCRIPTION: handels the forking, reactivating and keeping alive tasks #=============================================================================== sub get_processing_child { my $child; - # schaue durch alle %busy_child{pipe_wr} ob irgendwo 'done' drinsteht, wenn ja, dann setze das kind von busy auf free um + # checking %busy_child{pipe_wr} if msg is 'done', then set child from busy to free while(my ($key, $val) = each(%busy_child)) { - # test ob prozess noch existiert + # check wether process still exists my $exitus_pid = waitpid($key, WNOHANG); if($exitus_pid != 0) { delete $busy_child{$key}; @@ -278,7 +270,7 @@ sub get_processing_child { next; } - # test ob prozess noch arbeitet + # check wether process sitll works my $fh = $$val{'pipe_rd'}; $fh->blocking(0); my $child_answer; @@ -298,12 +290,12 @@ sub get_processing_child { } daemon_log("free child:$key\n", 5); } - # teste @free_child und @busy_child + # check @free_child and @busy_child my $free_len = scalar(keys(%free_child)); my $busy_len = scalar(keys(%busy_child)); daemon_log("free children $free_len, busy children $busy_len\n",5); - # gibt es bereits ein freies kind, dann lass es arbeiten + # if there is a free child, let the child work if($free_len > 0){ my @keys = keys(%free_child); $child = $free_child{$keys[0]}; @@ -340,12 +332,14 @@ sub get_processing_child { while( 1 ) { my $rbits = ""; vec( $rbits, fileno $PARENT_rd , 1 ) = 1; + + # waiting child_timeout for jobs to do my $nf = select($rbits, undef, undef, $child_timeout); if($nf < 0 ) { - # wenn $nf < 1, error handling + # if $nf < 1, error handling die "select(): $!\n"; } elsif (! $nf) { - # ist dieses kind nicht eines der letzenen $child_min, dann springe aus while schleife raus + # if already child_min childs are alive, then leave loop $free_len = scalar(keys(%free_child)); $busy_len = scalar(keys(%busy_child)); if($free_len + $busy_len >= $child_min) { @@ -355,25 +349,27 @@ sub get_processing_child { } } - # ansonsten + # a job for a child arise if ( vec $rbits, fileno $PARENT_rd, 1 ) { - # hole alles was in der pipe ist + # read everything from pipe my $msg = ""; $PARENT_rd->blocking(0); while(1) { my $read = <$PARENT_rd>; if(not defined $read) { last} $msg .= $read; - } + } + + # forward the job msg to another function &process_incoming_msg($msg); daemon_log("processing of msg finished", 5); - # wichtig!!! erst mit dem done wird das child nach free_child geschoben + # important!!! wait until child says 'done', until then child is set from busy to free print $PARENT_wr "done"; redo; } } - # kinder die die while-schleife verlassen haben sterben + # childs leaving the loop are allowed to die exit(0); #PARENT @@ -398,9 +394,9 @@ sub get_processing_child { #=== FUNCTION ================================================================ # NAME: process_incoming_msg -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: crypted_msg - string - incoming crypted message +# RETURNS: nothing +# DESCRIPTION: handels the proceeded distribution to the appropriated functions #=============================================================================== sub process_incoming_msg { my ($crypted_msg) = @_; @@ -429,7 +425,7 @@ sub process_incoming_msg { my ($msg, $msg_hash); my $msg_flag = 0; - # ermittle alle in frage kommenden known_daemons einträge + # collect addresses from possible incoming clients foreach my $host_key (@valid_keys) { eval{ daemon_log( "key: $host_key\n", 7); @@ -467,11 +463,11 @@ sub process_incoming_msg { elsif($header eq 'ping') { &ping($msg_hash)} elsif($header eq 'who_has') { &who_has($msg_hash)} elsif($header eq 'new_client') { &new_client($msg_hash)} + elsif($header eq 'delete_client') { &delete_client($msg_hash)} } else { # msg is for any other server my @targets = @{$msg_hash->{target}}; my $len_targets = @targets; - print "debug: process_incoming_msg: number of targets for msg: $len_targets\n"; if ($len_targets == 0){ # no targets specified @@ -480,11 +476,9 @@ sub process_incoming_msg { } elsif ($targets[0] eq "*"){ # all deamons in known_daemons are targets - print "debug: process_incoming_msg: all deamons in known_daemons are targets\n"; my $target = $targets[0]; my $source = @{$msg_hash->{source}}[0]; - print "debug: process_incoming_msg: source: $source\n"; my @target_addresses = keys(%$known_daemons); foreach my $target_address (@target_addresses) { if ($target_address eq $source) { next; } @@ -495,20 +489,15 @@ sub process_incoming_msg { } else { # a list of targets is specified - print "debug: process_incoming_msg: a list of targets is specified\n"; my $target_address; foreach $target_address (@targets) { - print "debug: process_incoming_msg: target in targets: $target_address\n"; if (exists $known_daemons->{$target_address}) { - print "debug: process_incoming_msg: target is a daemon\n"; &send_msg_hash2address($msg_hash, $target_address); } else { - print "debug: process_incoming_msg: target is not a daemon\n"; my @daemon_addresses = keys %$known_daemons; my $daemon_address; foreach $daemon_address (@daemon_addresses) { - print "debug: process_incoming_msg: client is registered under daemon $daemon_address???\n"; if (exists $known_daemons->{$daemon_address}->{clients}->{$target_address}) { my $header = &get_content_from_xml_hash($msg_hash, "header"); &send_msg_hash2address($msg_hash, $daemon_address); @@ -533,17 +522,18 @@ sub process_incoming_msg { # RETURNS: # DESCRIPTION: #=============================================================================== -sub get_content_of_known_daemons { - my ($host, $content) = @_; - return; -} +#sub get_content_of_known_daemons { +# my ($host, $content) = @_; +# return; +#} #=== FUNCTION ================================================================ # NAME: encrypt_msg -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg - string - message to encrypt +# my_cipher - ref - reference to a Crypt::Rijndael object +# RETURNS: crypted_msg - string - crypted message +# DESCRIPTION: crypts the incoming message with the Crypt::Rijndael module #=============================================================================== sub encrypt_msg { my ($msg, $my_cipher) = @_; @@ -560,9 +550,10 @@ sub encrypt_msg { #=== FUNCTION ================================================================ # NAME: decrypt_msg -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: crypted_msg - string - message to decrypt +# my_cipher - ref - reference to a Crypt::Rijndael object +# RETURNS: msg - string - decrypted message +# DESCRIPTION: decrypts the incoming message with the Crypt::Rijndael module #=============================================================================== sub decrypt_msg { my ($crypted_msg, $my_cipher) =@_; @@ -576,25 +567,39 @@ sub decrypt_msg { #=== FUNCTION ================================================================ # NAME: create_xml_hash -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: header - string - message header (required) +# source - string - where the message come from (required) +# target - string - where the message should go to (required) +# [header_value] - string - something usefull (optional) +# RETURNS: hash - hash - nomen est omen +# DESCRIPTION: creates a key-value hash, all values are stored in a array #=============================================================================== sub create_xml_hash { - my ($header, $source, $target) = @_; + my ($header, $source, $target, $header_value) = @_ ; + + if (not defined $header || not defined $source || not defined $target) { + daemon_log("ERROR: create_xml_hash function is invoked with uncompleted parameters", 7); + } + my $hash = { header => [$header], source => [$source], target => [$target], - $header => [], + $header => [$header_value], }; - daemon_log("create_xml_hash:", 7), - chomp(my $tmp = Dumper $hash); - daemon_log("\t$tmp\n", 7); + #daemon_log("create_xml_hash:", 7), + #chomp(my $tmp = Dumper $hash); + #daemon_log("\t$tmp\n", 7); return $hash } +#=== FUNCTION ================================================================ +# NAME: create_xml_string +# PARAMETERS: xml_hash - hash - hash from function create_xml_hash +# RETURNS: xml_string - string - xml string representation of the hash +# DESCRIPTION: transform the hash to a string using XML::Simple module +#=============================================================================== sub create_xml_string { my ($xml_hash) = @_ ; my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml'); @@ -603,6 +608,14 @@ sub create_xml_string { } +#=== FUNCTION ================================================================ +# NAME: add_content2xml_hash +# PARAMETERS: xml_ref - ref - reference to a hash from function create_xml_hash +# element - string - key for the hash +# content - string - value for the hash +# RETURNS: nothing +# DESCRIPTION: add key-value pair to xml_ref, if key alread exists, then append value to list +#=============================================================================== sub add_content2xml_hash { my ($xml_ref, $element, $content) = @_; if(not exists $$xml_ref{$element} ) { @@ -616,9 +629,11 @@ sub add_content2xml_hash { #=== FUNCTION ================================================================ # NAME: get_content_from_xml_hash -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: xml_ref - ref - reference of the xml hash +# element - string - key of the value you want +# RETURNS: value - string - if key is either header, target or source +# value - list - for all other keys in xml hash +# DESCRIPTION: #=============================================================================== sub get_content_from_xml_hash { my ($xml_ref, $element) = @_; @@ -632,10 +647,10 @@ sub get_content_from_xml_hash { #=== FUNCTION ================================================================ # NAME: open_socket -# PARAMETERS: PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000 -# [PeerPort] string necessary if port not appended by PeerAddr -# RETURNS: socket IO::Socket::INET -# DESCRIPTION: +# PARAMETERS: PeerAddr - string - something like 192.168.1.1 or 192.168.1.1:10000 +# [PeerPort] - string - necessary if port not appended by PeerAddr +# RETURNS: socket - IO::Socket::INET +# DESCRIPTION: open a socket to PeerAddr #=============================================================================== sub open_socket { my ($PeerAddr, $PeerPort) = @_ ; @@ -650,16 +665,16 @@ sub open_socket { Timeout => 5, ); if(not defined $socket) { - #daemon_log("cannot connect to socket at $PeerAddr, $@\n"); return; } return $socket; } + #=== FUNCTION ================================================================ # NAME: read_from_socket -# PARAMETERS: socket fh - -# RETURNS: result string - readed characters from socket +# PARAMETERS: socket - fh - filehandel to read from +# RETURNS: result - string - readed characters from socket # DESCRIPTION: reads data from socket in 16 byte steps #=============================================================================== sub read_from_socket { @@ -670,8 +685,6 @@ sub read_from_socket { my $char; $len = sysread($socket, $char, 16); if($len != 16) { last } - #print "$char\n"; - #print " $len\n"; if($len != 16) { last } $result .= $char; } @@ -681,7 +694,7 @@ sub read_from_socket { #=== FUNCTION ================================================================ # NAME: send_msg_hash2address -# PARAMETERS: msg string - xml message +# PARAMETERS: msg_hash - hash - xml_hash created with function create_xml_hash # PeerAddr string - socket address to send msg # PeerPort string - socket port, if not included in socket address # RETURNS: nothing @@ -692,35 +705,41 @@ sub send_msg_hash2address { # fetch header for logging my $header = &get_content_from_xml_hash($msg_hash, "header"); - # generiere xml string + + # generate xml string my $msg_xml = &create_xml_string($msg_hash); - # hole das entsprechende passwd aus dem hash + + # fetch the appropriated passwd from hash my $passwd = $known_daemons->{$address}->{passwd}; - # erzeuge ein ciphering object + + # create a ciphering object my $act_cipher = &create_ciphering($passwd); + # encrypt xml msg my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher); - # öffne socket + + # open socket my $socket = &open_socket($address); if(not defined $socket){ - print "cannot send '$header'-msg to $address , server not reachable\n"; + daemon_log("ERROR: cannot send '$header'-msg to $address , server not reachable", 1); return; } - # versende xml msg + + # send 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 + return; } #=== FUNCTION ================================================================ -# NAME: -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# NAME: send_msg_hash2all +# PARAMETERS: msg_hash - hash - xml_hash created with function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: send msg_hash to all registered daemons #=============================================================================== sub send_msg_hash2all { my ($msg_hash) = @_; @@ -728,44 +747,36 @@ sub send_msg_hash2all { # fetch header for logging my $header = &get_content_from_xml_hash($msg_hash, "header"); - # generiere xml string + # generate xml string my $msg_xml = &create_xml_string($msg_hash); - # hole die liste von target adressen + # fetch a list of all target addresses my @targets = keys(%$known_daemons); - # itteriere durch liste und schicke an jeden msg_xml + # itterates through the list an send each the msg foreach my $target (@targets) { - if($target eq $bus_address) {next}; # schicke die nachricht nicht an den bus + if($target eq $bus_address) {next}; # do not send msg to bus - # hole das entsprechende passwd aus dem hash + # fetch the appropriated passwd my $passwd = $known_daemons->{$target}->{passwd}; - # erzeuge ein ciphering object + # create ciphering object my $act_cipher = &create_ciphering($passwd); # encrypt xml msg my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher); - # öffne socket + # open socket my $socket = &open_socket($target); if(not defined $socket){ - - # hole status für den server aus hash - my $status = $known_daemons->{$target}->{status}; - if(not $status eq "down") { - daemon_log("cannot open socket to $target , server not reachable", 1); - - # update status - &update_known_daemons_entry(hostname=>$target, status=>"down"); - } + daemon_log("ERROR: cannot open socket to $target , server not reachable", 1); + &update_known_daemons_entry(hostname=>$target, status=>"down"); next; } - # versende xml msg + # send xml msg print $socket $crypted_msg."\n"; - # schließe socket close $socket; daemon_log("send '$header'-msg to $target", 5); daemon_log("crypted_msg:\n\t$crypted_msg", 7); @@ -775,18 +786,18 @@ sub send_msg_hash2all { #=== FUNCTION ================================================================ -# NAME: create_ciphering_object -# PARAMETERS: -# RETURNS: cipher object -# DESCRIPTION: +# NAME: create_ciphering +# PARAMETERS: passwd - string - used to create ciphering +# RETURNS: cipher - object +# DESCRIPTION: creates a Crypt::Rijndael::MODE_CBC object with passwd as key #=============================================================================== sub create_ciphering { my ($passwd) = @_; + # passwd has to be of multiple length of 32, depend on Crypt::Rijndael::MODE_CBC my $passwd_length = length $passwd; my $multiplier = int($passwd_length / 32) + 1; my $extension = 32*$multiplier - $passwd_length; $passwd = "a"x$extension.$passwd; - my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC ); return $my_cipher; } @@ -794,25 +805,24 @@ sub create_ciphering { #=== FUNCTION ================================================================ # NAME: create_passwd -# PARAMETERS: -# RETURNS: cipher object -# DESCRIPTION: +# PARAMETERS: nothing +# RETURNS: new_passwd - string +# DESCRIPTION: creates a 32 bit long random passwd out of "a".."z","A".."Z",0..9 #=============================================================================== sub create_passwd { my $new_passwd = ""; for(my $i=0; $i<31; $i++) { $new_passwd .= ("a".."z","A".."Z",0..9)[int(rand(62))] } - return $new_passwd; } #=== FUNCTION ================================================================ # NAME: here_i_am -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process the incoming msg 'here_i_am' #=============================================================================== sub here_i_am { my ($msg_hash) = @_ ; @@ -825,8 +835,7 @@ sub here_i_am { &update_known_daemons_entry(hostname=>$source, status=>"registered", passwd=>$bus_passwd); # create outgoing msg - my $out_hash = &create_xml_hash("new_passwd", "$bus_ip:$bus_port", $source); - &add_content2xml_hash($out_hash, "new_passwd", $new_passwd); + my $out_hash = &create_xml_hash("new_passwd", "$bus_ip:$bus_port", $source, $new_passwd); &send_msg_hash2address($out_hash, $source); # change passwd, reason @@ -839,9 +848,9 @@ sub here_i_am { #=== FUNCTION ================================================================ # NAME: confirm_new_passwd -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message #=============================================================================== sub confirm_new_passwd { my ($msg_hash) = @_ ; @@ -853,9 +862,9 @@ sub confirm_new_passwd { #=== FUNCTION ================================================================ # NAME: ping -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message #=============================================================================== sub ping { my ($msg_hash) = @_ ; @@ -868,9 +877,9 @@ sub ping { #=== FUNCTION ================================================================ # NAME: make ping -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: address - string - address which should be pinged +# RETURNS: nothing +# DESCRIPTION: send ping message to address #=============================================================================== sub make_ping { my ($address) = @_; @@ -883,9 +892,9 @@ sub make_ping { #=== FUNCTION ================================================================ # NAME: got_ping -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message #=============================================================================== sub got_ping { my ($msg_hash) = @_; @@ -895,6 +904,12 @@ sub got_ping { } +#=== FUNCTION ================================================================ +# NAME: new_client +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message +#=============================================================================== sub new_client { my ($msg_hash) = @_ ; my $source = &get_content_from_xml_hash($msg_hash, "source"); @@ -906,12 +921,34 @@ sub new_client { } +#=== FUNCTION ================================================================ +# NAME: delete_client +# PARAMETERS: msg_hash - hash - hash from function create_xml_hash +# RETURNS: nothing +# DESCRIPTION: process this incoming message +#=============================================================================== +sub delete_client { + my ($msg_hash) = @_ ; + my $source = &get_content_from_xml_hash($msg_hash, "source"); + my $header = &get_content_from_xml_hash($msg_hash, "header"); + my $del_client = (&get_content_from_xml_hash($msg_hash, $header))[0]; + + print Dumper $msg_hash; + + if (not exists $known_daemons->{$source}->{$del_client}) { + daemon_log + } + delete $known_daemons->{$source}->{$del_client}; + + return; +} + #=== FUNCTION ================================================================ # NAME: print_known_daemons_hash -# PARAMETERS: -# RETURNS: -# DESCRIPTION: +# PARAMETERS: nothing +# RETURNS: nothing +# DESCRIPTION: nome est omen #=============================================================================== sub print_known_daemons_hash { my ($tmp) = @_; @@ -922,11 +959,10 @@ sub print_known_daemons_hash { $shmkh->shlock(LOCK_EX); my @hosts = keys %$known_daemons; foreach my $host (@hosts) { - #my @elements = keys %$known_daemons->{$host}; my $status = $known_daemons->{$host}->{status} ; my $passwd = $known_daemons->{$host}->{passwd}; my $timestamp = $known_daemons->{$host}->{timestamp}; - my @clients = keys %{%$known_daemons->{$host}->{clients}}; + my @clients = keys %{$known_daemons->{$host}->{clients}}; my $client_string = join(", ", @clients); print "$host\n"; print "\tstatus: $status\n"; @@ -940,6 +976,13 @@ sub print_known_daemons_hash { return; } + +#=== FUNCTION ================================================================ +# NAME: create_known_daemons_entry +# PARAMETERS: hostname - string - ip address and port of host +# RETURNS: nothing +# DESCRIPTION: nome est omen +#=============================================================================== sub create_known_daemons_entry { my ($hostname) = @_; $shmkh->shlock(LOCK_EX); @@ -952,6 +995,16 @@ sub create_known_daemons_entry { return; } + +#=== FUNCTION ================================================================ +# NAME: update_known_daemons_entry +# 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_daemons_entry { my $arg = { hostname => undef, status => undef, passwd => undef, @@ -994,22 +1047,6 @@ sub update_known_daemons_entry { } - -# $shmkh->shlock(LOCK_EX); -# if($status) { -# $known_daemons->{$hostname}->{status} = $status; -# } -# if($passwd) { -# $known_daemons->{$hostname}->{passwd} = $passwd; -# } -# if($lcient -# $known_daemons->{$hostname}->{timestamp} = $t; -# $shmkh->shunlock(LOCK_EX); -# return; -#} - - - #==== MAIN = main ============================================================== # parse commandline options @@ -1021,7 +1058,6 @@ GetOptions("h|help" => \&usage, ); # read and set config parameters - &check_cmdline_param ; &read_configfile; &check_pid; @@ -1070,7 +1106,7 @@ if($bus_activ eq "on") { print "start bus at $bus_ip:$bus_port\n"; } -# füge den bus zu known_daemons hinzu +# add bus to known_daemons &create_known_daemons_entry($bus_address); &update_known_daemons_entry(hostname=>$bus_address, status=>"bus", passwd=>$bus_passwd); @@ -1091,7 +1127,6 @@ while(1) { my ($port, $iaddr) = unpack_sockaddr_in($other_end); my $actual_ip = inet_ntoa($iaddr); daemon_log("\naccept client from $actual_ip\n", 5); - #my $in_msg = <$client>; my $in_msg = &read_from_socket($client); if(defined $in_msg){ &activating_child($in_msg, $actual_ip); @@ -1102,10 +1137,6 @@ while(1) { close($client); } - # something is going out - if(vec $wbits, fileno $bus, 1){ - - } } diff --git a/contrib/daemon/gosa-sd.cfg b/contrib/daemon/gosa-sd.cfg index cfa4ec37e..5fa22df5a 100644 --- a/contrib/daemon/gosa-sd.cfg +++ b/contrib/daemon/gosa-sd.cfg @@ -20,8 +20,10 @@ max_clients = 5 [arp] arp_activ = on -arp_fifo_path = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/fifo - - +arp_fifo_path = /etc/gosad/fifo/arp_fifo +[gosa] +gosa_activ = on +gosa_fifo_in = /etc/gosad/fifo/gosa_fifo_in +gosa_fifo_out = /etc/gosad/fifo/gosa_fifo_out -- 2.30.2