Code

update
authorrettenbe <rettenbe@594d385d-05f5-0310-b6e9-bd551577e9d8>
Wed, 5 Dec 2007 11:13:02 +0000 (11:13 +0000)
committerrettenbe <rettenbe@594d385d-05f5-0310-b6e9-bd551577e9d8>
Wed, 5 Dec 2007 11:13:02 +0000 (11:13 +0000)
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@8011 594d385d-05f5-0310-b6e9-bd551577e9d8

contrib/daemon/modules/GosaPackages.pm [new file with mode: 0644]
contrib/daemon/modules/ServerPackages.pm [new file with mode: 0644]

diff --git a/contrib/daemon/modules/GosaPackages.pm b/contrib/daemon/modules/GosaPackages.pm
new file mode 100644 (file)
index 0000000..3f03d45
--- /dev/null
@@ -0,0 +1,106 @@
+package GosaPackages;
+
+use Exporter;
+@ISA = ("Exporter");
+
+# Each module has to have a function 'process_incoming_msg'. This function works as a interface to gosa-sd and recieves the msg hash from gosa-sd. 'process_incoming_function checks, wether it has a function to process the incoming msg and forward the msg to it. 
+
+
+use strict;
+use warnings;
+
+
+BEGIN{
+    # prepare module for working
+    # print "Module Gosa started!\n";
+
+}
+
+END{}
+
+
+### START ##########################
+
+# create general settings for this module
+my $gosa_cipher = &main::create_ciphering($main::gosa_passwd);
+
+
+sub get_module_tags {
+    
+    # dort stehen drei packettypen, für die sich das modul anmelden kann, gosa-admin-packages, server-packages, client-packages
+    my %tag_hash = (gosa_admin_packages => "yes", 
+                    server_packages => "no", 
+                    client_packages => "no");
+    return \%tag_hash;
+}
+
+#sub read_configfile {
+#    &main::read_configfile();
+#    return;
+#}
+
+
+sub process_incoming_msg {
+    my ($crypted_msg) = @_ ;
+    if(not defined $crypted_msg) {
+        &main::daemon_log("function 'process_incoming_msg': got no msg", 7);
+    }
+    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
+    $crypted_msg = $1;
+    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
+    
+    # collect addresses from possible incoming clients
+    # only gosa is allowd as incoming client
+    &main::daemon_log("GosaPackages: host_key: $host", 7);
+    &main::daemon_log("GosaPackages: key_passwd: $main::gosa_passwd", 7);
+
+    # determine the correct passwd for deciphering of the incoming msgs
+    my $msg = "";
+    my $msg_hash;
+    eval{
+        $msg = &main::decrypt_msg($crypted_msg, $gosa_cipher);
+        $msg_hash = $main::xml->XMLin($msg, ForceArray=>1);
+    };
+    if($@) {
+        &main::daemon_log("ERROR: GosaPackages do not understand the message:", 1);
+        &main::daemon_log("\t$msg", 7);
+        return;
+    }
+
+    &main::daemon_log("GosaPackages: msg for daemon from host:", 1);
+    &main::daemon_log("\t$host", 1);
+    &main::daemon_log("GosaPackages: msg to process:", 5);
+    &main::daemon_log("\t$msg", 5);
+
+
+
+
+    return "GosaPackages got msg: $msg";
+
+}
+
+
+#===  FUNCTION  ================================================================
+#         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) = @_;
+    
+    my $source = @{$msg_hash->{source}}[0];
+    my $target = @{$msg_hash->{target}}[0];
+    my $header = @{$msg_hash->{header}}[0];
+    
+    if(exists $main::known_daemons->{$source}) {
+        &main::add_content2known_daemons(hostname=>$source, status=>$header);
+    } else {
+        &main::add_content2known_clients(hostname=>$source, status=>$header);
+    }
+    
+    return;
+}
+
+
+1;
diff --git a/contrib/daemon/modules/ServerPackages.pm b/contrib/daemon/modules/ServerPackages.pm
new file mode 100644 (file)
index 0000000..cb0c625
--- /dev/null
@@ -0,0 +1,478 @@
+package ServerPackages;
+
+use Exporter;
+@ISA = ("Exporter");
+
+# Each module has to have a function 'process_incoming_msg'. This function works as a interface to gosa-sd and recieves the msg hash from gosa-sd. 'process_incoming_function checks, wether it has a function to process the incoming msg and forward the msg to it. 
+
+
+use strict;
+use warnings;
+
+
+BEGIN{
+    # prepare module for working
+    #print "ServerPackages loaded!\n";
+    
+}
+
+
+
+END {}
+
+
+### START ##########
+
+
+sub get_module_tags {
+    
+    # lese config file aus dort gibt es eine section Basic
+    # dort stehen drei packettypen, für die sich das modul anmelden kann, gosa-admin-packages, server-packages, client-packages
+    my %tag_hash = (gosa_admin_packages => "yes", 
+                    server_packages => "yes", 
+                    client_packages => "yes",
+                    );
+    return \%tag_hash;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  read_configfile
+#   PARAMETERS:  cfg_file - string -
+#      RETURNS:  nothing
+#  DESCRIPTION:  read cfg_file and set variables
+#===============================================================================
+#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 ] );
+#        }
+#    }
+#}
+
+
+sub process_incoming_msg {
+    my ($crypted_msg) = @_ ;
+    if(not defined $crypted_msg) {
+        &main::daemon_log("function 'process_incoming_msg': got no msg", 7);
+    }
+    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
+    $crypted_msg = $1;
+    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
+
+    # collect addresses from possible incoming clients
+    my @valid_keys;
+    my @host_keys = keys %$main::known_daemons;
+    foreach my $host_key (@host_keys) {    
+        if($host_key =~ "^$host") {
+            push(@valid_keys, $host_key);
+        }
+    }
+    my @client_keys = keys %$main::known_clients;
+    foreach my $client_key (@client_keys) {
+        if($client_key =~ "^$host"){
+            push(@valid_keys, $client_key);
+        }
+    }
+    push(@valid_keys, $main::server_address);
+    
+    my $l = @valid_keys;
+    my $msg_hash;
+    my $msg_flag = 0;    
+    my $msg = "";
+
+    # determine the correct passwd for deciphering of the incoming msgs
+    foreach my $host_key (@valid_keys) {
+        eval{
+            &main::daemon_log("ServerPackage: host_key: $host_key", 7);
+            my $key_passwd;
+            if (exists $main::known_daemons->{$host_key}) {
+                $key_passwd = $main::known_daemons->{$host_key}->{passwd};
+            } elsif (exists $main::known_clients->{$host_key}) {
+                $key_passwd = $main::known_clients->{$host_key}->{passwd};
+            } elsif ($host_key eq $main::server_address) {
+                $key_passwd = $main::server_passwd;
+            } 
+            &main::daemon_log("ServerPackage: key_passwd: $key_passwd", 7);
+            my $key_cipher = &main::create_ciphering($key_passwd);
+            $msg = &main::decrypt_msg($crypted_msg, $key_cipher);
+            $msg_hash = $main::xml->XMLin($msg, ForceArray=>1);
+        };
+        if($@) {
+            &main::daemon_log("ServerPackage: key raise error: $@", 7);
+            $msg_flag += 1;
+        } else {
+            last;
+        }
+    } 
+    
+    if($msg_flag >= $l)  {
+        &main::daemon_log("ERROR: ServerPackage do not understand the message:", 1);
+        &main::daemon_log("\t$msg", 7);
+        return;
+    }
+
+    # process incoming msg
+    my $header = @{$msg_hash->{header}}[0]; 
+    my $source = @{$msg_hash->{source}}[0];
+
+    &main::daemon_log("ServerPackages: msg from host:", 1);
+    &main::daemon_log("\t$host", 1);
+    &main::daemon_log("ServerPackages: header from msg:", 1);
+    &main::daemon_log("\t$header", 1);
+    &main::daemon_log("ServerPackages: msg to process:", 5);
+    &main::daemon_log("\t$msg", 5);
+
+    my @targets = @{$msg_hash->{target}};
+    my $len_targets = @targets;
+    if ($len_targets == 0){     
+        &main::daemon_log("ERROR: ServerPackages: no target specified for msg $header", 1);
+
+    }  elsif ($len_targets == 1){
+        # we have only one target symbol
+
+        my $target = $targets[0];
+        &main::daemon_log("SeverPackages: msg is for:", 7);
+        &main::daemon_log("\t$target", 7);
+
+        if ($target eq $main::server_address) {
+            # msg is for server
+            if ($header eq 'new_passwd'){ &new_passwd($msg_hash)}
+            elsif ($header eq 'here_i_am') { &here_i_am($msg_hash)}
+            elsif ($header eq 'who_has') { &who_has($msg_hash) }
+            elsif ($header eq 'who_has_i_do') { &who_has_i_do($msg_hash)}
+            elsif ($header eq 'update_status') { &update_status($msg_hash) }
+            elsif ($header eq 'got_ping') { &got_ping($msg_hash)}
+            elsif ($header eq 'get_load') { &execute_actions($msg_hash)}
+            else { &main::daemon_log("ERROR: ServerPackages: no function assigned to this msg", 5) }
+
+        
+       } elsif ($target eq "*") {
+            # msg is for all clients
+
+            my @target_addresses = keys(%$main::known_clients);
+            foreach my $target_address (@target_addresses) {
+                if ($target_address eq $source) { next; }
+                $msg_hash->{target} = [$target_address];
+                &send_msg_hash2address($msg_hash, $target_address);
+            }           
+        } else {
+            # msg is for one client
+
+            if (exists $main::known_clients->{$target}) {
+                # target is known
+
+                &send_msg_hash2address($msg_hash, $target);
+            } else {
+                # target is not known
+
+                &main::daemon_log("ERROR: ServerPackages. target $target is not known in known_clients", 1);
+            }
+        }
+    }
+
+    return ;
+}
+
+
+#===  FUNCTION  ================================================================
+#         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) = @_;
+    
+    my $source = @{$msg_hash->{source}}[0];
+    my $target = @{$msg_hash->{target}}[0];
+    my $header = @{$msg_hash->{header}}[0];
+    
+    if(exists $main::known_daemons->{$source}) {
+        &main::add_content2known_daemons(hostname=>$source, status=>$header);
+    } else {
+        &main::add_content2known_clients(hostname=>$source, status=>$header);
+    }
+    
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  new_passwd
+#   PARAMETERS:  msg_hash - ref - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub new_passwd {
+    my ($msg_hash) = @_;
+
+    my $source = @{$msg_hash->{source}}[0];
+    my $passwd = @{$msg_hash->{new_passwd}}[0];
+
+    if (exists $main::known_daemons->{$source}) {
+        &main::add_content2known_daemons(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
+        my $hash = &main::create_xml_hash("confirm_new_passwd", $main::server_address, $source);
+        &main::send_msg_hash2address($hash, $source);
+
+    } elsif (exists $main::known_clients->{$source}) {
+        &main::add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
+
+    } else {
+        &main::daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1)   
+    }
+
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  here_i_am
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub here_i_am {
+    my ($msg_hash) = @_;
+
+    my $source = @{$msg_hash->{source}}[0];
+    my $mac_address = @{$msg_hash->{mac_address}}[0];
+    my $out_hash;
+
+    # number of known clients
+    my $nu_clients = keys %$main::known_clients;
+
+    # check wether client address or mac address is already known
+    if (exists $main::known_clients->{$source}) {
+        &main::daemon_log("WARNING: $source is already known as a client", 1);
+        &main::daemon_log("WARNING: values for $source are being overwritten", 1);   
+        $nu_clients --;
+    }
+
+    # number of actual activ clients
+    my $act_nu_clients = $nu_clients;
+
+    &main::daemon_log("number of actual activ clients: $act_nu_clients", 5);
+    &main::daemon_log("number of maximal allowed clients: $main::max_clients", 5);
+
+    if($main::max_clients <= $act_nu_clients) {
+        my $out_hash = &main::create_xml_hash("denied", $main::server_address, $source);
+        &main::add_content2xml_hash($out_hash, "denied", "I_cannot_take_any_more_clients!");
+        my $passwd = @{$msg_hash->{new_passwd}}[0]; 
+        &main::send_msg_hash2address($out_hash, $source, $passwd);
+        return;
+    }
+    
+    # new client accepted
+    my $new_passwd = @{$msg_hash->{new_passwd}}[0];
+
+    # create known_daemons entry
+    my $events = @{$msg_hash->{events}}[0];
+    &main::create_known_client($source);
+    &main::add_content2known_clients(hostname=>$source, events=>$events, mac_address=>$mac_address, 
+                                status=>"registered", passwd=>$new_passwd);
+
+    # return acknowledgement to client
+    $out_hash = &main::create_xml_hash("registered", $main::server_address, $source);
+    &main::send_msg_hash2address($out_hash, $source);
+
+    # notify registered client to bus
+    $out_hash = &main::create_xml_hash("new_client", $main::server_address, $main::bus_address, $source);
+    &main::send_msg_hash2bus($out_hash);
+
+    # give the new client his ldap config
+    &new_ldap_config($source);
+
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  who_has
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing 
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub who_has {
+    my ($msg_hash) = @_ ;
+    
+    # what is your search pattern
+    my $search_pattern = @{$msg_hash->{who_has}}[0];
+    my $search_element = @{$msg_hash->{$search_pattern}}[0];
+    &main::daemon_log("who_has-msg looking for $search_pattern $search_element", 7);
+
+    # scanning known_clients for search_pattern
+    my @host_addresses = keys %$main::known_clients;
+    my $known_clients_entries = length @host_addresses;
+    my $host_address;
+    foreach my $host (@host_addresses) {
+        my $client_element = $main::known_clients->{$host}->{$search_pattern};
+        if ($search_element eq $client_element) {
+            $host_address = $host;
+            last;
+        }
+    }
+        
+    # search was successful
+    if (defined $host_address) {
+        my $source = @{$msg_hash->{source}}[0];
+        my $out_msg = &main::create_xml_hash("who_has_i_do", $main::server_address, $source, "mac_address");
+        &main::add_content2xml_hash($out_msg, "mac_address", $search_element);
+        &main::send_msg_hash2address($out_msg, $main::bus_address);
+    }
+    return;
+}
+
+
+sub who_has_i_do {
+    my ($msg_hash) = @_ ;
+    my $header = @{$msg_hash->{header}}[0];
+    my $source = @{$msg_hash->{source}}[0];
+    my $search_param = @{$msg_hash->{$header}}[0];
+    my $search_value = @{$msg_hash->{$search_param}}[0];
+    print "\ngot msg $header:\nserver $source has client with $search_param $search_value\n";
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  new_ldap_config
+#   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) = @_ ;
+    
+    if (not exists $main::known_clients->{$address}) {
+        &main::daemon_log("ERROR: $address does not exist in known_clients, cannot send him his ldap config", 1);
+        return;
+    }
+    
+    my $mac_address = $main::known_clients->{$address}->{"mac_address"};
+    if (not defined $mac_address) {
+        &main::daemon_log("ERROR: no mac address found for client $address", 1);
+        return;
+    }
+
+    # fetch dn
+    my $goHard_cmd = "ldapsearch -x '(&(objectClass=goHard)(macAddress=00:11:22:33:44:57))' dn gotoLdapServer";
+    my $dn;
+    my @gotoLdapServer;
+    open (PIPE, "$goHard_cmd 2>&1 |");
+    while(<PIPE>) {
+        chomp $_;
+        # If it's a comment, goto next
+        if ($_ =~ m/^[#]/) { next;}
+        if ($_ =~ m/^dn: ([\S]+?)$/) {
+            $dn = $1;
+        } elsif ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
+            push(@gotoLdapServer, $1);
+        }
+    }
+    close(PIPE);
+    
+    # no dn found
+    if (not defined $dn) {
+        &main::daemon_log("ERROR: no dn arose from command: $goHard_cmd", 1);
+        return;
+    }
+    
+    # no gotoLdapServer found
+    my $gosaGroupOfNames_cmd = "ldapsearch -x '(&(objectClass=gosaGroupOfNames)(member=$dn))' gotoLdapServer";
+    if (@gotoLdapServer == 0) {
+        open (PIPE, "$gosaGroupOfNames_cmd 2>&1 |");
+        while(<PIPE>) {
+            chomp $_;
+            if ($_ =~ m/^[#]/) { next; }
+            if ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
+                push(@gotoLdapServer, $1);
+            }
+        }
+        close(PIPE);
+    }
+
+    # still no gotoLdapServer found
+    if (@gotoLdapServer == 0) {
+        &main::daemon_log("ERROR: cannot find gotoLdapServer entry in command: $gosaGroupOfNames_cmd", 1);
+        return;
+    }
+
+    # sort @gotoLdapServer and then split of ranking
+    my @sorted_gotoLdapServer = sort(@gotoLdapServer);
+    @gotoLdapServer = reverse(@sorted_gotoLdapServer);
+    foreach (@gotoLdapServer) {
+        $_ =~ s/^\d://;
+    }
+
+    my $t = join(" ", @gotoLdapServer);
+    my $out_hash = &main::create_xml_hash("new_ldap_config", $main::server_address, $address);
+    map(&main::add_content2xml_hash($out_hash, "new_ldap_config", $_), @gotoLdapServer);
+    &main::send_msg_hash2address($out_hash, $address);
+
+    return;
+}
+
+
+#===  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/';
+    my $result;
+
+    my $header = @{$msg_hash->{header}}[0];
+    my $source = @{$msg_hash->{source}}[0];
+    my $target = @{$msg_hash->{target}}[0];
+    if((not defined $source)
+            && (not defined $target)
+            && (not defined $header)) {
+        &main::daemon_log("ERROR: Entries missing in XML msg for gosad actions under /etc/gosad/actions");
+    } else {
+        my $parameters="";
+        my @params = @{$msg_hash->{$header}};
+        my $params = join(", ", @params);
+        &main::daemon_log("execute_actions: got parameters: $params", 5);
+
+        if (@params) {
+            foreach my $param (@params) {
+                my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0];
+                &main::daemon_log("execute_actions: parameter -> value: $param -> $param_value", 7);
+                $parameters.= " ".$param_value;
+            }
+        }
+
+        my $cmd= $configdir.$header."$parameters";
+        &main::daemon_log("execute_actions: executing cmd: $cmd", 7);
+        $result= "";
+        open(PIPE, "$cmd 2>&1 |");
+        while(<PIPE>) {
+            $result.=$_;
+        }
+        close(PIPE);
+    }
+
+    # process the event result
+
+
+    return;
+}
+
+1;