From: rettenbe Date: Wed, 31 Oct 2007 09:58:28 +0000 (+0000) Subject: Namensänderungen X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=76ab8009bb0334238c4fcd7f90cbafc283d5c504;p=gosa.git Namensänderungen gosa-sd -> arp-handler-d git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@7697 594d385d-05f5-0310-b6e9-bd551577e9d8 --- diff --git a/contrib/daemon/arp-handler-d b/contrib/daemon/arp-handler-d new file mode 100755 index 000000000..b8698bcf7 --- /dev/null +++ b/contrib/daemon/arp-handler-d @@ -0,0 +1,563 @@ +#!/usr/bin/perl +#=============================================================================== +# +# FILE: gosa-support-daemon.pl +# +# USAGE: ./.gosa-support-daemon.pl +# +# DESCRIPTION: +# +# OPTIONS: --- +# REQUIREMENTS: --- +# BUGS: --- +# NOTES: --- +# AUTHOR: Andreas Rettenberger, +# COMPANY: Gonicus GmbH, Arnsberg +# VERSION: 1.0 +# CREATED: 21.08.2007 15:13:51 CEST +# REVISION: --- +#=============================================================================== + +use strict; +use warnings; +use Getopt::Long; +use Config::IniFiles; +use POSIX; +use Fcntl; +use Net::LDAP; +use Net::LDAP::LDIF; +use Net::LDAP::Entry; +use Switch; + + +my ($verbose, $cfg_file, $log_file, $pid_file, $foreground); +my ($timeout, $mailto, $mailfrom, $user, $group); +my ($procid, $pid, $loglevel); +my ($fifo_path, $max_process_timeout, $max_process ); +my %daemon_children; +my ($ldap, $bind_phrase, $password, $ldap_base) ; + +$procid = -1 ; +$foreground = 0 ; +$verbose = 0 ; +$max_process = 2 ; +$max_process_timeout = 1 ; +$ldap_base = "dc=gonicus,dc=de" ; +#$ldap_path = "/var/run/gosa-support-daemon.socket"; +#$log_path = "/var/log/gosa-support-daemon.log"; +#$pid_path = "/var/run/gosa-support-daemon/gosa-support-daemon.pid"; + +#--------------------------------------------------------------------------- +# parse commandline options +#--------------------------------------------------------------------------- +Getopt::Long::Configure( "bundling" ); +GetOptions( "v|verbose+" => \$verbose, + "c|config=s" => \$cfg_file, + "h|help" => \&usage, + "l|logfile=s" => \$log_file, + "p|pid=s" => \$pid_file, + "f|foreground" => \$foreground); + +#--------------------------------------------------------------------------- +# read and set config parameters +#--------------------------------------------------------------------------- +my %cfg_defaults = +("Allgemein" => + {"timeout" => [ \$timeout, 1000 ], + "mailto" => [ \$mailto, 'root@localhost' ], + "mailfrom" => [ \$mailfrom, 'sps-daemon@localhost' ], + "user" => [ \$user, "nobody" ], + "group" => [ \$group, "nogroup" ], + "fifo_path" => [ \$fifo_path, "/home/rettenbe/gonicus/gosa-support/tmp/fifo" ], + "log_file" => [ \$log_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.log" ], + "pid_file" => [ \$pid_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.pid" ], + "loglevel" => [ \$loglevel, 1] + }, +"LDAP" => + {"bind" => [ \$bind_phrase, "cn=ldapadmin,dc=gonicus,dc=de" ], + "password" => [ \$password, "tester" ], + } + ); +&read_configfile; + + +#=== FUNCTION ================================================================ +# NAME: check_cmdline_param +# PURPOSE: checks all commandline parameters to validity +# PARAMETERS: none +# RETURNS: none +# DESCRIPTION: ???? +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub check_cmdline_param () { + my $err_config; + my $err_log; + my $err_pid; + my $err_counter = 0; + if( not defined( $cfg_file)) { + $err_config = "please specify a config file"; + $err_counter += 1; + } + if( not defined( $log_file)) { + $err_log = "please specify a log file"; + $err_counter += 1; + } + if( not defined( $pid_file)) { + $err_pid = "please specify a pid file"; + $err_counter += 1; + } + if( $err_counter > 0 ) { + &usage( "", 1 ); + if( defined( $err_config)) { print STDERR "$err_config\n"} + if( defined( $err_log)) { print STDERR "$err_log\n" } + if( defined( $err_pid)) { print STDERR "$err_pid\n"} + print STDERR "\n"; + exit( -1 ); + } +} + +#=== FUNCTION ================================================================ +# NAME: check_pid +# PURPOSE: +# PARAMETERS: none +# RETURNS: none +# DESCRIPTION: ???? +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub check_pid { + if( open( LOCK_FILE, "<$pid_file") ) { + $procid = ; + if( defined $procid ) { + chomp( $procid ); + if( -f "/proc/$procid/stat" ) { + my($stat) = `cat /proc/$procid/stat` =~ m/$procid \((.+)\).*/; + print "\t".$stat."\n"; + if( "sps-daemon.pl" eq $stat ) { + close( LOCK_FILE ); + exit -1; + } + } + } + close( LOCK_FILE ); + unlink( $pid_file ); + } + + # Try to open PID file + if (!sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) { + my($msg) = "Couldn't obtain lockfile '$pid_file' "; + if (open(LOCK_FILE, "<", $pid_file) && ($pid = )) { + chomp($pid); + $msg .= "(PID $pid)\n"; + } else { + $msg .= "(unable to read PID)\n"; + } + if ( ! $foreground ) { + daemon_log( $msg."\n"); + } else { + print( STDERR " $msg " ); + } + exit( -1 ); + } +} + +#=== FUNCTION ================================================================ +# NAME: read_configfile +# PURPOSE: read the configuration file and provide the programm with +# parameters +# PARAMETERS: none +# RETURNS: none +# DESCRIPTION: ???? +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub read_configfile { + my $log_time = localtime(time); + my $cfg; + if( defined( $cfg_file) && ( length($cfg_file) > 0 )) { + if( -r $cfg_file ) { + $cfg = Config::IniFiles->new( -file => $cfg_file ); + } else { + usage( "Couldn't read config file: $cfg_file \n" ); + } + } else { + $cfg = Config::IniFiles->new() ; + } + + foreach my $section (keys %cfg_defaults) { # "Parse" config into values + foreach my $param (keys %{$cfg_defaults{ $section }}) { + my $pinfo = $cfg_defaults{ $section }{ $param }; + ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] ); + } + } + + if(-e $log_file ) { unlink $log_file } + daemon_log("$log_time: config file read\n"); +} + +#=== FUNCTION ================================================================ +# NAME: daemon_log +# PURPOSE: log messages to specified logfile +# PARAMETERS: $msg, $level +# RETURNS: ???? +# DESCRIPTION: Takes a message ($msg) and append it to the logfile. The +# standard log-level ($level) is 1. Messages whith higher level +# than the verbosity-level (defined by commandline) are printed +# out to commandline. Messages with log-level lower than 2 are +# not logged to logfile! +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub daemon_log { + my( $msg, $level ) = @_; + if(not defined $msg) { return } + if(not defined $level) { $level = 1 } + open(LOG_HANDLE, ">>$log_file"); + if(not defined open( LOG_HANDLE, ">>$log_file" ) ) { return } + chomp($msg); + #if( $verbose >= $level ) { print "$msg"."\n" } + if( $level <= 1 ) { print LOG_HANDLE $msg."\n" } + if( $foreground ) { print $msg."\n" } + close( LOG_HANDLE ); + } + +#=== FUNCTION ================================================================ +# NAME: signal handler +# PURPOSE: catches signals from the programm and do diffrent things +# than default +# PARAMETERS: none +# RETURNS: none +# DESCRIPTION: sighandler +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub sigINT { + my $log_time = localtime(time); + print "INT\n"; + if( -p $fifo_path ) { + close FIFO ; + unlink($fifo_path) ; + daemon_log( "$log_time: FIFO closed after signal INT!\n") ; + } + if(defined($ldap)) { + $ldap->unbind; + } + $SIG{INT} = "DEFAULT" ; + kill INT => $$ ; +} +$SIG{INT} = \&sigINT ; + +#=== FUNCTION ================================================================ +# NAME: usage +# PURPOSE: +# PARAMETERS: none +# RETURNS: none +# DESCRIPTION: print out the usage of the program +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +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" ; +usage: $0 [-hvf] [-c config, -l logfile, -p pidfile] + + -h : this (help) message + -c : config file + -l : log file (example: /var/log/sps/sps.log) + -p : pid file (example: /var/run/sps/sps.pid) + -f : foreground (don"t fork) + -v : be verbose (multiple to increase verbosity) +EOF + } + print "\n" ; +} + + +#=== FUNCTION ================================================================ +# NAME: open_fifo +# PURPOSE: +# PARAMETERS: $fifo_path +# RETURNS: 0: FIFO couldn"t be setup, 1: FIFO setup correctly +# DESCRIPTION: creates a FIFO at $fifo_path +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub open_fifo { + my ($fifo_path) = @_ ; + my $log_time = localtime( time ); + if( -p $fifo_path ) { + daemon_log("$log_time: FIFO at $fifo_path already exists\n"); + return 0; + } + POSIX::mkfifo($fifo_path, 0666) or die "can't mkfifo $fifo_path: $!"; + daemon_log( "$log_time: FIFO started at $fifo_path\n" ) ; + return 1; + } + + +#=== FUNCTION ================================================================ +# NAME: add_ldap_entry +# PURPOSE: adds an element to ldap-tree +# PARAMETERS: +# RETURNS: none +# DESCRIPTION: ???? +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub add_ldap_entry { + my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus, $ip, $interface, $desc) = @_; + my $dn = "cn=$mac,ou=incoming,$ldap_base"; + my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))"); + my $c_res = $s_res->count; + if($c_res == 1) { + daemon_log("WARNING: macAddress $mac already in LDAP", 1); + return; + } elsif($c_res > 0) { + daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1); + return; + } + + # create LDAP entry + my $entry = Net::LDAP::Entry->new( $dn ); + $entry->dn($dn); + $entry->add("objectClass" => "goHard"); + $entry->add("cn" => $mac); + $entry->add("macAddress" => $mac); + if(defined $gotoSysStatus) {$entry->add("gotoSysStatus" => $gotoSysStatus)} + if(defined $ip) {$entry->add("ipHostNumber" => $ip) } + #if(defined $interface) { } + if(defined $desc) {$entry->add("description" => $desc) } + + # submit entry to LDAP + my $result = $entry->update ($ldap_tree); + + # for $result->code constants please look at Net::LDAP::Constant + my $log_time = localtime( time ); + if($result->code == 68) { # entry already exists + daemon_log("WARNING: $log_time: $dn ".$result->error, 3); + } elsif($result->code == 0) { # everything went fine + daemon_log("$log_time: add entry $dn to ldap", 1); + } else { # if any other error occur + daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1); + } + return; +} + + +#=== FUNCTION ================================================================ +# NAME: change_ldap_entry +# PURPOSE: ???? +# PARAMETERS: ???? +# RETURNS: ???? +# DESCRIPTION: ???? +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub change_ldap_entry { + my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus ) = @_; + + # check if ldap_entry exists or not + my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))"); + my $c_res = $s_res->count; + if($c_res == 0) { + daemon_log("WARNING: macAddress $mac not in LDAP", 1); + return; + } elsif($c_res > 1) { + daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1); + return; + } + + my $s_res_entry = $s_res->pop_entry(); + my $dn = $s_res_entry->dn(); + my $result = $ldap->modify( $dn, replace => {'gotoSysStatus' => $gotoSysStatus } ); + + # for $result->code constants please look at Net::LDAP::Constant + my $log_time = localtime( time ); + if($result->code == 32) { # entry doesnt exists + &add_ldap_entry($mac, $gotoSysStatus); + } elsif($result->code == 0) { # everything went fine + daemon_log("$log_time: entry $dn changed successful", 1); + } else { # if any other error occur + daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1); + } + + return; +} + +#=== FUNCTION ================================================================ +# NAME: search_ldap_entry +# PURPOSE: ???? +# PARAMETERS: [Net::LDAP] $ldap_tree - object of an ldap-tree +# string $sub_tree - dn of the subtree the search is performed +# string $search_string - either a string or a Net::LDAP::Filter object +# RETURNS: [Net::LDAP::Search] $msg - result object of the performed search +# DESCRIPTION: ???? +# THROWS: no exceptions +# COMMENTS: none +# SEE ALSO: n/a +#=============================================================================== +sub search_ldap_entry { + my ($ldap_tree, $sub_tree, $search_string) = @_; + my $msg = $ldap_tree->search( # perform a search + base => $sub_tree, + filter => $search_string, + ) or daemon_log("cannot perform search at ldap: $@", 1); +# if(defined $msg) { +# print $sub_tree."\t".$search_string."\t"; +# print $msg->count."\n"; +# foreach my $entry ($msg->entries) { $entry->dump; }; +# } + + return $msg; +} + + + +#========= MAIN = main ======================================================== +daemon_log( "####### START DAEMON ######\n", 1 ); +&check_cmdline_param ; +&check_pid; +&open_fifo($fifo_path); + +# Just fork, if we"re not in foreground mode +if( ! $foreground ) { $pid = fork(); } +else { $pid = $$; } + +# Do something useful - put our PID into the pid_file +if( 0 != $pid ) { + open( LOCK_FILE, ">$pid_file" ); + print LOCK_FILE "$pid\n"; + close( LOCK_FILE ); + if( !$foreground ) { exit( 0 ) }; +} + + +if( not -p $fifo_path ) { die "fifo file disappeared\n" } +sysopen(FIFO, $fifo_path, O_RDONLY) or die "can't read from $fifo_path: $!" ; + +while( 1 ) { + # checke alle prozesse im hash daemon_children ob sie noch aktiv sind, wenn + # nicht, dann entferne prozess aus hash + while( (my $key, my $val) = each( %daemon_children) ) { + my $status = waitpid( $key, &WNOHANG) ; + if( $status == -1 ) { + delete $daemon_children{$key} ; + daemon_log("childprocess finished: $key", 3) ; + } + } + + # ist die max_process anzahl von prozesskindern erreicht, dann warte und + # prüfe erneut, ob in der zwischenzeit prozesse fertig geworden sind + if( keys( %daemon_children ) >= $max_process ) { + sleep($max_process_timeout) ; + next ; + } + + my $msg = ; + if( not defined( $msg )) { next ; } + + chomp( $msg ); + if( length( $msg ) == 0 ) { next ; } + + my $forked_pid = fork(); +#=== PARENT = parent ========================================================== + if ( $forked_pid != 0 ) { + daemon_log("childprocess forked: $forked_pid", 3) ; + $daemon_children{$forked_pid} = 0 ; + } +#=== CHILD = child ============================================================ + else { + # parse the incoming message from arp, split the message and return + # the values in an array. not defined values are set to "none" + #my ($mac, $ip, $interface, $arp_sig, $desc) = &parse_input( $msg ) ; + daemon_log( "childprocess read from arp: $fifo_path\nline: $msg", 3); + my ($mac, $ip, $interface, $arp_sig, $desc) = split('\s', $msg, 5); + + # create connection to LDAP + $ldap = Net::LDAP->new( "localhost" ) or die "$@"; + $ldap->bind($bind_phrase, + password => $password, + ) ; + + switch($arp_sig) { + case 0 {&change_ldap_entry($ldap, $ldap_base, + $mac, "ip-changed", + )} + case 1 {&change_ldap_entry($ldap, $ldap_base, + $mac, "mac-not-whitelisted", + )} + case 2 {&change_ldap_entry($ldap, $ldap_base, + $mac, "mac-in-blacklist", + )} + case 3 {&add_ldap_entry($ldap, $ldap_base, + $mac, "new-mac-address", $ip, + $interface, $desc, + )} + case 4 {&change_ldap_entry($ldap, $ldap_base, + $mac, "unauthorized-arp-request", + )} + case 5 {&change_ldap_entry($ldap, $ldap_base, + $mac, "abusive-number-of-arp-requests", + )} + case 6 {&change_ldap_entry($ldap, $ldap_base, + $mac, "ether-and-arp-mac-differs", + )} + case 7 {&change_ldap_entry($ldap, $ldap_base, + $mac, "flood-detected", + )} + case 8 {&add_ldap_entry($ldap, $ldap_base, + $mac, $ip, "new-system", + )} + case 9 {&change_ldap_entry($ldap, $ldap_base, + $mac, "mac-changed", + )} + } + + + # ldap search +# my $base_phrase = "dc=gonicus,dc=de"; +# my $filter_phrase = "cn=keinesorge"; +# my $attrs_phrase = "cn macAdress"; +# my $msg_search = $ldap->search( base => $base_phrase, +# filter => $filter_phrase, +# attrs => $attrs_phrase, +# ); +# $msg_search->code && die $msg_search->error; +# +# my @entries = $msg_search->entries; +# my $max = $msg_search->count; +# print "anzahl der entries: $max\n"; +# my $i; +# for ( $i = 0 ; $i < $max ; $i++ ) { +# my $entry = $msg_search->entry ( $i ); +# foreach my $attr ( $entry->attributes ) { +# if( not $attr eq "cn") { +# next; +# } +# print join( "\n ", $attr, $entry->get_value( $attr ) ), "\n\n"; +# } +# } + + # ldap add + + + $ldap->unbind; + exit; + } + +} + + diff --git a/contrib/daemon/arp-handler-d.cfg b/contrib/daemon/arp-handler-d.cfg new file mode 100644 index 000000000..36c24a35b --- /dev/null +++ b/contrib/daemon/arp-handler-d.cfg @@ -0,0 +1,14 @@ +[Allgemein] +timeout = 1000 +mailto = root@localhost +mailfrom = gosa-sd@localhost +user = rettenbe +group = usr +fifo_path = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/fifo +log_file = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/gosa-sd.log +pid_file = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/gosa-sd.pid +loglevel = 1 + +[LDAP] +bind = cn=ldapadmin,dc=gonicus,dc=de +password = tester diff --git a/contrib/daemon/gosa-sd b/contrib/daemon/gosa-sd deleted file mode 100755 index 3db6576aa..000000000 --- a/contrib/daemon/gosa-sd +++ /dev/null @@ -1,562 +0,0 @@ -#!/usr/bin/perl -#=============================================================================== -# -# FILE: gosa-support-daemon.pl -# -# USAGE: ./.gosa-support-daemon.pl -# -# DESCRIPTION: -# -# OPTIONS: --- -# REQUIREMENTS: --- -# BUGS: --- -# NOTES: --- -# AUTHOR: Andreas Rettenberger, -# COMPANY: Gonicus GmbH, Arnsberg -# VERSION: 1.0 -# CREATED: 21.08.2007 15:13:51 CEST -# REVISION: --- -#=============================================================================== - -use strict; -use warnings; -use Getopt::Long; -use Config::IniFiles; -use POSIX; -use Fcntl; -use Net::LDAP; -use Net::LDAP::LDIF; -use Net::LDAP::Entry; -use Switch; - - -my ($verbose, $cfg_file, $log_file, $pid_file, $foreground); -my ($timeout, $mailto, $mailfrom, $user, $group); -my ($procid, $pid, $loglevel); -my ($fifo_path, $max_process_timeout, $max_process ); -my %daemon_children; -my ($ldap, $bind_phrase, $password, $ldap_base) ; - -$procid = -1 ; -$foreground = 0 ; -$verbose = 0 ; -$max_process = 2 ; -$max_process_timeout = 1 ; -$ldap_base = "dc=gonicus,dc=de" ; -#$ldap_path = "/var/run/gosa-support-daemon.socket"; -#$log_path = "/var/log/gosa-support-daemon.log"; -#$pid_path = "/var/run/gosa-support-daemon/gosa-support-daemon.pid"; - -#--------------------------------------------------------------------------- -# parse commandline options -#--------------------------------------------------------------------------- -Getopt::Long::Configure( "bundling" ); -GetOptions( "v|verbose+" => \$verbose, - "c|config=s" => \$cfg_file, - "h|help" => \&usage, - "l|logfile=s" => \$log_file, - "p|pid=s" => \$pid_file, - "f|foreground" => \$foreground); - -#--------------------------------------------------------------------------- -# read and set config parameters -#--------------------------------------------------------------------------- -my %cfg_defaults = -("Allgemein" => - {"timeout" => [ \$timeout, 1000 ], - "mailto" => [ \$mailto, 'root@localhost' ], - "mailfrom" => [ \$mailfrom, 'sps-daemon@localhost' ], - "user" => [ \$user, "nobody" ], - "group" => [ \$group, "nogroup" ], - "fifo_path" => [ \$fifo_path, "/home/rettenbe/gonicus/gosa-support/tmp/fifo" ], - "log_file" => [ \$log_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.log" ], - "pid_file" => [ \$pid_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.pid" ], - "loglevel" => [ \$loglevel, 1] - }, -"LDAP" => - {"bind" => [ \$bind_phrase, "cn=ldapadmin,dc=gonicus,dc=de" ], - "password" => [ \$password, "tester" ], - } - ); -&read_configfile; - - -#=== FUNCTION ================================================================ -# NAME: check_cmdline_param -# PURPOSE: checks all commandline parameters to validity -# PARAMETERS: none -# RETURNS: none -# DESCRIPTION: ???? -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub check_cmdline_param () { - my $err_config; - my $err_log; - my $err_pid; - my $err_counter = 0; - if( not defined( $cfg_file)) { - $err_config = "please specify a config file"; - $err_counter += 1; - } - if( not defined( $log_file)) { - $err_log = "please specify a log file"; - $err_counter += 1; - } - if( not defined( $pid_file)) { - $err_pid = "please specify a pid file"; - $err_counter += 1; - } - if( $err_counter > 0 ) { - &usage( "", 1 ); - if( defined( $err_config)) { print STDERR "$err_config\n"} - if( defined( $err_log)) { print STDERR "$err_log\n" } - if( defined( $err_pid)) { print STDERR "$err_pid\n"} - print STDERR "\n"; - exit( -1 ); - } -} - -#=== FUNCTION ================================================================ -# NAME: check_pid -# PURPOSE: -# PARAMETERS: none -# RETURNS: none -# DESCRIPTION: ???? -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub check_pid { - if( open( LOCK_FILE, "<$pid_file") ) { - $procid = ; - if( defined $procid ) { - chomp( $procid ); - if( -f "/proc/$procid/stat" ) { - my($stat) = `cat /proc/$procid/stat` =~ m/$procid \((.+)\).*/; - print "\t".$stat."\n"; - if( "sps-daemon.pl" eq $stat ) { - close( LOCK_FILE ); - exit -1; - } - } - } - close( LOCK_FILE ); - unlink( $pid_file ); - } - - # Try to open PID file - if (!sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) { - my($msg) = "Couldn't obtain lockfile '$pid_file' "; - if (open(LOCK_FILE, "<", $pid_file) && ($pid = )) { - chomp($pid); - $msg .= "(PID $pid)\n"; - } else { - $msg .= "(unable to read PID)\n"; - } - if ( ! $foreground ) { - daemon_log( $msg."\n"); - } else { - print( STDERR " $msg " ); - } - exit( -1 ); - } -} - -#=== FUNCTION ================================================================ -# NAME: read_configfile -# PURPOSE: read the configuration file and provide the programm with -# parameters -# PARAMETERS: none -# RETURNS: none -# DESCRIPTION: ???? -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub read_configfile { - my $log_time = localtime(time); - my $cfg; - if( defined( $cfg_file) && ( length($cfg_file) > 0 )) { - if( -r $cfg_file ) { - $cfg = Config::IniFiles->new( -file => $cfg_file ); - } else { - usage( "Couldn't read config file: $cfg_file \n" ); - } - } else { - $cfg = Config::IniFiles->new() ; - } - - foreach my $section (keys %cfg_defaults) { # "Parse" config into values - foreach my $param (keys %{$cfg_defaults{ $section }}) { - my $pinfo = $cfg_defaults{ $section }{ $param }; - ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] ); - } - } - - if(-e $log_file ) { unlink $log_file } - daemon_log("$log_time: config file read\n"); -} - -#=== FUNCTION ================================================================ -# NAME: daemon_log -# PURPOSE: log messages to specified logfile -# PARAMETERS: $msg, $level -# RETURNS: ???? -# DESCRIPTION: Takes a message ($msg) and append it to the logfile. The -# standard log-level ($level) is 1. Messages whith higher level -# than the verbosity-level (defined by commandline) are printed -# out to commandline. Messages with log-level lower than 2 are -# not logged to logfile! -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub daemon_log { - my( $msg, $level ) = @_; - if(not defined $msg) { return } - if(not defined $level) { $level = 1 } - open(LOG_HANDLE, ">>$log_file"); - if(not defined open( LOG_HANDLE, ">>$log_file" ) ) { return } - chomp($msg); - if( $verbose >= $level ) { print "$msg"."\n" } - if( $level <= 1 ) { print LOG_HANDLE $msg."\n" } - close( LOG_HANDLE ); - } - -#=== FUNCTION ================================================================ -# NAME: signal handler -# PURPOSE: catches signals from the programm and do diffrent things -# than default -# PARAMETERS: none -# RETURNS: none -# DESCRIPTION: sighandler -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub sigINT { - my $log_time = localtime(time); - print "INT\n"; - if( -p $fifo_path ) { - close FIFO ; - unlink($fifo_path) ; - daemon_log( "$log_time: FIFO closed after signal INT!\n") ; - } - if(defined($ldap)) { - $ldap->unbind; - } - $SIG{INT} = "DEFAULT" ; - kill INT => $$ ; -} -$SIG{INT} = \&sigINT ; - -#=== FUNCTION ================================================================ -# NAME: usage -# PURPOSE: -# PARAMETERS: none -# RETURNS: none -# DESCRIPTION: print out the usage of the program -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -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" ; -usage: $0 [-hvf] [-c config, -l logfile, -p pidfile] - - -h : this (help) message - -c : config file - -l : log file (example: /var/log/sps/sps.log) - -p : pid file (example: /var/run/sps/sps.pid) - -f : foreground (don"t fork) - -v : be verbose (multiple to increase verbosity) -EOF - } - print "\n" ; -} - - -#=== FUNCTION ================================================================ -# NAME: open_fifo -# PURPOSE: -# PARAMETERS: $fifo_path -# RETURNS: 0: FIFO couldn"t be setup, 1: FIFO setup correctly -# DESCRIPTION: creates a FIFO at $fifo_path -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub open_fifo { - my ($fifo_path) = @_ ; - my $log_time = localtime( time ); - if( -p $fifo_path ) { - daemon_log("$log_time: FIFO at $fifo_path already exists\n"); - return 0; - } - POSIX::mkfifo($fifo_path, 0666) or die "can't mkfifo $fifo_path: $!"; - daemon_log( "$log_time: FIFO started at $fifo_path\n" ) ; - return 1; - } - - -#=== FUNCTION ================================================================ -# NAME: add_ldap_entry -# PURPOSE: adds an element to ldap-tree -# PARAMETERS: -# RETURNS: none -# DESCRIPTION: ???? -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub add_ldap_entry { - my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus, $ip, $interface, $desc) = @_; - my $dn = "cn=$mac,ou=incoming,$ldap_base"; - my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))"); - my $c_res = $s_res->count; - if($c_res == 1) { - daemon_log("WARNING: macAddress $mac already in LDAP", 1); - return; - } elsif($c_res > 0) { - daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1); - return; - } - - # create LDAP entry - my $entry = Net::LDAP::Entry->new( $dn ); - $entry->dn($dn); - $entry->add("objectClass" => "goHard"); - $entry->add("cn" => $mac); - $entry->add("macAddress" => $mac); - if(defined $gotoSysStatus) {$entry->add("gotoSysStatus" => $gotoSysStatus)} - if(defined $ip) {$entry->add("ipHostNumber" => $ip) } - #if(defined $interface) { } - if(defined $desc) {$entry->add("description" => $desc) } - - # submit entry to LDAP - my $result = $entry->update ($ldap_tree); - - # for $result->code constants please look at Net::LDAP::Constant - my $log_time = localtime( time ); - if($result->code == 68) { # entry already exists - daemon_log("WARNING: $log_time: $dn ".$result->error, 3); - } elsif($result->code == 0) { # everything went fine - daemon_log("$log_time: add entry $dn to ldap", 1); - } else { # if any other error occur - daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1); - } - return; -} - - -#=== FUNCTION ================================================================ -# NAME: change_ldap_entry -# PURPOSE: ???? -# PARAMETERS: ???? -# RETURNS: ???? -# DESCRIPTION: ???? -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub change_ldap_entry { - my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus ) = @_; - - # check if ldap_entry exists or not - my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))"); - my $c_res = $s_res->count; - if($c_res == 0) { - daemon_log("WARNING: macAddress $mac not in LDAP", 1); - return; - } elsif($c_res > 1) { - daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1); - return; - } - - my $s_res_entry = $s_res->pop_entry(); - my $dn = $s_res_entry->dn(); - my $result = $ldap->modify( $dn, replace => {'gotoSysStatus' => $gotoSysStatus } ); - - # for $result->code constants please look at Net::LDAP::Constant - my $log_time = localtime( time ); - if($result->code == 32) { # entry doesnt exists - &add_ldap_entry($mac, $gotoSysStatus); - } elsif($result->code == 0) { # everything went fine - daemon_log("$log_time: entry $dn changed successful", 1); - } else { # if any other error occur - daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1); - } - - return; -} - -#=== FUNCTION ================================================================ -# NAME: search_ldap_entry -# PURPOSE: ???? -# PARAMETERS: [Net::LDAP] $ldap_tree - object of an ldap-tree -# string $sub_tree - dn of the subtree the search is performed -# string $search_string - either a string or a Net::LDAP::Filter object -# RETURNS: [Net::LDAP::Search] $msg - result object of the performed search -# DESCRIPTION: ???? -# THROWS: no exceptions -# COMMENTS: none -# SEE ALSO: n/a -#=============================================================================== -sub search_ldap_entry { - my ($ldap_tree, $sub_tree, $search_string) = @_; - my $msg = $ldap_tree->search( # perform a search - base => $sub_tree, - filter => $search_string, - ) or daemon_log("cannot perform search at ldap: $@", 1); -# if(defined $msg) { -# print $sub_tree."\t".$search_string."\t"; -# print $msg->count."\n"; -# foreach my $entry ($msg->entries) { $entry->dump; }; -# } - - return $msg; -} - - - -#========= MAIN = main ======================================================== -daemon_log( "####### START DAEMON ######\n", 1 ); -#&check_cmdline_param ; -&check_pid; -&open_fifo($fifo_path); - -# Just fork, if we"re not in foreground mode -if( ! $foreground ) { $pid = fork(); } -else { $pid = $$; } - -# Do something useful - put our PID into the pid_file -if( 0 != $pid ) { - open( LOCK_FILE, ">$pid_file" ); - print LOCK_FILE "$pid\n"; - close( LOCK_FILE ); - if( !$foreground ) { exit( 0 ) }; -} - - -if( not -p $fifo_path ) { die "fifo file disappeared\n" } -sysopen(FIFO, $fifo_path, O_RDONLY) or die "can't read from $fifo_path: $!" ; - -while( 1 ) { - # checke alle prozesse im hash daemon_children ob sie noch aktiv sind, wenn - # nicht, dann entferne prozess aus hash - while( (my $key, my $val) = each( %daemon_children) ) { - my $status = waitpid( $key, &WNOHANG) ; - if( $status == -1 ) { - delete $daemon_children{$key} ; - daemon_log("childprocess finished: $key", 3) ; - } - } - - # ist die max_process anzahl von prozesskindern erreicht, dann warte und - # prüfe erneut, ob in der zwischenzeit prozesse fertig geworden sind - if( keys( %daemon_children ) >= $max_process ) { - sleep($max_process_timeout) ; - next ; - } - - my $msg = ; - if( not defined( $msg )) { next ; } - - chomp( $msg ); - if( length( $msg ) == 0 ) { next ; } - - my $forked_pid = fork(); -#=== PARENT = parent ========================================================== - if ( $forked_pid != 0 ) { - daemon_log("childprocess forked: $forked_pid", 3) ; - $daemon_children{$forked_pid} = 0 ; - } -#=== CHILD = child ============================================================ - else { - # parse the incoming message from arp, split the message and return - # the values in an array. not defined values are set to "none" - #my ($mac, $ip, $interface, $arp_sig, $desc) = &parse_input( $msg ) ; - daemon_log( "childprocess read from arp: $fifo_path\nline: $msg", 3); - my ($mac, $ip, $interface, $arp_sig, $desc) = split('\s', $msg, 5); - - # create connection to LDAP - $ldap = Net::LDAP->new( "localhost" ) or die "$@"; - $ldap->bind($bind_phrase, - password => $password, - ) ; - - switch($arp_sig) { - case 0 {&change_ldap_entry($ldap, $ldap_base, - $mac, "ip-changed", - )} - case 1 {&change_ldap_entry($ldap, $ldap_base, - $mac, "mac-not-whitelisted", - )} - case 2 {&change_ldap_entry($ldap, $ldap_base, - $mac, "mac-in-blacklist", - )} - case 3 {&add_ldap_entry($ldap, $ldap_base, - $mac, "new-mac-address", $ip, - $interface, $desc, - )} - case 4 {&change_ldap_entry($ldap, $ldap_base, - $mac, "unauthorized-arp-request", - )} - case 5 {&change_ldap_entry($ldap, $ldap_base, - $mac, "abusive-number-of-arp-requests", - )} - case 6 {&change_ldap_entry($ldap, $ldap_base, - $mac, "ether-and-arp-mac-differs", - )} - case 7 {&change_ldap_entry($ldap, $ldap_base, - $mac, "flood-detected", - )} - case 8 {&add_ldap_entry($ldap, $ldap_base, - $mac, $ip, "new-system", - )} - case 9 {&change_ldap_entry($ldap, $ldap_base, - $mac, "mac-changed", - )} - } - - - # ldap search -# my $base_phrase = "dc=gonicus,dc=de"; -# my $filter_phrase = "cn=keinesorge"; -# my $attrs_phrase = "cn macAdress"; -# my $msg_search = $ldap->search( base => $base_phrase, -# filter => $filter_phrase, -# attrs => $attrs_phrase, -# ); -# $msg_search->code && die $msg_search->error; -# -# my @entries = $msg_search->entries; -# my $max = $msg_search->count; -# print "anzahl der entries: $max\n"; -# my $i; -# for ( $i = 0 ; $i < $max ; $i++ ) { -# my $entry = $msg_search->entry ( $i ); -# foreach my $attr ( $entry->attributes ) { -# if( not $attr eq "cn") { -# next; -# } -# print join( "\n ", $attr, $entry->get_value( $attr ) ), "\n\n"; -# } -# } - - # ldap add - - - $ldap->unbind; - exit; - } - -} - - diff --git a/contrib/daemon/gosa-sd-bus b/contrib/daemon/gosa-sd-bus new file mode 100755 index 000000000..230002dd9 --- /dev/null +++ b/contrib/daemon/gosa-sd-bus @@ -0,0 +1,459 @@ +#!/usr/bin/perl +#=============================================================================== +# +# FILE: gosa-server +# +# USAGE: ./gosa-server +# +# DESCRIPTION: +# +# OPTIONS: --- +# REQUIREMENTS: --- +# BUGS: --- +# NOTES: +# AUTHOR: (Andreas Rettenberger), +# COMPANY: +# VERSION: 1.0 +# CREATED: 12.09.2007 08:54:41 CEST +# REVISION: --- +#=============================================================================== + +use strict; +use warnings; +use Getopt::Long; +use Config::IniFiles; +use POSIX; +use Time::HiRes qw( gettimeofday ); + +use IO::Socket::INET; +use Crypt::Rijndael; +use XML::Simple; +use Data::Dumper; +use Sys::Syslog qw( :DEFAULT setlogsock); + +my ($cfg_file, %cfg_defaults, $foreground); +my ($bus_passwd, $bus_ip, $bus_port, $bus); +my ($pid_file, $procid, $pid, $log_file); +my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout); + +$foreground = 0 ; +%cfg_defaults = +("general" => + {"log_file" => [\$log_file, "/var/run/gosa-server-bus.log"], + "pid_file" => [\$pid_file, "/var/run/gosa-server-bus.pid"], + + }, +"bus" => + {"bus_passwd" => [\$bus_passwd, "tester78901234567890123456789012"], + "bus_ip" => [\$bus_ip, "10.89.1.155"], + "bus_port" => [\$bus_port, "10001"], + "child_max" => [\$child_max, 10], + "child_min" => [\$child_min, 3], + "child_timeout" => [\$child_timeout, 180], + } + ); + +#=== FUNCTION ================================================================ +# NAME: read_configfile +# PARAMETERS: cfg_file - string - +# RETURNS: +# DESCRIPTION: +#=============================================================================== +sub read_configfile { + my $cfg; + if( defined( $cfg_file) && ( length($cfg_file) > 0 )) { + if( -r $cfg_file ) { + $cfg = Config::IniFiles->new( -file => $cfg_file ); + } else { + print STDERR "Couldn't read config file!"; + } + } else { + $cfg = Config::IniFiles->new() ; + } + foreach my $section (keys %cfg_defaults) { + foreach my $param (keys %{$cfg_defaults{ $section }}) { + my $pinfo = $cfg_defaults{ $section }{ $param }; + ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] ); + } + } +} + +#=== FUNCTION ================================================================ +# NAME: logging +# PARAMETERS: level - string - default 'info' +# msg - string - +# facility - string - default 'LOG_DAEMON' +# RETURNS: +# DESCRIPTION: +#=============================================================================== +sub daemon_log { + my( $msg, $level ) = @_; + if(not defined $msg) { return } + if(not defined $level) { $level = 1 } + if(defined $log_file){ + open(LOG_HANDLE, ">>$log_file"); + if(not defined open( LOG_HANDLE, ">>$log_file" )) { + print STDERR "cannot open $log_file: $!"; + return } + chomp($msg); + print LOG_HANDLE $msg."\n"; + if(defined $foreground) { print $msg."\n" } + } + close( LOG_HANDLE ); +# my ($msg, $level, $facility) = @_; +# if(not defined $msg) {return} +# if(not defined $level) {$level = "info"} +# if(not defined $facility) {$facility = "LOG_DAEMON"} +# openlog($0, "pid,cons,", $facility); +# syslog($level, $msg); +# closelog; +# return; +} + +#=== FUNCTION ================================================================ +# NAME: check_cmdline_param +# PARAMETERS: +# RETURNS: +# DESCRIPTION: +#=============================================================================== +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; + } + if( $err_counter > 0 ) { + &usage( "", 1 ); + if( defined( $err_config)) { print STDERR "$err_config\n"} + print STDERR "\n"; + exit( -1 ); + } +} + +#=== FUNCTION ================================================================ +# NAME: check_pid +# PARAMETERS: +# RETURNS: +# DESCRIPTION: +#=============================================================================== +sub check_pid { + $pid = -1; + # Check, if we are already running + if( open(LOCK_FILE, "<$pid_file") ) { + $pid = ; + if( defined $pid ) { + chomp( $pid ); + if( -f "/proc/$pid/stat" ) { + my($stat) = `cat /proc/$pid/stat` =~ m/$pid \((.+)\).*/; + if( "faimond" eq $stat ) { + close( LOCK_FILE ); + exit -1; + } + } + } + close( LOCK_FILE ); + unlink( $pid_file ); + } + # Try to open PID file + if (!sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) { + my($msg) = "Couldn't obtain lockfile '$pid_file' "; + + if (open(LOCK_FILE, '<', $pid_file) + && ($pid = )) + { + chomp($pid); + $msg .= "(PID $pid)\n"; + } else { + $msg .= "(unable to read PID)\n"; + } + if( ! ($foreground) ) { + openlog( "gosa-server-bus", "cons,pid", "daemon" ); + syslog( "warning", $msg ); + closelog(); + } + else { + print( STDERR " $msg " ); + } + exit( -1 ); + } +} + +#=== FUNCTION ================================================================ +# NAME: usage +# PARAMETERS: +# RETURNS: +# DESCRIPTION: +#=============================================================================== +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" ; +usage: $0 [-hvf] [-c config] + + -h : this (help) message + -c : config file + -v : be verbose (multiple to increase verbosity) +EOF + } + print "\n" ; +} + +sub sig_int_handler { + my ($signal) = @_; + if($bus){ + close($bus); + print "$bus closed\n"; + } + print "$signal\n"; + exit(1); +} +$SIG{INT} = \&sig_int_handler; + +#=== FUNCTION ================================================================ +# NAME: activating_child +# PARAMETERS: +# RETURNS: +# DESCRIPTION: +#=============================================================================== +sub activating_child { + my ($msg) = @_; + my $child = &get_processing_child(); + my $pipe_wr = $$child{'pipe_wr'}; + print "activating: childpid:$$child{'pid'}\n"; + #print "activating: pipe_wr:$pipe_wr\n"; + print $pipe_wr $msg."\n"; + #print "activating: done\n"; + return; + +} + + +#=== FUNCTION ================================================================ +# NAME: get_processing_child +# PARAMETERS: +# RETURNS: +# DESCRIPTION: +#=============================================================================== +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 + while(my ($key, $val) = each(%busy_child)) { + # test ob prozess noch existiert + my $exitus_pid = waitpid($key, WNOHANG); + if($exitus_pid != 0) { + delete $busy_child{$key}; + print "prozess:$key wurde aus busy_child entfernt\n"; + next; + } + + # test ob prozess noch arbeitet + my $fh = $$val{'pipe_rd'}; + $fh->blocking(0); + my $child_answer; + if(not $child_answer = <$fh>) { next } + chomp($child_answer); + if($child_answer eq "done") { + delete $busy_child{$key}; + $free_child{$key} = $val; + } + } + + while(my ($key, $val) = each(%free_child)) { + my $exitus_pid = waitpid($key, WNOHANG); + if($exitus_pid != 0) { + delete $free_child{$key}; + print "prozess:$key wurde aus free_child entfernt\n"; + } + print "free child:$key\n"; + } + + + # teste @free_child und @busy_child + my $free_len = scalar(keys(%free_child)); + my $busy_len = scalar(keys(%busy_child)); + print "free children $free_len, busy children $busy_len\n"; + + # gibt es bereits ein freies kind, dann lass es arbeiten + if($free_len > 0){ + my @keys = keys(%free_child); + $child = $free_child{$keys[0]}; + if(defined $child) { + $busy_child{$$child{'pid'}} = $child ; + delete $free_child{$$child{'pid'}}; + } + return $child; + } + + # no free child, try to fork another one + if($free_len + $busy_len < $child_max) { + + print "not enough children, create a new one\n"; + + # New pipes for communication + my( $PARENT_wr, $PARENT_rd ); + my( $CHILD_wr, $CHILD_rd ); + pipe( $CHILD_rd, $PARENT_wr ); + pipe( $PARENT_rd, $CHILD_wr ); + $PARENT_wr->autoflush(1); + $CHILD_wr->autoflush(1); + + ############ + # fork child + ############ + my $child_pid = fork(); + + #CHILD + if($child_pid == 0) { + # Close unused pipes + close( $CHILD_rd ); + close( $CHILD_wr ); + while( 1 ) { + my $rbits = ""; + 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) { + # seit timeout ist nichts mehr passiert, + print "timeout!!\n"; + + # ist dieses kind nicht eines der letzenen $child_min, dann springe aus while schleife raus + $free_len = scalar(keys(%free_child)); + $busy_len = scalar(keys(%busy_child)); + if($free_len + $busy_len >= $child_min) { + last; + } else { + redo; + } + } + + # ansonsten + if ( vec $rbits, fileno $PARENT_rd, 1 ) { + my $msg = <$PARENT_rd>; + &process_incoming_msg($msg); + + # schreibe an den parent_wr zurück 'done' + print $PARENT_wr "done"."\n"; + + redo; + } + } + # child die die while-schleife verlassen haben, "stirbt!" + exit(0); + + #PARENT + } else { + # Close unused pipes + close( $PARENT_rd ); + close( $PARENT_wr ); + + # add child to child alive hash + my %child_hash = ( + 'pid' => $child_pid, + 'pipe_wr' => $CHILD_wr, + 'pipe_rd' => $CHILD_rd, + ); + + $child = \%child_hash; + $busy_child{$$child{'pid'}} = $child; + return $child; + } + } +} + + +#=== FUNCTION ================================================================ +# NAME: process_incoming_msg +# PARAMETERS: +# RETURNS: +# DESCRIPTION: +#=============================================================================== +sub process_incoming_msg { + my ($msg) = @_; + print "msg to process:$msg\n"; + sleep(10); + return; +} + +#==== MAIN = main ============================================================== + +# parse commandline options +Getopt::Long::Configure( "bundling" ); +GetOptions("h|help" => \&usage, + "c|config=s" => \$cfg_file, + "f|foreground" => \$foreground, + ); + +# read and set config parameters +&read_configfile; +&check_cmdline_param ; +&check_pid; + +$SIG{CHLD} = 'IGNORE'; + +# restart daemon log file +if(-e $log_file ) { unlink $log_file } +daemon_log("started!"); + +# Just fork, if we"re not in foreground mode +if( ! $foreground ) { $pid = fork(); } +else { $pid = $$; } + +# Do something useful - put our PID into the pid_file +if( 0 != $pid ) { + open( LOCK_FILE, ">$pid_file" ); + print LOCK_FILE "$pid\n"; + close( LOCK_FILE ); + if( !$foreground ) { exit( 0 ) }; +} + +# open the bus socket +$bus = IO::Socket::INET->new(LocalPort => $bus_port, + Type => SOCK_STREAM, + Reuse => 1, + Listen => 20, + ) or die "kann kein TCP-Server an Port $bus_port sein: $@\n"; + +# waiting for incoming msg +my $client; +while($client = $bus->accept()){ + my $other_end = getpeername($client) + or die "Gegenstelle konnte nicht identifiziert werden: $!\n"; + my ($port, $iaddr) = unpack_sockaddr_in($other_end); + my $actual_ip = inet_ntoa($iaddr); + my $claimed_hostname = gethostbyaddr($iaddr, AF_INET); + daemon_log("accept client from $actual_ip\n"); + + my $in_msg; + chomp( $in_msg = <$client> ); + + &activating_child($in_msg); + close($client); +} + + + +#Struktur Parent: +# syslog(Parent gestartet) + +# forken von min_child kindern +# liste mit child refs +# +# aufbau des sockets +# warten auf eingang +# kinder die älter als child_timeout sind werden beendet, aber nicht mehr als child_min +# wenn eingang da, abfrage, ist ein kind frei? +# kind frei: kind nimmt eingang entgegen und arbeitet ihn ab +# kind nicht frei: existieren bereits max_child kinder? +# max ereicht: tue nichts, warte bis ein kind fertig ist +# max nicht erreicht: forke neues kind + + + + + + diff --git a/contrib/daemon/gosa-sd-bus.cfg b/contrib/daemon/gosa-sd-bus.cfg new file mode 100644 index 000000000..8294e6e91 --- /dev/null +++ b/contrib/daemon/gosa-sd-bus.cfg @@ -0,0 +1,10 @@ +[general] +log_file = /var/log/gosa-server-bus.log +pid_file = /var/run/gosa-server-bus.pid +[bus] +buspasswd = tester78901234567890123456789012 +bus_ip = 10.89.1.155 +bus_port = 10001 +child_max = 10 +child_min = 2 +child_timeout = 10