Code

bugfix: error message for gosa_ping was not gosa-si valid
[gosa.git] / gosa-si / server / events / gosaTriggered.pm
1 ## @file
2 # @details A GOsa-SI event module containing all functions common used by GOsa
3 # @brief Implementation of a GOsa-SI event module. 
5 package gosaTriggered;
6 use Exporter;
7 @ISA = qw(Exporter);
8 my @events = (
9     "get_events", 
10     "get_login_usr_for_client",
11     "get_client_for_login_usr",
12     "gen_smb_hash",
13     "trigger_reload_ldap_config",
14     "ping",
15     "network_completition",
16     "set_activated_for_installation",
17     "new_key_for_client",
18     "detect_hardware",
19     "get_login_usr",
20     "get_login_client",
21     "trigger_action_localboot",
22     "trigger_action_faireboot",
23     "trigger_action_reboot",
24     "trigger_action_activate",
25     "trigger_action_lock",
26     "trigger_action_halt",
27     "trigger_action_update", 
28     "trigger_action_reinstall",
29     "trigger_action_memcheck", 
30     "trigger_action_sysinfo",
31     "trigger_action_instant_update",
32     "trigger_action_rescan",
33     "trigger_action_wake",
34     "recreate_fai_server_db",
35     "recreate_fai_release_db",
36     "recreate_packages_list_db",
37     "send_user_msg", 
38     "get_available_kernel",
39         "trigger_activate_new",
40 #       "get_dak_keyring",
41 #       "import_dak_key",
42 #       "remove_dak_key",
43 #    "get_dak_queue",
44     );
45 @EXPORT = @events;
47 use strict;
48 use warnings;
49 use GOSA::GosaSupportDaemon;
50 use Data::Dumper;
51 use Crypt::SmbHash;
52 use Net::ARP;
53 use Net::Ping;
54 use Socket;
55 use Time::HiRes qw( usleep);
56 use MIME::Base64;
58 BEGIN {}
60 END {}
62 ### Start ######################################################################
64 ## @method get_events()
65 # A brief function returning a list of functions which are exported by importing the module.
66 # @return List of all provided functions
67 sub get_events {
68     return \@events;
69 }
71 ## @method send_usr_msg($msg, $msg_hash, $session_id)
72 # This function accepts usr messages from GOsa, split mulitple target messages to mulitiple single target messages and put all messages into messaging_db
73 # @param msg - STRING - xml message
74 # @param msg_hash - HASHREF - message information parsed into a hash
75 # @param session_id - INTEGER - POE session id of the processing of this message
76 # @return (out_msg)  - ARRAY - Array containing the answer message from client
77 sub send_user_msg {
78     my ($msg, $msg_hash, $session_id) = @_ ;
79     my $header = @{$msg_hash->{'header'}}[0];
80     my $source = @{$msg_hash->{'source'}}[0];
81     my $target = @{$msg_hash->{'target'}}[0];
83     #my $subject = &decode_base64(@{$msg_hash->{'subject'}}[0]);   # just for debugging
84     my $subject = @{$msg_hash->{'subject'}}[0];
85     my $from = @{$msg_hash->{'from'}}[0];
86     my @users = exists $msg_hash->{'users'} ? @{$msg_hash->{'users'}} : () ;
87         my @groups = exists $msg_hash->{'groups'} ? @{$msg_hash->{'groups'}} : ();
88     my $delivery_time = @{$msg_hash->{'delivery_time'}}[0];
89     #my $message = &decode_base64(@{$msg_hash->{'message'}}[0]);   # just for debugging
90     my $message = @{$msg_hash->{'message'}}[0];
91     
92     # keep job queue uptodate if necessary 
93     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
94     if( defined $jobdb_id) {
95         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
96         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
97         my $res = $main::job_db->exec_statement($sql_statement);
98     }
100     # error handling
101     if (not $delivery_time =~ /^\d{14}$/) {
102         my $error_string = "delivery_time '$delivery_time' is not a valid timestamp, please use format 'yyyymmddhhmmss'";
103         &main::daemon_log("$session_id ERROR: $error_string", 1);
104         return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
105     }
107     # determine new message id
108     my $new_msg_id = 1;
109         my $new_msg_id_sql = "SELECT MAX(CAST(id AS INTEGER)) FROM $main::messaging_tn";
110     my $new_msg_id_res = $main::messaging_db->exec_statement($new_msg_id_sql);
111     if (defined @{@{$new_msg_id_res}[0]}[0] ) {
112         $new_msg_id = int(@{@{$new_msg_id_res}[0]}[0]);
113         $new_msg_id += 1;
114     }
116         # highlight user name and group name
117         my @receiver_l;
118         @users = map(push(@receiver_l, "u_$_"), @users);
119         @groups = map(push(@receiver_l, "g_$_"), @groups);
121     # add incoming message to messaging_db
122     my $func_dic = {table=>$main::messaging_tn,
123         primkey=>[],
124         id=>$new_msg_id,
125         subject=>$subject,
126         message_from=>$from,
127         message_to=>join(",", @receiver_l),
128         flag=>"n",
129         direction=>"in",
130         delivery_time=>$delivery_time,
131         message=>$message,
132         timestamp=>&get_time(),
133     };
134     my $res = $main::messaging_db->add_dbentry($func_dic);
135     if (not $res == 0) {
136         &main::daemon_log("$session_id ERROR: gosaTriggered.pm: cannot add message to message_db: $res", 1);
137     } else {
138         &main::daemon_log("$session_id INFO: gosaTriggered.pm: message with subject '$subject' successfully added to message_db", 5);
139     }
141     return;
145 sub recreate_fai_server_db {
146     my ($msg, $msg_hash, $session_id) = @_ ;
147     my $out_msg;
149     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
150     if( defined $jobdb_id) {
151         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
152         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
153         my $res = $main::job_db->exec_statement($sql_statement);
154     }
156     $main::fai_server_db->create_table("new_fai_server", \@main::fai_server_col_names);
157     &main::create_fai_server_db("new_fai_server",undef,"dont", $session_id);
158     $main::fai_server_db->move_table("new_fai_server", $main::fai_server_tn);
159     
160     my @out_msg_l = ( $out_msg );
161     return @out_msg_l;
165 sub recreate_fai_release_db {
166     my ($msg, $msg_hash, $session_id) = @_ ;
167     my $out_msg;
169     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
170     if( defined $jobdb_id) {
171         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
172         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
173         my $res = $main::job_db->exec_statement($sql_statement);
174     }
176     $main::fai_release_db->create_table("new_fai_release", \@main::fai_release_col_names);
177     &main::create_fai_release_db("new_fai_release", $session_id);
178     $main::fai_release_db->move_table("new_fai_release", $main::fai_release_tn);
180     my @out_msg_l = ( $out_msg );
181     return @out_msg_l;
185 sub recreate_packages_list_db {
186         my ($msg, $msg_hash, $session_id) = @_ ;
187         my $out_msg;
189         my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
190         if( defined $jobdb_id) {
191                 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
192                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
193                 my $res = $main::job_db->exec_statement($sql_statement);
194         }
196         &main::create_packages_list_db;
198         my @out_msg_l = ( $out_msg );
199         return @out_msg_l;
203 sub get_login_usr_for_client {
204     my ($msg, $msg_hash, $session_id) = @_ ;
205     my $header = @{$msg_hash->{'header'}}[0];
206     my $source = @{$msg_hash->{'source'}}[0];
207     my $target = @{$msg_hash->{'target'}}[0];
208     my $client = @{$msg_hash->{'client'}}[0];
210     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
211     if( defined $jobdb_id) {
212         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
213         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
214         my $res = $main::job_db->exec_statement($sql_statement);
215     }
217     $header =~ s/^gosa_//;
219     my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$client' OR macaddress LIKE '$client'";
220     my $res = $main::known_clients_db->select_dbentry($sql_statement);
222     my $out_msg = "<xml><header>$header</header><source>$target</source><target>$source</target>";
223     $out_msg .= &db_res2xml($res);
224     $out_msg .= "</xml>";
226     my @out_msg_l = ( $out_msg );
227     return @out_msg_l;
231 sub get_client_for_login_usr {
232     my ($msg, $msg_hash, $session_id) = @_ ;
233     my $header = @{$msg_hash->{'header'}}[0];
234     my $source = @{$msg_hash->{'source'}}[0];
235     my $target = @{$msg_hash->{'target'}}[0];
237     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
238     if( defined $jobdb_id) {
239         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
240         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
241         my $res = $main::job_db->exec_statement($sql_statement);
242     }
244     my $usr = @{$msg_hash->{'usr'}}[0];
245     $header =~ s/^gosa_//;
247     my $sql_statement = "SELECT * FROM known_clients WHERE login LIKE '%$usr%'";
248     my $res = $main::known_clients_db->select_dbentry($sql_statement);
250     my $out_msg = "<xml><header>$header</header><source>$target</source><target>$source</target>";
251     $out_msg .= &db_res2xml($res);
252     $out_msg .= "</xml>";
253     my @out_msg_l = ( $out_msg );
254     return @out_msg_l;
259 sub ping {
260     my ($msg, $msg_hash, $session_id) = @_ ;
261     my $header = @{$msg_hash->{header}}[0];
262     my $target = @{$msg_hash->{target}}[0];
263     my $source = @{$msg_hash->{source}}[0];
264     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
265     my $error = 0;
266     my $answer_msg;
267     my ($sql, $res);
269     if( defined $jobdb_id) {
270         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
271         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
272         my $res = $main::job_db->exec_statement($sql_statement);
273     }
275     # send message
276     $sql = "SELECT * FROM $main::known_clients_tn WHERE ((hostname='$target') || (macaddress LIKE '$target'))"; 
277     $res = $main::known_clients_db->exec_statement($sql);
279     # sanity check of db result
280     my ($host_name, $host_key);
281     if ((defined $res) && (@$res > 0) && @{@$res[0]} > 0) {
282         $host_name = @{@$res[0]}[0];
283         $host_key = @{@$res[0]}[2];
284     } else {
285         &main::daemon_log("$session_id ERROR: cannot determine host_name and host_key from known_clients_db at function ping\n$msg", 1);
286         my %data = ( 'answer_xml'  => 'host not found in known_clients_db',
287                 'macaddress' => $target,
288                 );
289         $answer_msg = &build_msg("got_ping_error", $main::server_address, $source, \%data);
290         $error = 1;
291     }
293     if (not $error) {
294         my $client_hash = &create_xml_hash("ping", $main::server_address, $host_name);
295         &add_content2xml_hash($client_hash, 'session_id', $session_id); 
296         my $client_msg = &create_xml_string($client_hash);
297         &main::send_msg_to_target($client_msg, $host_name, $host_key, $header, $session_id);
299         my $message_id;
300         my $i = 0;
301         while (1) {
302             $i++;
303             $sql = "SELECT * FROM $main::incoming_tn WHERE headertag='answer_$session_id'";
304             $res = $main::incoming_db->exec_statement($sql);
305             if (ref @$res[0] eq "ARRAY") { 
306                 $message_id = @{@$res[0]}[0];
307                 last;
308             }
310             # do not run into a endless loop
311             if ($i > 100) { last; }
312             usleep(100000);
313         }
315         # if an answer to the question exists
316         if (defined $message_id) {
317             my $answer_xml = @{@$res[0]}[3];
318             my %data = ( 'answer_xml'  => 'bin noch da' );
319             $answer_msg = &build_msg("got_ping", $target, $source, \%data);
320             my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
321             if (defined $forward_to_gosa){
322                 $answer_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
323             }
324             $sql = "DELETE FROM $main::incoming_tn WHERE id=$message_id"; 
325             $res = $main::incoming_db->exec_statement($sql);
326         }
328     }
330     return ( $answer_msg );
335 sub gen_smb_hash {
336      my ($msg, $msg_hash, $session_id) = @_ ;
337      my $source = @{$msg_hash->{source}}[0];
338      my $target = @{$msg_hash->{target}}[0];
339      my $password = @{$msg_hash->{password}}[0];
341      my %data= ('hash' => join(q[:], ntlmgen $password));
342      my $out_msg = &build_msg("gen_smb_hash", $target, $source, \%data );
343      my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
344      if (defined $forward_to_gosa) {
345          $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
346      }
348      return ( $out_msg );
352 sub network_completition {
353      my ($msg, $msg_hash, $session_id) = @_ ;
354      my $source = @{$msg_hash->{source}}[0];
355      my $target = @{$msg_hash->{target}}[0];
356      my $name = @{$msg_hash->{hostname}}[0];
358      # Can we resolv the name?
359      my %data;
360      if (inet_aton($name)){
361              my $address = inet_ntoa(inet_aton($name));
362              my $p = Net::Ping->new('tcp');
363              my $mac= "";
364              if ($p->ping($address, 1)){
365                $mac = Net::ARP::arp_lookup("", $address);
366              }
368              %data= ('ip' => $address, 'mac' => $mac);
369      } else {
370              %data= ('ip' => '', 'mac' => '');
371      }
373      my $out_msg = &build_msg("network_completition", $target, $source, \%data );
374      my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
375      if (defined $forward_to_gosa) {
376          $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
377      }
379      return ( $out_msg );
383 sub detect_hardware {
384     my ($msg, $msg_hash, $session_id) = @_ ;
385     # just forward msg to client, but dont forget to split off 'gosa_' in header
386     my $source = @{$msg_hash->{source}}[0];
387     my $target = @{$msg_hash->{target}}[0];
388     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
389     if( defined $jobdb_id) {
390         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
391         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
392         my $res = $main::job_db->exec_statement($sql_statement);
393     }
395     my $out_hash = &create_xml_hash("detect_hardware", $source, $target);
396     if( defined $jobdb_id ) { 
397         &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id); 
398     }
399     my $out_msg = &create_xml_string($out_hash);
401     my @out_msg_l = ( $out_msg );
402     return @out_msg_l;
407 sub trigger_reload_ldap_config {
408     my ($msg, $msg_hash, $session_id) = @_ ;
409     my $target = @{$msg_hash->{target}}[0];
411     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
412     if( defined $jobdb_id) {
413         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
414         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
415         my $res = $main::job_db->exec_statement($sql_statement);
416     }
418         my $out_msg = &ClientPackages::new_ldap_config($target, $session_id);
419         my @out_msg_l = ( $out_msg );
421     return @out_msg_l;
425 sub set_activated_for_installation {
426     my ($msg, $msg_hash, $session_id) = @_;
427     my $header = @{$msg_hash->{header}}[0];
428     my $source = @{$msg_hash->{source}}[0];
429     my $target = @{$msg_hash->{target}}[0];
430         my @out_msg_l;
432         # update status of job 
433     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
434     if( defined $jobdb_id) {
435         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
436         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
437         my $res = $main::job_db->exec_statement($sql_statement);
438     }
440         # create set_activated_for_installation message for delivery
441     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $target);
442     if( defined $jobdb_id ) { 
443         &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id); 
444     }
445     my $out_msg = &create_xml_string($out_hash);
446         push(@out_msg_l, $out_msg); 
448     return @out_msg_l;
452 sub trigger_action_faireboot {
453     my ($msg, $msg_hash, $session_id) = @_;
454     my $macaddress = @{$msg_hash->{macaddress}}[0];
455     my $source = @{$msg_hash->{source}}[0];
457     my @out_msg_l;
458     $msg =~ s/<header>gosa_trigger_action_faireboot<\/header>/<header>trigger_action_faireboot<\/header>/;
459     push(@out_msg_l, $msg);
461     &main::change_goto_state('locked', \@{$msg_hash->{macaddress}}, $session_id);
462         &main::change_fai_state('install', \@{$msg_hash->{macaddress}}, $session_id); 
464     # set job to status 'done', job will be deleted automatically
465     my $sql_statement = "UPDATE $main::job_queue_tn ".
466         "SET status='done', modified='1'".
467         "WHERE (macaddress='$macaddress' AND status='processing')";
468     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
469     my $res = $main::job_db->update_dbentry( $sql_statement );
471     return @out_msg_l;
475 sub trigger_action_lock {
476     my ($msg, $msg_hash, $session_id) = @_;
477     my $macaddress = @{$msg_hash->{macaddress}}[0];
478     my $source = @{$msg_hash->{source}}[0];
480     &main::change_goto_state('locked', \@{$msg_hash->{macaddress}}, $session_id);
481     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
482     if( defined $jobdb_id) {
483         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
484         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
485         my $res = $main::job_db->exec_statement($sql_statement);
486     }
487                                              
488     my @out_msg_l;
489     return @out_msg_l;
493 sub trigger_action_activate {
494     my ($msg, $msg_hash, $session_id) = @_;
495     my $macaddress = @{$msg_hash->{macaddress}}[0];
496     my $source = @{$msg_hash->{source}}[0];
498     &main::change_goto_state('active', \@{$msg_hash->{macaddress}}, $session_id);
499     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
500     if( defined $jobdb_id) {
501         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
502         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
503         my $res = $main::job_db->exec_statement($sql_statement);
504     }
505                                              
506     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $macaddress);
507     if( exists $msg_hash->{'jobdb_id'} ) { 
508         &add_content2xml_hash($out_hash, 'jobdb_id', @{$msg_hash->{'jobdb_id'}}[0]); 
509     }
510     my $out_msg = &create_xml_string($out_hash);
512     return ( $out_msg );
516 sub trigger_action_localboot {
517     my ($msg, $msg_hash, $session_id) = @_;
518     $msg =~ s/<header>gosa_trigger_action_localboot<\/header>/<header>trigger_action_localboot<\/header>/;
519     &main::change_fai_state('localboot', \@{$msg_hash->{macaddress}}, $session_id);
520     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
521     if( defined $jobdb_id) {
522         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
523         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
524         my $res = $main::job_db->exec_statement($sql_statement);
525     }
527     my @out_msg_l = ($msg);  
528     return @out_msg_l;
532 sub trigger_action_halt {
533     my ($msg, $msg_hash, $session_id) = @_;
534     $msg =~ s/<header>gosa_trigger_action_halt<\/header>/<header>trigger_action_halt<\/header>/;
536     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
537     if( defined $jobdb_id) {
538         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
539         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
540         my $res = $main::job_db->exec_statement($sql_statement);
541     }
543     my @out_msg_l = ($msg);  
544     return @out_msg_l;
548 sub trigger_action_reboot {
549     my ($msg, $msg_hash, $session_id) = @_;
550     $msg =~ s/<header>gosa_trigger_action_reboot<\/header>/<header>trigger_action_reboot<\/header>/;
552     &main::change_fai_state('reboot', \@{$msg_hash->{macaddress}}, $session_id);
553     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
554     if( defined $jobdb_id) {
555         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
556         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
557         my $res = $main::job_db->exec_statement($sql_statement);
558     }
560     my @out_msg_l = ($msg);  
561     return @out_msg_l;
565 sub trigger_action_memcheck {
566     my ($msg, $msg_hash, $session_id) = @_ ;
567     $msg =~ s/<header>gosa_trigger_action_memcheck<\/header>/<header>trigger_action_memcheck<\/header>/;
569     &main::change_fai_state('memcheck', \@{$msg_hash->{macaddress}}, $session_id);
570     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
571     if( defined $jobdb_id) {
572         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
573         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
574         my $res = $main::job_db->exec_statement($sql_statement);
575     }
577     my @out_msg_l = ($msg);  
578     return @out_msg_l;
582 sub trigger_action_reinstall {
583     my ($msg, $msg_hash, $session_id) = @_;
584     $msg =~ s/<header>gosa_trigger_action_reinstall<\/header>/<header>trigger_action_reinstall<\/header>/;
586     &main::change_fai_state('reinstall', \@{$msg_hash->{macaddress}}, $session_id);
588     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
589     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
590     my @out_msg_l = ($wake_msg, $msg);  
591     return @out_msg_l;
595 sub trigger_action_update {
596     my ($msg, $msg_hash, $session_id) = @_;
597     $msg =~ s/<header>gosa_trigger_action_update<\/header>/<header>trigger_action_update<\/header>/;
599     &main::change_fai_state('update', \@{$msg_hash->{macaddress}}, $session_id);
601     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
602     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
603     my @out_msg_l = ($wake_msg, $msg);  
604     return @out_msg_l;
608 sub trigger_action_instant_update {
609     my ($msg, $msg_hash, $session_id) = @_;
610     $msg =~ s/<header>gosa_trigger_action_instant_update<\/header>/<header>trigger_action_instant_update<\/header>/;
612     &main::change_fai_state('update', \@{$msg_hash->{macaddress}}, $session_id);
614     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
615     if( defined $jobdb_id) {
616         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
617         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
618         my $res = $main::job_db->exec_statement($sql_statement);
619     }
621     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
622     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
623     my @out_msg_l = ($wake_msg, $msg);  
624     return @out_msg_l;
628 sub trigger_action_sysinfo {
629     my ($msg, $msg_hash, $session_id) = @_;
630     $msg =~ s/<header>gosa_trigger_action_sysinfo<\/header>/<header>trigger_action_sysinfo<\/header>/;
632     &main::change_fai_state('sysinfo', \@{$msg_hash->{macaddress}}, $session_id);
633     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
634     if( defined $jobdb_id) {
635         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
636         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
637         my $res = $main::job_db->exec_statement($sql_statement);
638     }
640     my @out_msg_l = ($msg);  
641     return @out_msg_l;
645 sub new_key_for_client {
646     my ($msg, $msg_hash, $session_id) = @_;
648     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
649     if( defined $jobdb_id) {
650         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
651         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
652         my $res = $main::job_db->exec_statement($sql_statement);
653     }
654     
655     $msg =~ s/<header>gosa_new_key_for_client<\/header>/<header>new_key<\/header>/;
656     my @out_msg_l = ($msg);  
657     return @out_msg_l;
661 sub trigger_action_rescan {
662     my ($msg, $msg_hash, $session_id) = @_;
664     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
665     if( defined $jobdb_id) {
666         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
667         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
668         my $res = $main::job_db->exec_statement($sql_statement);
669     }
672     $msg =~ s/<header>gosa_trigger_action_rescan<\/header>/<header>detect_hardware<header>/;
673     my @out_msg_l = ($msg);  
674     return @out_msg_l;
678 sub trigger_action_wake {
679     my ($msg, $msg_hash, $session_id) = @_;
680     
681     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
682     if( defined $jobdb_id) {
683         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
684         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
685         my $res = $main::job_db->exec_statement($sql_statement);
686     }
688     # build out message
689     my $out_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
690     foreach (@{$msg_hash->{target}}) {
691         &add_content2xml_hash($out_hash, 'macAddress', $_);
692     }
693     my $out_msg = &create_xml_string($out_hash);
694     
695     # invoke trigger wake for this gosa-si-server
696     &main::server_server_com::trigger_wake($out_msg, $out_hash, $session_id);
698     # send trigger wake to all other gosa-si-server
699     my @out_msg_l = ($out_msg);  
700     return @out_msg_l;
704 sub get_available_kernel {
705         my ($msg, $msg_hash, $session_id) = @_;
707         my $source = @{$msg_hash->{'source'}}[0];
708         my $target = @{$msg_hash->{'target'}}[0];
709         my $release= @{$msg_hash->{'release'}}[0];
711         my @kernel;
712         # Get Kernel packages for release
713         my $sql_statement = "SELECT * FROM $main::packages_list_tn WHERE distribution='$release' AND package LIKE 'linux\-image\-%'";
714         my $res_hash = $main::packages_list_db->select_dbentry($sql_statement);
715         my %data;
716         my $i=1;
718         foreach my $package (keys %{$res_hash}) {
719                 $data{"answer".$i++}= $data{"answer".$i++}= ${$res_hash}{$package}->{'package'};
720         }
721         $data{"answer".$i++}= "default";
723         my $out_msg = &build_msg("get_available_kernel", $target, $source, \%data);
724         my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
725         if (defined $forward_to_gosa) {
726             $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
727         }
729         return ( $out_msg );
733 sub trigger_activate_new {
734         my ($msg, $msg_hash, $session_id) = @_;
736         my $source = @{$msg_hash->{'source'}}[0];
737         my $target = @{$msg_hash->{'target'}}[0];
738         my $header= @{$msg_hash->{'header'}}[0];
739         my $mac= (defined($msg_hash->{'mac'}))?@{$msg_hash->{'mac'}}[0]:undef;
740         my $ogroup= (defined($msg_hash->{'ogroup'}))?@{$msg_hash->{'ogroup'}}[0]:undef;
741         my $timestamp= (defined($msg_hash->{'timestamp'}))?@{$msg_hash->{'timestamp'}}[0]:undef;
742         my $base= (defined($msg_hash->{'base'}))?@{$msg_hash->{'base'}}[0]:undef;
743         my $hostname= (defined($msg_hash->{'fqdn'}))?@{$msg_hash->{'fqdn'}}[0]:undef;
744         my $ip_address= (defined($msg_hash->{'ip'}))?@{$msg_hash->{'ip'}}[0]:undef;
745         my $dhcp_statement= (defined($msg_hash->{'dhcp'}))?@{$msg_hash->{'dhcp'}}[0]:undef;
746         my $jobdb_id= (defined($msg_hash->{'jobdb_id'}))?@{$msg_hash->{'jobdb_id'}}[0]:undef;
748         my $ldap_handle = &main::get_ldap_handle();
749         my $ldap_entry;
750         my $ogroup_entry;
751         my $changed_attributes_counter = 0;
752         
753         eval {
755                 my $ldap_mesg= $ldap_handle->search(
756                         base => $main::ldap_base,
757                         scope => 'sub',
758                         filter => "(&(objectClass=gosaGroupOfnames)(cn=$ogroup))",
759                 );
760                 if($ldap_mesg->count == 1) {
761                         $ogroup_entry= $ldap_mesg->pop_entry();
762                 } elsif ($ldap_mesg->count == 0) {
763                         &main::daemon_log("ERROR: A GosaGroupOfNames with cn '$ogroup' was not found in base '".$main::ldap_base."'!", 1);
764                 } else {
765                         &main::daemon_log("ERROR: More than one ObjectGroups with cn '$ogroup' was found in base '".$main::ldap_base."'!", 1);
766                 }
768                 # build the base, use optional base parameter or take it from ogroup
769                 if(!(defined($base) && (length($base) > 0))) {
770                                 # Subtract the ObjectGroup cn
771                                 $base = $1 if $ogroup_entry->dn =~ /cn=$ogroup,ou=groups,(.*)$/;
772                 }
774                 # prepend ou=systems (configurable through config)
775                 $base = $main::new_systems_ou.",".$base;
777                 # Search for an existing entry (should be in ou=incoming)
778                 $ldap_mesg= $ldap_handle->search(
779                         base => $main::ldap_base,
780                         scope => 'sub',
781                         filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
782                 );
784                 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
786                 if($ldap_mesg->count == 1) {
787                         &main::daemon_log("DEBUG: One system with mac address '$mac' was found in base '".$main::ldap_base."'!", 6);
788                         # Get the entry from LDAP
789                         $ldap_entry= $ldap_mesg->pop_entry();
791                         if(!($ldap_entry->dn() eq "cn=".$ldap_entry->get_value('cn').",$base")) {
792                                 # Move the entry to the new ou
793                                 $ldap_entry->changetype('moddn');
794                                 $ldap_entry->add(
795                                         newrdn => "cn=".$ldap_entry->get_value('cn'),
796                                         deleteoldrdn => 1,
797                                         newsuperior => $base,
798                                 );
799                         }
801                 } 
803                 $ldap_mesg= $ldap_handle->search(
804                         base => $main::ldap_base,
805                         scope => 'sub',
806                         filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
807                 );
809                 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
811                 if($ldap_mesg->count == 1) {
812                         $ldap_entry= $ldap_mesg->pop_entry();
813                         # Check for needed objectClasses
814                         my $oclasses = $ldap_entry->get_value('objectClass', asref => 1);
815                         foreach my $oclass ("FAIobject", "GOhard") {
816                                 if(!(scalar grep $_ eq $oclass, map {$_ => 1} @$oclasses)) {
817                                         &main::daemon_log("Adding objectClass $oclass", 1);
818                                         $ldap_entry->add(
819                                                 objectClass => $oclass,
820                                         );
821                                         my $oclass_result = $ldap_entry->update($ldap_handle);
822                                 }
823                         }
825                         # Set FAIstate
826                         if(defined($ldap_entry->get_value('FAIstate'))) {
827                                 if(!($ldap_entry->get_value('FAIstate') eq 'install')) {
828                                         $ldap_entry->replace(
829                                                 'FAIstate' => 'install'
830                                         );
831                                         my $replace_result = $ldap_entry->update($ldap_handle);
832                                 }
833                         } else {
834                                 $ldap_entry->add(
835                                         'FAIstate' => 'install'
836                                 );
837                                 my $add_result = $ldap_entry->update($ldap_handle);
838                         }
841                 } elsif ($ldap_mesg->count == 0) {
842                         # TODO: Create a new entry
843                         # $ldap_entry = Net::LDAP::Entry->new();
844                         # $ldap_entry->dn("cn=$mac,$base");
845                         &main::daemon_log("WARNING: No System with mac address '$mac' was found in base '".$main::ldap_base."'! Re-queuing job.", 4);
846                         $main::job_db->exec_statement("UPDATE jobs SET status = 'waiting', timestamp = '".&get_time()."' WHERE id = $jobdb_id");
847                 } else {
848                         &main::daemon_log("ERROR: More than one system with mac address '$mac' was found in base '".$main::ldap_base."'!", 1);
849                 }
851                 # Add to ObjectGroup
852                 if(!(scalar grep $_, map {$_ => 1} $ogroup_entry->get_value('member', asref => 1))) {
853                         $ogroup_entry->add (
854                                 'member' => $ldap_entry->dn(),
855                         );
856                         my $ogroup_result = $ogroup_entry->update($ldap_handle);
857                         if ($ogroup_result->code() != 0) {
858                                 &main::daemon_log("ERROR: Updating the ObjectGroup '$ogroup' failed (code '".$ogroup_result->code()."') with '".$ogroup_result->{'errorMessage'}."'!", 1);
859                         }
860                 }
862                 # Finally set gotoMode to active
863                 if(defined($ldap_entry->get_value('gotoMode'))) {
864                         if(!($ldap_entry->get_value('gotoMode') eq 'active')) {
865                                 $ldap_entry->replace(
866                                         'gotoMode' => 'active'
867                                 );
868                                 my $activate_result = $ldap_entry->update($ldap_handle);
869                                 if ($activate_result->code() != 0) {
870                                         &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
871                                 }
872                         }
873                 } else {
874                         $ldap_entry->add(
875                                 'gotoMode' => 'active'
876                         );
877                         my $activate_result = $ldap_entry->update($ldap_handle);
878                         if ($activate_result->code() != 0) {
879                                 &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
880                         }
881                 }
882         };
883         if($@) {
884                 &main::daemon_log("ERROR: activate_new failed with '$@'!", 1);
885         }
887         # Delete job
888         $main::job_db->exec_statement("DELETE FROM jobs WHERE id =  $jobdb_id");
890         # create set_activated_for_installation message for delivery
891     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $target);
892     my $out_msg = &create_xml_string($out_hash);
893         my @out_msg_l = ($out_msg);
895     return @out_msg_l;
899 #sub get_dak_keyring {
900 #    my ($msg, $msg_hash) = @_;
901 #    my $source = @{$msg_hash->{'source'}}[0];
902 #    my $target = @{$msg_hash->{'target'}}[0];
903 #    my $header= @{$msg_hash->{'header'}}[0];
904 #    my $session_id = @{$msg_hash->{'session_id'}}[0];
906 #    # build return message with twisted target and source
907 #    my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
908 #    &add_content2xml_hash($out_hash, "session_id", $session_id);
910 #    my @keys;
911 #    my %data;
913 #    my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
915 #    my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
916 #    my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --keyring $keyring";
918 #    # Check if the keyrings are in place and readable
919 #    if(
920 #        &run_as($main::dak_user, "test -r $keyring")->{'resultCode'} != 0
921 #    ) {
922 #        &add_content2xml_hash($out_hash, "error", "DAK Keyring is not readable");
923 #    } else {
924 #        my $command = "$gpg --list-keys";
925 #        my $output = &run_as($main::dak_user, $command);
926 #        &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
928 #        my $i=0;
929 #        foreach (@{$output->{'output'}}) {
930 #            if ($_ =~ m/^pub\s.*$/) {
931 #                ($keys[$i]->{'pub'}->{'length'}, $keys[$i]->{'pub'}->{'uid'}, $keys[$i]->{'pub'}->{'created'}) = ($1, $2, $3)
932 #                if $_ =~ m/^pub\s*?(\w*?)\/(\w*?)\s(\d{4}-\d{2}-\d{2})/;
933 #                $keys[$i]->{'pub'}->{'expires'} = $1 if $_ =~ m/^pub\s*?\w*?\/\w*?\s\d{4}-\d{2}-\d{2}\s\[expires:\s(\d{4}-\d{2}-\d{2})\]/;
934 #                $keys[$i]->{'pub'}->{'expired'} = $1 if $_ =~ m/^pub\s*?\w*?\/\w*?\s\d{4}-\d{2}-\d{2}\s\[expired:\s(\d{4}-\d{2}-\d{2})\]/;
935 #            } elsif ($_ =~ m/^sub\s.*$/) {
936 #                ($keys[$i]->{'sub'}->{'length'}, $keys[$i]->{'sub'}->{'uid'}, $keys[$i]->{'sub'}->{'created'}) = ($1, $2, $3)
937 #                if $_ =~ m/^sub\s*?(\w*?)\/(\w*?)\s(\d{4}-\d{2}-\d{2})/;
938 #                $keys[$i]->{'sub'}->{'expires'} = $1 if $_ =~ m/^pub\s*?\w*?\/\w*?\s\d{4}-\d{2}-\d{2}\s\[expires:\s(\d{4}-\d{2}-\d{2})\]/;
939 #                $keys[$i]->{'sub'}->{'expired'} = $1 if $_ =~ m/^pub\s*?\w*?\/\w*?\s\d{4}-\d{2}-\d{2}\s\[expired:\s(\d{4}-\d{2}-\d{2})\]/;
940 #            } elsif ($_ =~ m/^uid\s.*$/) {
941 #                push @{$keys[$i]->{'uid'}}, $1 if $_ =~ m/^uid\s*?([^\s].*?)$/;
942 #            } elsif ($_ =~ m/^$/) {
943 #                $i++;
944 #            }
945 #        }
946 #    }
948 #    my $i=0;
949 #    foreach my $key (@keys) {
950 #        #    &main::daemon_log(Dumper($key));
951 #        &add_content2xml_hash($out_hash, "answer".$i++, $key);
952 #    }
953 #    my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
954 #    if (defined $forward_to_gosa) {
955 #        &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
956 #    }
957 #    return &create_xml_string($out_hash);
958 #}
961 #sub import_dak_key {
962 #    my ($msg, $msg_hash) = @_;
963 #    my $source = @{$msg_hash->{'source'}}[0];
964 #    my $target = @{$msg_hash->{'target'}}[0];
965 #    my $header= @{$msg_hash->{'header'}}[0];
966 #    my $session_id = @{$msg_hash->{'session_id'}}[0];
967 #    my $key = &decode_base64(@{$msg_hash->{'key'}}[0]);
969 #    # build return message with twisted target and source
970 #    my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
971 #    &add_content2xml_hash($out_hash, "session_id", $session_id);
973 #    my %data;
975 #    my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
977 #    my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
978 #    my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --keyring $keyring";
980 #    # Check if the keyrings are in place and writable
981 #    if(
982 #        &run_as($main::dak_user, "test -w $keyring")->{'resultCode'} != 0
983 #    ) {
984 #        &add_content2xml_hash($out_hash, "error", "DAK Keyring is not writable");
985 #    } else {
986 #        my $keyfile;
987 #        open($keyfile, ">/tmp/gosa_si_tmp_dak_key");
988 #        print $keyfile $key;
989 #        close($keyfile);
990 #        my $command = "$gpg --import /tmp/gosa_si_tmp_dak_key";
991 #        my $output = &run_as($main::dak_user, $command);
992 #        &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
993 #        unlink("/tmp/gosa_si_tmp_dak_key");
995 #        if($output->{'resultCode'} != 0) {
996 #            &add_content2xml_hash($out_hash, "error", "Import of DAK key failed! Output was '".$output->{'output'}."'");
997 #        } else {
998 #            &add_content2xml_hash($out_hash, "answer", "Import of DAK key successfull! Output was '".$output->{'output'}."'");
999 #        }
1000 #    }
1002 #    my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1003 #    if (defined $forward_to_gosa) {
1004 #        &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1005 #    }
1006 #    return &create_xml_string($out_hash);
1007 #}
1010 #sub remove_dak_key {
1011 #    my ($msg, $msg_hash) = @_;
1012 #    my $source = @{$msg_hash->{'source'}}[0];
1013 #    my $target = @{$msg_hash->{'target'}}[0];
1014 #    my $header= @{$msg_hash->{'header'}}[0];
1015 #    my $session_id = @{$msg_hash->{'session_id'}}[0];
1016 #    my $key = @{$msg_hash->{'keyid'}}[0];
1017 #    # build return message with twisted target and source
1018 #    my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
1019 #    &add_content2xml_hash($out_hash, "session_id", $session_id);
1021 #    my %data;
1023 #    my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
1025 #    my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
1026 #    my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --homedir ".$main::dak_signing_keys_directory." --keyring $keyring";
1028 #    # Check if the keyrings are in place and writable
1029 #    if(
1030 #        &run_as($main::dak_user, "test -w $keyring")->{'resultCode'} != 0
1031 #    ) {
1032 #        &add_content2xml_hash($out_hash, "error", "DAK keyring is not writable");
1033 #    } else {
1034 #        # Check if the key is present in the keyring
1035 #        if(&run_as($main::dak_user, "$gpg --list-keys $key")->{'resultCode'} == 0) {
1036 #            my $command = "$gpg --batch --yes --delete-key $key";
1037 #            my $output = &run_as($main::dak_user, $command);
1038 #            &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
1039 #        } else {
1040 #            &add_content2xml_hash($out_hash, "error", "DAK key with id '$key' was not found in keyring");
1041 #        }
1042 #    }
1044 #    my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1045 #    if (defined $forward_to_gosa) {
1046 #        &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1047 #    }
1048 #    return &create_xml_string($out_hash);
1049 #}
1052 #sub get_dak_queue {
1053 #    my ($msg, $msg_hash, $session_id) = @_;
1054 #    my %data;
1055 #    my $source = @{$msg_hash->{'source'}}[0];
1056 #    my $target = @{$msg_hash->{'target'}}[0];
1057 #    my $header= @{$msg_hash->{'header'}}[0];
1059 #    my %data;
1061 #    foreach my $dir ("unchecked", "new", "accepted") {
1062 #        foreach my $file(<"$main::dak_queue_directory/$dir/*.changes">) {
1063 #        }
1064 #    }
1066 #    my $out_msg = &build_msg("get_dak_queue", $target, $source, \%data);
1067 #    my @out_msg_l = ($out_msg);
1068 #    return @out_msg_l;
1069 #}
1072 # vim:ts=4:shiftwidth:expandtab
1073 1;