Code

bugfix: catch ldap error
[gosa.git] / gosa-si / modules / ServerPackages.pm
1 package ServerPackages;
3 use Exporter;
4 @ISA = ("Exporter");
6 # 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. 
9 use strict;
10 use warnings;
11 use GOSA::GosaSupportDaemon;
12 use IO::Socket::INET;
13 use XML::Simple;
14 use Data::Dumper;
15 use Net::LDAP;
17 BEGIN{}
18 END {}
20 my ($known_clients_file_name);
21 my ($server_activ, $server_port, $server_passwd, $max_clients, $ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password);
22 my ($bus_activ, $bus_passwd, $bus_ip, $bus_port);
23 my $server;
24 my $no_bus;
25 my (@ldap_cfg, @pam_cfg, @nss_cfg, $goto_admin, $goto_secret);
28 my %cfg_defaults =
29 ("general" =>
30     {"known_clients_file_name" => [\$known_clients_file_name, '/var/lib/gosa-si/known_clients.db' ],
31     },
32 "server" =>
33     {"server_activ" => [\$server_activ, "on"],
34     "server_port" => [\$server_port, "20081"],
35     "server_passwd" => [\$server_passwd, ""],
36     "max_clients" => [\$max_clients, 100],
37     "ldap_uri" => [\$ldap_uri, ""],
38     "ldap_base" => [\$ldap_base, ""],
39     "ldap_admin_dn" => [\$ldap_admin_dn, ""],
40     "ldap_admin_password" => [\$ldap_admin_password, ""],
41     },
42 "bus" =>
43     {"bus_activ" => [\$bus_activ, "on"],
44     "bus_passwd" => [\$bus_passwd, ""],
45     "bus_ip" => [\$bus_ip, ""],
46     "bus_port" => [\$bus_port, "20080"],
47     },
48 );
50 ### START #####################################################################
53 # read configfile and import variables
54 &read_configfile();
56 # detect own ip and mac address
57 my ($server_ip, $server_mac_address) = &get_ip_and_mac(); 
58 if (not defined $server_ip) {
59     die "EXIT: ip address of $0 could not be detected";
60 }
61 &main::daemon_log("server ip address detected: $server_ip", 1);
62 &main::daemon_log("server mac address detected: $server_mac_address", 1);
64 # complete addresses
65 my $server_address = "$server_ip:$server_port";
66 my $bus_address = "$bus_ip:$bus_port";
68 # create general settings for this module
69 my $xml = new XML::Simple();
71 # open server socket
72 if($server_activ eq "on"){
73     &main::daemon_log(" ", 1);
74     $server = IO::Socket::INET->new(LocalPort => $server_port,
75             Type => SOCK_STREAM,
76             Reuse => 1,
77             Listen => 20,
78             ); 
79     if(not defined $server){
80         &main::daemon_log("cannot be a tcp server at $server_port : $@");
81     } else {
82         &main::daemon_log("start server: $server_address", 1);
83     }
84 }
86 # connect to known_clients_db
87 #my $known_clients_db = GOSA::DBsqlite->new($known_clients_file_name);
90 # register at bus
91 if ($main::no_bus > 0) {
92     $bus_activ = "off"
93 }
94 if($bus_activ eq "on") {
95     &main::daemon_log(" ", 1);
96     &register_at_bus();
97 }
99 ### functions #################################################################
101 #sub get_module_tags {
102 #    
103 #    # lese config file aus dort gibt es eine section Basic
104 #    # dort stehen drei packettypen, für die sich das modul anmelden kann, gosa-admin-packages, 
105 #    #   server-packages, client-packages
106 #    my %tag_hash = (gosa_admin_packages => "yes", 
107 #                    server_packages => "yes", 
108 #                    client_packages => "yes",
109 #                    );
110 #    return \%tag_hash;
111 #}
114 sub get_module_info {
115     my @info = ($server_address,
116                 $server_passwd,
117                 $server,
118                 $server_activ,
119                 "socket",
120                 );
121     return \@info;
125 #===  FUNCTION  ================================================================
126 #         NAME:  read_configfile
127 #   PARAMETERS:  cfg_file - string -
128 #      RETURNS:  nothing
129 #  DESCRIPTION:  read cfg_file and set variables
130 #===============================================================================
131 sub read_configfile {
132     my $cfg;
133     if( defined( $main::cfg_file) && ( length($main::cfg_file) > 0 )) {
134         if( -r $main::cfg_file ) {
135             $cfg = Config::IniFiles->new( -file => $main::cfg_file );
136         } else {
137             print STDERR "Couldn't read config file!";
138         }
139     } else {
140         $cfg = Config::IniFiles->new() ;
141     }
142     foreach my $section (keys %cfg_defaults) {
143         foreach my $param (keys %{$cfg_defaults{ $section }}) {
144             my $pinfo = $cfg_defaults{ $section }{ $param };
145             ${@$pinfo[0]} = $cfg->val( $section, $param, @$pinfo[1] );
146         }
147     }
149     # Read non predefined sections
150     my $param;
151     if ($cfg->SectionExists('ldap')){
152                 foreach $param ($cfg->Parameters('ldap')){
153                         push (@ldap_cfg, "$param ".$cfg->val('ldap', $param));
154                 }
155     }
156     if ($cfg->SectionExists('pam_ldap')){
157                 foreach $param ($cfg->Parameters('pam_ldap')){
158                         push (@pam_cfg, "$param ".$cfg->val('pam_ldap', $param));
159                 }
160     }
161     if ($cfg->SectionExists('nss_ldap')){
162                 foreach $param ($cfg->Parameters('nss_ldap')){
163                         push (@nss_cfg, "$param ".$cfg->val('nss_ldap', $param));
164                 }
165     }
166     if ($cfg->SectionExists('goto')){
167         $goto_admin= $cfg->val('goto', 'terminal_admin');
168         $goto_secret= $cfg->val('goto', 'terminal_secret');
169     } else {
170         $goto_admin= undef;
171         $goto_secret= undef;
172     }
177 #===  FUNCTION  ================================================================
178 #         NAME:  get_ip_and_mac 
179 #   PARAMETERS:  nothing
180 #      RETURNS:  (ip, mac) 
181 #  DESCRIPTION:  executes /sbin/ifconfig and parses the output, the first occurence 
182 #                of a inet address is returned as well as the mac address in the line
183 #                above the inet address
184 #===============================================================================
185 sub get_ip_and_mac {
186     my $ip = "0.0.0.0.0"; # Defualt-IP
187     my $mac = "00:00:00:00:00:00";  # Default-MAC
188     my @ifconfig = qx(/sbin/ifconfig);
189     foreach(@ifconfig) {
190         if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
191             $mac = "$1:$2:$3:$4:$5:$6";
192             next;
193         }
194         if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
195             $ip = "$1.$2.$3.$4";
196             last;
197         }
198     }
199     return ($ip, $mac);
203 #===  FUNCTION  ================================================================
204 #         NAME:  open_socket
205 #   PARAMETERS:  PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000
206 #                [PeerPort] string necessary if port not appended by PeerAddr
207 #      RETURNS:  socket IO::Socket::INET
208 #  DESCRIPTION:  open a socket to PeerAddr
209 #===============================================================================
210 sub open_socket {
211     my ($PeerAddr, $PeerPort) = @_ ;
212     if(defined($PeerPort)){
213         $PeerAddr = $PeerAddr.":".$PeerPort;
214     }
215     my $socket;
216     $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
217             Porto => "tcp" ,
218             Type => SOCK_STREAM,
219             Timeout => 5,
220             );
221     if(not defined $socket) {
222         return;
223     }
224     &main::daemon_log("open_socket to: $PeerAddr", 7);
225     return $socket;
228 #===  FUNCTION  ================================================================
229 #         NAME:  register_at_bus
230 #   PARAMETERS:  nothing
231 #      RETURNS:  nothing
232 #  DESCRIPTION:  creates an entry in known_daemons and send a 'here_i_am' msg to bus
233 #===============================================================================
234 sub register_at_bus {
236     # create known_daemons entry
237     &main::create_known_daemon($bus_address);
238     &main::add_content2known_daemons(hostname=>$bus_address, status=>"register_at_bus", passwd=>$bus_passwd);
240     my $msg_hash = &create_xml_hash("here_i_am", $server_address, $bus_address);
241     my $answer = "";
242     $answer = &send_msg_hash2address($msg_hash, $bus_address);
243     if ($answer == 0) {
244         &main::daemon_log("register at bus: $bus_address", 1);
245     } else {
246         &main::daemon_log("unable to send 'register'-msg to bus: $bus_address", 1);
247     }
248     return;
251 #===  FUNCTION  ================================================================
252 #         NAME:  process_incoming_msg
253 #   PARAMETERS:  crypted_msg - string - incoming crypted message
254 #      RETURNS:  nothing
255 #  DESCRIPTION:  handels the proceeded distribution to the appropriated functions
256 #===============================================================================
257 sub process_incoming_msg {
258     my ($crypted_msg) = @_ ;
259     if(not defined $crypted_msg) {
260         &main::daemon_log("function 'process_incoming_msg': got no msg", 7);
261     }
263     &main::daemon_log("ServerPackages: incoming msg: \n$crypted_msg", 7);
265     $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
266     $crypted_msg = $1;
267     my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
269     # collect addresses from possible incoming clients
270     my @valid_keys;
271     my @host_keys = keys %$main::known_daemons;
272     foreach my $host_key (@host_keys) {    
273         if($host_key =~ "^$host") {
274             push(@valid_keys, $host_key);
275         }
276     }
277     my @client_keys = keys %$main::known_clients;
278     foreach my $client_key (@client_keys) {
279         if($client_key =~ "^$host"){
280             push(@valid_keys, $client_key);
281         }
282     }
283     push(@valid_keys, $server_address);
284     
285     my $l = @valid_keys;
286     my $msg_hash;
287     my $msg_flag = 0;    
288     my $msg = "";
290     # determine the correct passwd for deciphering of the incoming msgs
291     foreach my $host_key (@valid_keys) {
292         eval{
293             &main::daemon_log("ServerPackage: host_key: $host_key", 7);
294             my $key_passwd;
295             if (exists $main::known_daemons->{$host_key}) {
296                 $key_passwd = $main::known_daemons->{$host_key}->{passwd};
297             } elsif (exists $main::known_clients->{$host_key}) {
298                 $key_passwd = $main::known_clients->{$host_key}->{passwd};
299             } elsif ($host_key eq $server_address) {
300                 $key_passwd = $server_passwd;
301             } 
302             &main::daemon_log("ServerPackage: key_passwd: $key_passwd", 7);
303             my $key_cipher = &create_ciphering($key_passwd);
304             $msg = &decrypt_msg($crypted_msg, $key_cipher);
305             &main::daemon_log("ServerPackages: decrypted msg: \n$msg", 7);
306             $msg_hash = $xml->XMLin($msg, ForceArray=>1);
307             #my $tmp = printf Dumper $msg_hash;
308             #&main::daemon_log("DEBUG: ServerPackages: xml hash: $tmp", 7);
309         };
310         if($@) {
311             &main::daemon_log("ServerPackage: key raise error: $@", 7);
312             $msg_flag += 1;
313         } else {
314             last;
315         }
316     } 
317     
318     if($msg_flag >= $l)  {
319         &main::daemon_log("WARNING: ServerPackage do not understand the message:", 5);
320         &main::daemon_log("$@", 7);
321         return;
322     }
324     # process incoming msg
325     my $header = @{$msg_hash->{header}}[0]; 
326     my $source = @{$msg_hash->{source}}[0];
328     &main::daemon_log("recieve '$header' at ServerPackages from $host", 1);
329     &main::daemon_log("ServerPackages: msg to process: \n$msg", 5);
331     my @targets = @{$msg_hash->{target}};
332     my $len_targets = @targets;
333     if ($len_targets == 0){     
334         &main::daemon_log("ERROR: ServerPackages: no target specified for msg $header", 1);
336     }  elsif ($len_targets == 1){
337         # we have only one target symbol
339         my $target = $targets[0];
340         &main::daemon_log("SeverPackages: msg is for: $target", 7);
342         # msg is for server
343         if ($target eq $server_address) {
345             # msg is a event
347             # msg is a hard implemented function
348             if ($header eq 'new_passwd'){ &new_passwd($msg_hash)}
349             elsif ($header eq 'here_i_am') { &here_i_am($msg_hash)}
350             elsif ($header eq 'who_has') { &who_has($msg_hash) }
351             elsif ($header eq 'who_has_i_do') { &who_has_i_do($msg_hash)}
352             elsif ($header eq 'update_status') { &update_status($msg_hash) }
353             elsif ($header eq 'got_ping') { &got_ping($msg_hash)}
354             elsif ($header eq 'get_load') { &execute_actions($msg_hash)}
355             else { &main::daemon_log("ERROR: ServerPackages: no function assigned to this msg", 5) }
357         
358        # msg is for all clients
359        } elsif ($target eq "*") {
360             my @target_addresses = keys(%$main::known_clients);
361             foreach my $target_address (@target_addresses) {
362                 if ($target_address eq $source) { next; }
363                 $msg_hash->{target} = [$target_address];
364                 &send_msg_hash2address($msg_hash, $target_address);
365             } 
366           
367         # msg is for one host
368         } else {
369             if (exists $main::known_clients->{$target}) {
370                 &send_msg_hash2address($msg_hash, $target);
371             } elsif (exists $main::known_daemons->{$target}) {
372                 # target is known
373                 &send_msg_hash2address($msg_hash, $target);
374             } else {
375                 # target is not known
376                 &main::daemon_log("ERROR: ServerPackages: target $target is not known neither in known_clients nor in known_daemons", 1);
377             }
378         }
379     }
381     return ;
385 #===  FUNCTION  ================================================================
386 #         NAME:  got_ping
387 #   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
388 #      RETURNS:  nothing
389 #  DESCRIPTION:  process this incoming message
390 #===============================================================================
391 sub got_ping {
392     my ($msg_hash) = @_;
393     
394     my $source = @{$msg_hash->{source}}[0];
395     my $target = @{$msg_hash->{target}}[0];
396     my $header = @{$msg_hash->{header}}[0];
397     
398     if(exists $main::known_daemons->{$source}) {
399         &main::add_content2known_daemons(hostname=>$source, status=>$header);
400     } else {
401         &main::add_content2known_clients(hostname=>$source, status=>$header);
402     }
403     
404     return;
408 #===  FUNCTION  ================================================================
409 #         NAME:  new_passwd
410 #   PARAMETERS:  msg_hash - ref - hash from function create_xml_hash
411 #      RETURNS:  nothing
412 #  DESCRIPTION:  process this incoming message
413 #===============================================================================
414 sub new_passwd {
415     my ($msg_hash) = @_;
417     my $source = @{$msg_hash->{source}}[0];
418     my $passwd = @{$msg_hash->{new_passwd}}[0];
420     if (exists $main::known_daemons->{$source}) {
421         &main::add_content2known_daemons(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
422         my $hash = &create_xml_hash("confirm_new_passwd", $server_address, $source);
423         &send_msg_hash2address($hash, $source);
425     } elsif (exists $main::known_clients->{$source}) {
426         &main::add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
428     } else {
429         &main::daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1)   
430     }
432     return;
436 #===  FUNCTION  ================================================================
437 #         NAME:  here_i_am
438 #   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
439 #      RETURNS:  nothing
440 #  DESCRIPTION:  process this incoming message
441 #===============================================================================
442 sub here_i_am {
443     my ($msg_hash) = @_;
445     my $source = @{$msg_hash->{source}}[0];
446     my $mac_address = @{$msg_hash->{mac_address}}[0];
447     my $out_hash;
449     # number of known clients
450     my $nu_clients = keys %{$main::known_clients_db->select_dbentry( {table=>'known_clients'} )};
452     # check wether client address or mac address is already known
453     if (exists $main::known_clients->{$source}) {
454         &main::daemon_log("WARNING: $source is already known as a client", 1);
455         &main::daemon_log("WARNING: values for $source are being overwritten", 1);   
456         $nu_clients --;
457     }
459     # number of actual activ clients
460     my $act_nu_clients = $nu_clients;
462     &main::daemon_log("number of actual activ clients: $act_nu_clients", 5);
463     &main::daemon_log("number of maximal allowed clients: $max_clients", 5);
465     if($max_clients <= $act_nu_clients) {
466         my $out_hash = &create_xml_hash("denied", $server_address, $source);
467         &add_content2xml_hash($out_hash, "denied", "I_cannot_take_any_more_clients!");
468         my $passwd = @{$msg_hash->{new_passwd}}[0]; 
469         &send_msg_hash2address($out_hash, $source, $passwd);
470         return;
471     }
472     
473     # new client accepted
474     my $new_passwd = @{$msg_hash->{new_passwd}}[0];
476     # create known_daemons entry
477     my $events = @{$msg_hash->{events}}[0];
478     
479     # add entry to known_clients_db
480     my $res = $main::known_clients_db->add_dbentry( {table=>'known_clients', 
481                                                 primkey=>'hostname',
482                                                 hostname=>$source,
483                                                 events=>$events,
484                                                 macaddress=>$mac_address,
485                                                 status=>'registered',
486                                                 hostkey=>$new_passwd,
487                                                 timestamp=>&get_time,
488                                                 } );
489     if ($res == 3) {
490         my $update_hash = { table=>'known_clients' };
491         $update_hash->{where} = [ { hostname=>[$source] } ],
492         $update_hash->{update} = [ { events=>[$events],
493                                      macaddress=>[$mac_address],
494                                      status=>['registered'],
495                                      hostkey=>[$new_passwd],
496                                      timestamp=>[&get_time],
497                                     } ];
498         $res = $main::known_clients_db->update_dbentry( $update_hash );
499     } 
500     if ($res != 1)  {
501         &main::daemon_log("ERROR: cannot add entry to known_clients: $res");
502         return;
503     }
504     
505     # return acknowledgement to client
506     $out_hash = &create_xml_hash("registered", $server_address, $source);
507     &send_msg_hash2address($out_hash, $source, $new_passwd);
509     # notify registered client to bus
510     if( $bus_activ eq "on") {
511         &main::daemon_log("send bus msg that client '$source' has registerd at server '$server_address'", 3);
512         $out_hash = &create_xml_hash("new_client", $server_address, $bus_address, $source);
513         &send_msg_hash2address($out_hash, $bus_address);
514     }
516     # give the new client his ldap config
517     &new_ldap_config($source);
519     return;
523 #===  FUNCTION  ================================================================
524 #         NAME:  who_has
525 #   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
526 #      RETURNS:  nothing 
527 #  DESCRIPTION:  process this incoming message
528 #===============================================================================
529 sub who_has {
530     my ($msg_hash) = @_ ;
531     
532     # what is your search pattern
533     my $search_pattern = @{$msg_hash->{who_has}}[0];
534     my $search_element = @{$msg_hash->{$search_pattern}}[0];
535     &main::daemon_log("who_has-msg looking for $search_pattern $search_element", 7);
537     # scanning known_clients for search_pattern
538     my @host_addresses = keys %$main::known_clients;
539     my $known_clients_entries = length @host_addresses;
540     my $host_address;
541     foreach my $host (@host_addresses) {
542         my $client_element = $main::known_clients->{$host}->{$search_pattern};
543         if ($search_element eq $client_element) {
544             $host_address = $host;
545             last;
546         }
547     }
548         
549     # search was successful
550     if (defined $host_address) {
551         my $source = @{$msg_hash->{source}}[0];
552         my $out_msg = &create_xml_hash("who_has_i_do", $server_address, $source, "mac_address");
553         &add_content2xml_hash($out_msg, "mac_address", $search_element);
554         &send_msg_hash2address($out_msg, $bus_address);
555     }
556     return;
560 sub who_has_i_do {
561     my ($msg_hash) = @_ ;
562     my $header = @{$msg_hash->{header}}[0];
563     my $source = @{$msg_hash->{source}}[0];
564     my $search_param = @{$msg_hash->{$header}}[0];
565     my $search_value = @{$msg_hash->{$search_param}}[0];
566     print "\ngot msg $header:\nserver $source has client with $search_param $search_value\n";
570 #===  FUNCTION  ================================================================
571 #         NAME:  new_ldap_config
572 #   PARAMETERS:  address - string - ip address and port of a host
573 #      RETURNS:  nothing
574 #  DESCRIPTION:  send to address the ldap configuration found for dn gotoLdapServer
575 #===============================================================================
576 sub new_ldap_config {
577     my ($address) = @_ ;
578     
579     my $res = $main::known_clients_db->select_dbentry( { table=>'known_clients', hostname=>$address } );
581     # check hit
582     my $hit_counter = keys %{$res};
583     if( not $hit_counter == 1 ) {
584         &main::daemon_log("ERROR: more or no hit found in known_clients_db by query by '$address'", 1);
585         my $tmp = print Dumer $res;
586     }
588     my $macaddress = $res->{1}->{macaddress};
589     my $hostkey = $res->{1}->{hostkey};
591     if (not defined $macaddress) {
592         &main::daemon_log("ERROR: no mac address found for client $address", 1);
593         return;
594     }
596     # Build LDAP connection
597     my $ldap = Net::LDAP->new($ldap_uri);
598     if( not defined $ldap ) {
599         &main::daemon_log("ERROR: cannot connect to ldap: $ldap_uri", 1);
600         return;
601     } 
604     # Bind to a directory with dn and password
605     my $mesg= $ldap->bind($ldap_admin_dn, $ldap_admin_password);
607     # Perform search
608     $mesg = $ldap->search( base   => $ldap_base,
609                     scope  => 'sub',
610                     attrs => ['dn', 'gotoLdapServer'],
611                     filter => "(&(objectClass=GOhard)(macaddress=$macaddress))");
612     $mesg->code && die $mesg->error;
614     # Sanity check
615     if ($mesg->count != 1) {
616             &main::daemon_log("WARNING: client mac address $macaddress not found/not unique in ldap search", 1);
617         &main::daemon_log("\tbase: $ldap_base", 1);
618         &main::daemon_log("\tscope: sub", 1);
619         &main::daemon_log("\tattrs: dn, gotoLdapServer", 1);
620         &main::daemon_log("\tfilter: (&(objectClass=GOhard)(macaddress=$macaddress))", 1);
621             return;
622     }
624     my $entry= $mesg->entry(0);
625     my $dn= $entry->dn;
626     my @servers= $entry->get_value("gotoLdapServer");
627     my @ldap_uris;
628     my $server;
629     my $base;
631     # Do we need to look at an object class?
632     if ($#servers < 1){
633             $mesg = $ldap->search( base   => $ldap_base,
634                             scope  => 'sub',
635                             attrs => ['dn', 'gotoLdapServer'],
636                             filter => "(&(objectClass=gosaGroupOfNames)(member=$dn))");
637             $mesg->code && die $mesg->error;
639             # Sanity check
640             if ($mesg->count != 1) {
641                     &main::daemon_log("WARNING: no LDAP information found for client mac $macaddress", 1);
642                     return;
643             }
645             $entry= $mesg->entry(0);
646             $dn= $entry->dn;
647             @servers= $entry->get_value("gotoLdapServer");
648     }
650     @servers= sort (@servers);
652     foreach $server (@servers){
653             $base= $server;
654             $server =~ s%^[^:]+:[^:]+:(ldap.*://[^/]+)/.*$%$1%;
655             $base =~ s%^[^:]+:[^:]+:ldap.*://[^/]+/(.*)$%$1%;
656             push (@ldap_uris, $server);
657     }
659     # Unbind
660     $mesg = $ldap->unbind;
662     # Assemble data package
663     my %data = ( 'ldap_uri'  => \@ldap_uris, 'ldap_base' => $base,
664                      'ldap_cfg' => \@ldap_cfg, 'pam_cfg' => \@pam_cfg,'nss_cfg' => \@nss_cfg );
666     # Need to append GOto settings?
667     if (defined $goto_admin and defined $goto_secret){
668             $data{'goto_admin'}= $goto_admin;
669             $data{'goto_secret'}= $goto_secret;
670     }
672     # Send information
673     send_msg("new_ldap_config", $server_address, $address, \%data, $hostkey);
675     return;
679 #===  FUNCTION  ================================================================
680 #         NAME:  execute_actions
681 #   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
682 #      RETURNS:  nothing
683 #  DESCRIPTION:  invokes the script specified in msg_hash which is located under
684 #                /etc/gosad/actions
685 #===============================================================================
686 sub execute_actions {
687     my ($msg_hash) = @_ ;
688     my $configdir= '/etc/gosad/actions/';
689     my $result;
691     my $header = @{$msg_hash->{header}}[0];
692     my $source = @{$msg_hash->{source}}[0];
693     my $target = @{$msg_hash->{target}}[0];
694  
695     if((not defined $source)
696             && (not defined $target)
697             && (not defined $header)) {
698         &main::daemon_log("ERROR: Entries missing in XML msg for gosad actions under /etc/gosad/actions");
699     } else {
700         my $parameters="";
701         my @params = @{$msg_hash->{$header}};
702         my $params = join(", ", @params);
703         &main::daemon_log("execute_actions: got parameters: $params", 5);
705         if (@params) {
706             foreach my $param (@params) {
707                 my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0];
708                 &main::daemon_log("execute_actions: parameter -> value: $param -> $param_value", 7);
709                 $parameters.= " ".$param_value;
710             }
711         }
713         my $cmd= $configdir.$header."$parameters";
714         &main::daemon_log("execute_actions: executing cmd: $cmd", 7);
715         $result= "";
716         open(PIPE, "$cmd 2>&1 |");
717         while(<PIPE>) {
718             $result.=$_;
719         }
720         close(PIPE);
721     }
723     # process the event result
726     return;
730 1;