Code

Migrated to get_cfg_value
[gosa.git] / gosa-si / server / events / gosaTriggered.pm
1 package gosaTriggered;
2 use Exporter;
3 @ISA = qw(Exporter);
4 my @events = (
5     "get_events", 
6     "get_login_usr_for_client",
7     "get_client_for_login_usr",
8     "gen_smb_hash",
9     "trigger_reload_ldap_config",
10     "ping",
11     "network_completition",
12     "set_activated_for_installation",
13     "new_key_for_client",
14     "detect_hardware",
15     "get_login_usr",
16     "get_login_client",
17     "trigger_action_localboot",
18     "trigger_action_faireboot",
19     "trigger_action_reboot",
20     "trigger_action_activate",
21     "trigger_action_lock",
22     "trigger_action_halt",
23     "trigger_action_update", 
24     "trigger_action_reinstall",
25     "trigger_action_memcheck", 
26     "trigger_action_sysinfo",
27     "trigger_action_instant_update",
28     "trigger_action_rescan",
29     "trigger_action_wake",
30     "recreate_fai_server_db",
31     "recreate_fai_release_db",
32     "recreate_packages_list_db",
33     "send_user_msg", 
34     "get_available_kernel",
35         "trigger_activate_new",
36         "get_dak_keyring",
37         "import_dak_key",
38         "remove_dak_key",
39 #    "get_dak_queue",
40     );
41 @EXPORT = @events;
43 use strict;
44 use warnings;
45 use GOSA::GosaSupportDaemon;
46 use Data::Dumper;
47 use Crypt::SmbHash;
48 use Net::ARP;
49 use Net::Ping;
50 use Socket;
51 use Time::HiRes qw( usleep);
52 use MIME::Base64;
54 BEGIN {}
56 END {}
58 ### Start ######################################################################
60 #&main::read_configfile($main::cfg_file, %cfg_defaults);
62 sub get_events {
63     return \@events;
64 }
66 sub send_user_msg {
67     my ($msg, $msg_hash, $session_id) = @_ ;
68     my $header = @{$msg_hash->{'header'}}[0];
69     my $source = @{$msg_hash->{'source'}}[0];
70     my $target = @{$msg_hash->{'target'}}[0];
72     #my $subject = &decode_base64(@{$msg_hash->{'subject'}}[0]);
73     my $subject = @{$msg_hash->{'subject'}}[0];
74     my $from = @{$msg_hash->{'from'}}[0];
75     my @users = exists $msg_hash->{'users'} ? @{$msg_hash->{'users'}} : () ;
76         my @groups = exists $msg_hash->{'groups'} ? @{$msg_hash->{'groups'}} : ();
77     my $delivery_time = @{$msg_hash->{'delivery_time'}}[0];
78     #my $message = &decode_base64(@{$msg_hash->{'message'}}[0]);
79     my $message = @{$msg_hash->{'message'}}[0];
80     
81     # keep job queue uptodate if necessary 
82     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
83     if( defined $jobdb_id) {
84         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
85         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
86         my $res = $main::job_db->exec_statement($sql_statement);
87     }
89     # error handling
90     if (not $delivery_time =~ /^\d{14}$/) {
91         my $error_string = "delivery_time '$delivery_time' is not a valid timestamp, please use format 'yyyymmddhhmmss'";
92         &main::daemon_log("$session_id ERROR: $error_string", 1);
93         return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
94     }
96     # add incoming message to messaging_db
97     my $new_msg_id = 1;
98         my $new_msg_id_sql = "SELECT MAX(CAST(id AS INTEGER)) FROM $main::messaging_tn";
99     my $new_msg_id_res = $main::messaging_db->exec_statement($new_msg_id_sql);
100     if (defined @{@{$new_msg_id_res}[0]}[0] ) {
101         $new_msg_id = int(@{@{$new_msg_id_res}[0]}[0]);
102         $new_msg_id += 1;
103     }
105         # highlight user name and group name
106         my @receiver_l;
107         @users = map(push(@receiver_l, "u_$_"), @users);
108         @groups = map(push(@receiver_l, "g_$_"), @groups);
110     my $func_dic = {table=>$main::messaging_tn,
111         primkey=>[],
112         id=>$new_msg_id,
113         subject=>$subject,
114         message_from=>$from,
115         message_to=>join(",", @receiver_l),
116         flag=>"n",
117         direction=>"in",
118         delivery_time=>$delivery_time,
119         message=>$message,
120         timestamp=>&get_time(),
121     };
122     my $res = $main::messaging_db->add_dbentry($func_dic);
123     if (not $res == 0) {
124         &main::daemon_log("$session_id ERROR: gosaTriggered.pm: cannot add message to message_db: $res", 1);
125     } else {
126         &main::daemon_log("$session_id INFO: gosaTriggered.pm: message with subject '$subject' successfully added to message_db", 5);
127     }
129     return;
133 sub recreate_fai_server_db {
134     my ($msg, $msg_hash, $session_id) = @_ ;
135     my $out_msg;
137     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
138     if( defined $jobdb_id) {
139         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
140         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
141         my $res = $main::job_db->exec_statement($sql_statement);
142     }
144     $main::fai_server_db->create_table("new_fai_server", \@main::fai_server_col_names);
145     &main::create_fai_server_db("new_fai_server",undef,"dont", $session_id);
146     $main::fai_server_db->move_table("new_fai_server", $main::fai_server_tn);
147     
148     my @out_msg_l = ( $out_msg );
149     return @out_msg_l;
153 sub recreate_fai_release_db {
154     my ($msg, $msg_hash, $session_id) = @_ ;
155     my $out_msg;
157     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
158     if( defined $jobdb_id) {
159         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
160         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
161         my $res = $main::job_db->exec_statement($sql_statement);
162     }
164     $main::fai_release_db->create_table("new_fai_release", \@main::fai_release_col_names);
165     &main::create_fai_release_db("new_fai_release", $session_id);
166     $main::fai_release_db->move_table("new_fai_release", $main::fai_release_tn);
168     my @out_msg_l = ( $out_msg );
169     return @out_msg_l;
173 sub recreate_packages_list_db {
174         my ($msg, $msg_hash, $session_id) = @_ ;
175         my $out_msg;
177         my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
178         if( defined $jobdb_id) {
179                 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
180                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
181                 my $res = $main::job_db->exec_statement($sql_statement);
182         }
184         &main::create_packages_list_db;
186         my @out_msg_l = ( $out_msg );
187         return @out_msg_l;
191 sub get_login_usr_for_client {
192     my ($msg, $msg_hash, $session_id) = @_ ;
193     my $header = @{$msg_hash->{'header'}}[0];
194     my $source = @{$msg_hash->{'source'}}[0];
195     my $target = @{$msg_hash->{'target'}}[0];
196     my $client = @{$msg_hash->{'client'}}[0];
198     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
199     if( defined $jobdb_id) {
200         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
201         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
202         my $res = $main::job_db->exec_statement($sql_statement);
203     }
205     $header =~ s/^gosa_//;
207     my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$client' OR macaddress LIKE '$client'";
208     my $res = $main::known_clients_db->select_dbentry($sql_statement);
210     my $out_msg = "<xml><header>$header</header><source>$target</source><target>$source</target>";
211     $out_msg .= &db_res2xml($res);
212     $out_msg .= "</xml>";
214     my @out_msg_l = ( $out_msg );
215     return @out_msg_l;
219 sub get_client_for_login_usr {
220     my ($msg, $msg_hash, $session_id) = @_ ;
221     my $header = @{$msg_hash->{'header'}}[0];
222     my $source = @{$msg_hash->{'source'}}[0];
223     my $target = @{$msg_hash->{'target'}}[0];
225     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
226     if( defined $jobdb_id) {
227         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
228         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
229         my $res = $main::job_db->exec_statement($sql_statement);
230     }
232     my $usr = @{$msg_hash->{'usr'}}[0];
233     $header =~ s/^gosa_//;
235     my $sql_statement = "SELECT * FROM known_clients WHERE login LIKE '%$usr%'";
236     my $res = $main::known_clients_db->select_dbentry($sql_statement);
238     my $out_msg = "<xml><header>$header</header><source>$target</source><target>$source</target>";
239     $out_msg .= &db_res2xml($res);
240     $out_msg .= "</xml>";
241     my @out_msg_l = ( $out_msg );
242     return @out_msg_l;
247 sub ping {
248     my ($msg, $msg_hash, $session_id) = @_ ;
249     my $header = @{$msg_hash->{header}}[0];
250     my $target = @{$msg_hash->{target}}[0];
251     my $source = @{$msg_hash->{source}}[0];
252     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
253     my $error = 0;
254     my $answer_msg;
255     my ($sql, $res);
257     if( defined $jobdb_id) {
258         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
259         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
260         my $res = $main::job_db->exec_statement($sql_statement);
261     }
263     # send message
264     $sql = "SELECT * FROM $main::known_clients_tn WHERE ((hostname='$target') || (macaddress LIKE '$target'))"; 
265     $res = $main::known_clients_db->exec_statement($sql);
267     # sanity check of db result
268     my ($host_name, $host_key);
269     if ((defined $res) && (@$res > 0) && @{@$res[0]} > 0) {
270         $host_name = @{@$res[0]}[0];
271         $host_key = @{@$res[0]}[2];
272     } else {
273         &main::daemon_log("$session_id ERROR: cannot determine host_name and host_key from known_clients_db at function ping\n$msg", 1);
274         my %data = ( 'answer_xml'  => 'host not found in known_clients_db' );
275         $answer_msg = &build_msg("got_ping_error", $target, $source, \%data);
276         $error = 1;
277     }
279     if (not $error) {
280         my $client_hash = &create_xml_hash("ping", $main::server_address, $host_name);
281         &add_content2xml_hash($client_hash, 'session_id', $session_id); 
282         my $client_msg = &create_xml_string($client_hash);
283         &main::send_msg_to_target($client_msg, $host_name, $host_key, $header, $session_id);
285         my $message_id;
286         my $i = 0;
287         while (1) {
288             $i++;
289             $sql = "SELECT * FROM $main::incoming_tn WHERE headertag='answer_$session_id'";
290             $res = $main::incoming_db->exec_statement($sql);
291             if (ref @$res[0] eq "ARRAY") { 
292                 $message_id = @{@$res[0]}[0];
293                 last;
294             }
296             # do not run into a endless loop
297             if ($i > 100) { last; }
298             usleep(100000);
299         }
301         # if an answer to the question exists
302         if (defined $message_id) {
303             my $answer_xml = @{@$res[0]}[3];
304             my %data = ( 'answer_xml'  => 'bin noch da' );
305             $answer_msg = &build_msg("got_ping", $target, $source, \%data);
306             my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
307             if (defined $forward_to_gosa){
308                 $answer_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
309             }
310             $sql = "DELETE FROM $main::incoming_tn WHERE id=$message_id"; 
311             $res = $main::incoming_db->exec_statement($sql);
312         }
314     }
316     return ( $answer_msg );
321 sub gen_smb_hash {
322      my ($msg, $msg_hash, $session_id) = @_ ;
323      my $source = @{$msg_hash->{source}}[0];
324      my $target = @{$msg_hash->{target}}[0];
325      my $password = @{$msg_hash->{password}}[0];
327      my %data= ('hash' => join(q[:], ntlmgen $password));
328      my $out_msg = &build_msg("gen_smb_hash", $target, $source, \%data );
329      my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
330      if (defined $forward_to_gosa) {
331          $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
332      }
334      return ( $out_msg );
338 sub network_completition {
339      my ($msg, $msg_hash, $session_id) = @_ ;
340      my $source = @{$msg_hash->{source}}[0];
341      my $target = @{$msg_hash->{target}}[0];
342      my $name = @{$msg_hash->{hostname}}[0];
344      # Can we resolv the name?
345      my %data;
346      if (inet_aton($name)){
347              my $address = inet_ntoa(inet_aton($name));
348              my $p = Net::Ping->new('tcp');
349              my $mac= "";
350              if ($p->ping($address, 1)){
351                $mac = Net::ARP::arp_lookup("", $address);
352              }
354              %data= ('ip' => $address, 'mac' => $mac);
355      } else {
356              %data= ('ip' => '', 'mac' => '');
357      }
359      my $out_msg = &build_msg("network_completition", $target, $source, \%data );
360      my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
361      if (defined $forward_to_gosa) {
362          $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
363      }
365      return ( $out_msg );
369 sub detect_hardware {
370     my ($msg, $msg_hash, $session_id) = @_ ;
371     # just forward msg to client, but dont forget to split off 'gosa_' in header
372     my $source = @{$msg_hash->{source}}[0];
373     my $target = @{$msg_hash->{target}}[0];
374     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
375     if( defined $jobdb_id) {
376         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
377         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
378         my $res = $main::job_db->exec_statement($sql_statement);
379     }
381     my $out_hash = &create_xml_hash("detect_hardware", $source, $target);
382     if( defined $jobdb_id ) { 
383         &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id); 
384     }
385     my $out_msg = &create_xml_string($out_hash);
387     my @out_msg_l = ( $out_msg );
388     return @out_msg_l;
393 sub trigger_reload_ldap_config {
394     my ($msg, $msg_hash, $session_id) = @_ ;
395     my $target = @{$msg_hash->{target}}[0];
397     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
398     if( defined $jobdb_id) {
399         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
400         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
401         my $res = $main::job_db->exec_statement($sql_statement);
402     }
404         my $out_msg = &ClientPackages::new_ldap_config($target, $session_id);
405         my @out_msg_l = ( $out_msg );
407     return @out_msg_l;
411 sub set_activated_for_installation {
412     my ($msg, $msg_hash, $session_id) = @_;
413     my $header = @{$msg_hash->{header}}[0];
414     my $source = @{$msg_hash->{source}}[0];
415     my $target = @{$msg_hash->{target}}[0];
416         my @out_msg_l;
418         # update status of job 
419     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
420     if( defined $jobdb_id) {
421         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
422         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
423         my $res = $main::job_db->exec_statement($sql_statement);
424     }
426         # create set_activated_for_installation message for delivery
427     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $target);
428     if( defined $jobdb_id ) { 
429         &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id); 
430     }
431     my $out_msg = &create_xml_string($out_hash);
432         push(@out_msg_l, $out_msg); 
434     return @out_msg_l;
438 sub trigger_action_faireboot {
439     my ($msg, $msg_hash, $session_id) = @_;
440     my $macaddress = @{$msg_hash->{macaddress}}[0];
441     my $source = @{$msg_hash->{source}}[0];
443     my @out_msg_l;
444     $msg =~ s/<header>gosa_trigger_action_faireboot<\/header>/<header>trigger_action_faireboot<\/header>/;
445     push(@out_msg_l, $msg);
447     &main::change_goto_state('locked', \@{$msg_hash->{macaddress}}, $session_id);
448         &main::change_fai_state('install', \@{$msg_hash->{macaddress}}, $session_id); 
450     # set job to status 'done', job will be deleted automatically
451     my $sql_statement = "UPDATE $main::job_queue_tn ".
452         "SET status='done', modified='1'".
453         "WHERE (macaddress='$macaddress' AND status='processing')";
454     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
455     my $res = $main::job_db->update_dbentry( $sql_statement );
457     return @out_msg_l;
461 sub trigger_action_lock {
462     my ($msg, $msg_hash, $session_id) = @_;
463     my $macaddress = @{$msg_hash->{macaddress}}[0];
464     my $source = @{$msg_hash->{source}}[0];
466     &main::change_goto_state('locked', \@{$msg_hash->{macaddress}}, $session_id);
467     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
468     if( defined $jobdb_id) {
469         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
470         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
471         my $res = $main::job_db->exec_statement($sql_statement);
472     }
473                                              
474     my @out_msg_l;
475     return @out_msg_l;
479 sub trigger_action_activate {
480     my ($msg, $msg_hash, $session_id) = @_;
481     my $macaddress = @{$msg_hash->{macaddress}}[0];
482     my $source = @{$msg_hash->{source}}[0];
484     &main::change_goto_state('active', \@{$msg_hash->{macaddress}}, $session_id);
485     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
486     if( defined $jobdb_id) {
487         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
488         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
489         my $res = $main::job_db->exec_statement($sql_statement);
490     }
491                                              
492     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $macaddress);
493     if( exists $msg_hash->{'jobdb_id'} ) { 
494         &add_content2xml_hash($out_hash, 'jobdb_id', @{$msg_hash->{'jobdb_id'}}[0]); 
495     }
496     my $out_msg = &create_xml_string($out_hash);
498     return ( $out_msg );
502 sub trigger_action_localboot {
503     my ($msg, $msg_hash, $session_id) = @_;
504     $msg =~ s/<header>gosa_trigger_action_localboot<\/header>/<header>trigger_action_localboot<\/header>/;
505     &main::change_fai_state('localboot', \@{$msg_hash->{macaddress}}, $session_id);
506     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
507     if( defined $jobdb_id) {
508         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
509         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
510         my $res = $main::job_db->exec_statement($sql_statement);
511     }
513     my @out_msg_l = ($msg);  
514     return @out_msg_l;
518 sub trigger_action_halt {
519     my ($msg, $msg_hash, $session_id) = @_;
520     $msg =~ s/<header>gosa_trigger_action_halt<\/header>/<header>trigger_action_halt<\/header>/;
522     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
523     if( defined $jobdb_id) {
524         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
525         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
526         my $res = $main::job_db->exec_statement($sql_statement);
527     }
529     my @out_msg_l = ($msg);  
530     return @out_msg_l;
534 sub trigger_action_reboot {
535     my ($msg, $msg_hash, $session_id) = @_;
536     $msg =~ s/<header>gosa_trigger_action_reboot<\/header>/<header>trigger_action_reboot<\/header>/;
538     &main::change_fai_state('reboot', \@{$msg_hash->{macaddress}}, $session_id);
539     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
540     if( defined $jobdb_id) {
541         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
542         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
543         my $res = $main::job_db->exec_statement($sql_statement);
544     }
546     my @out_msg_l = ($msg);  
547     return @out_msg_l;
551 sub trigger_action_memcheck {
552     my ($msg, $msg_hash, $session_id) = @_ ;
553     $msg =~ s/<header>gosa_trigger_action_memcheck<\/header>/<header>trigger_action_memcheck<\/header>/;
555     &main::change_fai_state('memcheck', \@{$msg_hash->{macaddress}}, $session_id);
556     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
557     if( defined $jobdb_id) {
558         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
559         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
560         my $res = $main::job_db->exec_statement($sql_statement);
561     }
563     my @out_msg_l = ($msg);  
564     return @out_msg_l;
568 sub trigger_action_reinstall {
569     my ($msg, $msg_hash, $session_id) = @_;
570     $msg =~ s/<header>gosa_trigger_action_reinstall<\/header>/<header>trigger_action_reinstall<\/header>/;
572     &main::change_fai_state('reinstall', \@{$msg_hash->{macaddress}}, $session_id);
574     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
575     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
576     my @out_msg_l = ($wake_msg, $msg);  
577     return @out_msg_l;
581 sub trigger_action_update {
582     my ($msg, $msg_hash, $session_id) = @_;
583     $msg =~ s/<header>gosa_trigger_action_update<\/header>/<header>trigger_action_update<\/header>/;
585     &main::change_fai_state('update', \@{$msg_hash->{macaddress}}, $session_id);
587     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
588     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
589     my @out_msg_l = ($wake_msg, $msg);  
590     return @out_msg_l;
594 sub trigger_action_instant_update {
595     my ($msg, $msg_hash, $session_id) = @_;
596     $msg =~ s/<header>gosa_trigger_action_instant_update<\/header>/<header>trigger_action_instant_update<\/header>/;
598     &main::change_fai_state('update', \@{$msg_hash->{macaddress}}, $session_id);
600     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
601     if( defined $jobdb_id) {
602         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
603         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
604         my $res = $main::job_db->exec_statement($sql_statement);
605     }
607     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
608     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
609     my @out_msg_l = ($wake_msg, $msg);  
610     return @out_msg_l;
614 sub trigger_action_sysinfo {
615     my ($msg, $msg_hash, $session_id) = @_;
616     $msg =~ s/<header>gosa_trigger_action_sysinfo<\/header>/<header>trigger_action_sysinfo<\/header>/;
618     &main::change_fai_state('sysinfo', \@{$msg_hash->{macaddress}}, $session_id);
619     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
620     if( defined $jobdb_id) {
621         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
622         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
623         my $res = $main::job_db->exec_statement($sql_statement);
624     }
626     my @out_msg_l = ($msg);  
627     return @out_msg_l;
631 sub new_key_for_client {
632     my ($msg, $msg_hash, $session_id) = @_;
634     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
635     if( defined $jobdb_id) {
636         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
637         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
638         my $res = $main::job_db->exec_statement($sql_statement);
639     }
640     
641     $msg =~ s/<header>gosa_new_key_for_client<\/header>/<header>new_key<\/header>/;
642     my @out_msg_l = ($msg);  
643     return @out_msg_l;
647 sub trigger_action_rescan {
648     my ($msg, $msg_hash, $session_id) = @_;
650     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
651     if( defined $jobdb_id) {
652         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
653         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
654         my $res = $main::job_db->exec_statement($sql_statement);
655     }
658     $msg =~ s/<header>gosa_trigger_action_rescan<\/header>/<header>detect_hardware<header>/;
659     my @out_msg_l = ($msg);  
660     return @out_msg_l;
664 sub trigger_action_wake {
665     my ($msg, $msg_hash, $session_id) = @_;
666     
667     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
668     if( defined $jobdb_id) {
669         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
670         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
671         my $res = $main::job_db->exec_statement($sql_statement);
672     }
674     # build out message
675     my $out_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
676     foreach (@{$msg_hash->{target}}) {
677         &add_content2xml_hash($out_hash, 'macAddress', $_);
678     }
679     my $out_msg = &create_xml_string($out_hash);
680     
681     # invoke trigger wake for this gosa-si-server
682     &main::server_server_com::trigger_wake($out_msg, $out_hash, $session_id);
684     # send trigger wake to all other gosa-si-server
685     my @out_msg_l = ($out_msg);  
686     return @out_msg_l;
690 sub get_available_kernel {
691         my ($msg, $msg_hash, $session_id) = @_;
693         my $source = @{$msg_hash->{'source'}}[0];
694         my $target = @{$msg_hash->{'target'}}[0];
695         my $release= @{$msg_hash->{'release'}}[0];
697         my @kernel;
698         # Get Kernel packages for release
699         my $sql_statement = "SELECT * FROM $main::packages_list_tn WHERE distribution='$release' AND package LIKE 'linux\-image\-%'";
700         my $res_hash = $main::packages_list_db->select_dbentry($sql_statement);
701         my %data;
702         my $i=1;
704         foreach my $package (keys %{$res_hash}) {
705                 $data{"answer".$i++}= $data{"answer".$i++}= ${$res_hash}{$package}->{'package'};
706         }
707         $data{"answer".$i++}= "default";
709         my $out_msg = &build_msg("get_available_kernel", $target, $source, \%data);
710         my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
711         if (defined $forward_to_gosa) {
712             $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
713         }
715         return ( $out_msg );
719 sub trigger_activate_new {
720         my ($msg, $msg_hash, $session_id) = @_;
722         my $source = @{$msg_hash->{'source'}}[0];
723         my $target = @{$msg_hash->{'target'}}[0];
724         my $header= @{$msg_hash->{'header'}}[0];
725         my $mac= (defined($msg_hash->{'mac'}))?@{$msg_hash->{'mac'}}[0]:undef;
726         my $ogroup= (defined($msg_hash->{'ogroup'}))?@{$msg_hash->{'ogroup'}}[0]:undef;
727         my $timestamp= (defined($msg_hash->{'timestamp'}))?@{$msg_hash->{'timestamp'}}[0]:undef;
728         my $base= (defined($msg_hash->{'base'}))?@{$msg_hash->{'base'}}[0]:undef;
729         my $hostname= (defined($msg_hash->{'fqdn'}))?@{$msg_hash->{'fqdn'}}[0]:undef;
730         my $ip_address= (defined($msg_hash->{'ip'}))?@{$msg_hash->{'ip'}}[0]:undef;
731         my $dhcp_statement= (defined($msg_hash->{'dhcp'}))?@{$msg_hash->{'dhcp'}}[0]:undef;
732         my $jobdb_id= (defined($msg_hash->{'jobdb_id'}))?@{$msg_hash->{'jobdb_id'}}[0]:undef;
734         my $ldap_handle = &main::get_ldap_handle();
735         my $ldap_entry;
736         my $ogroup_entry;
737         my $changed_attributes_counter = 0;
738         
739         eval {
741                 my $ldap_mesg= $ldap_handle->search(
742                         base => $main::ldap_base,
743                         scope => 'sub',
744                         filter => "(&(objectClass=gosaGroupOfnames)(cn=$ogroup))",
745                 );
746                 if($ldap_mesg->count == 1) {
747                         $ogroup_entry= $ldap_mesg->pop_entry();
748                 } elsif ($ldap_mesg->count == 0) {
749                         &main::daemon_log("ERROR: A GosaGroupOfNames with cn '$ogroup' was not found in base '".$main::ldap_base."'!", 1);
750                 } else {
751                         &main::daemon_log("ERROR: More than one ObjectGroups with cn '$ogroup' was found in base '".$main::ldap_base."'!", 1);
752                 }
754                 # build the base, use optional base parameter or take it from ogroup
755                 if(!(defined($base) && (length($base) > 0))) {
756                                 # Subtract the ObjectGroup cn
757                                 $base = $1 if $ogroup_entry->dn =~ /cn=$ogroup,ou=groups,(.*)$/;
758                 }
760                 # prepend ou=systems (configurable through config)
761                 $base = $main::new_systems_ou.",".$base;
763                 # Search for an existing entry (should be in ou=incoming)
764                 $ldap_mesg= $ldap_handle->search(
765                         base => $main::ldap_base,
766                         scope => 'sub',
767                         filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
768                 );
770                 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
772                 if($ldap_mesg->count == 1) {
773                         &main::daemon_log("DEBUG: One system with mac address '$mac' was found in base '".$main::ldap_base."'!", 6);
774                         # Get the entry from LDAP
775                         $ldap_entry= $ldap_mesg->pop_entry();
777                         if(!($ldap_entry->dn() eq "cn=".$ldap_entry->get_value('cn').",$base")) {
778                                 # Move the entry to the new ou
779                                 $ldap_entry->changetype('moddn');
780                                 $ldap_entry->add(
781                                         newrdn => "cn=".$ldap_entry->get_value('cn'),
782                                         deleteoldrdn => 1,
783                                         newsuperior => $base,
784                                 );
785                         }
787                 } 
789                 $ldap_mesg= $ldap_handle->search(
790                         base => $main::ldap_base,
791                         scope => 'sub',
792                         filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
793                 );
795                 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
797                 if($ldap_mesg->count == 1) {
798                         $ldap_entry= $ldap_mesg->pop_entry();
799                         # Check for needed objectClasses
800                         my $oclasses = $ldap_entry->get_value('objectClass', asref => 1);
801                         foreach my $oclass ("FAIobject", "GOhard") {
802                                 if(!(scalar grep $_ eq $oclass, map {$_ => 1} @$oclasses)) {
803                                         &main::daemon_log("Adding objectClass $oclass", 1);
804                                         $ldap_entry->add(
805                                                 objectClass => $oclass,
806                                         );
807                                         my $oclass_result = $ldap_entry->update($ldap_handle);
808                                 }
809                         }
811                         # Set FAIstate
812                         if(defined($ldap_entry->get_value('FAIstate'))) {
813                                 if(!($ldap_entry->get_value('FAIstate') eq 'install')) {
814                                         $ldap_entry->replace(
815                                                 'FAIstate' => 'install'
816                                         );
817                                         my $replace_result = $ldap_entry->update($ldap_handle);
818                                 }
819                         } else {
820                                 $ldap_entry->add(
821                                         'FAIstate' => 'install'
822                                 );
823                                 my $add_result = $ldap_entry->update($ldap_handle);
824                         }
827                 } elsif ($ldap_mesg->count == 0) {
828                         # TODO: Create a new entry
829                         # $ldap_entry = Net::LDAP::Entry->new();
830                         # $ldap_entry->dn("cn=$mac,$base");
831                         &main::daemon_log("WARNING: No System with mac address '$mac' was found in base '".$main::ldap_base."'! Re-queuing job.", 4);
832                         $main::job_db->exec_statement("UPDATE jobs SET status = 'waiting', timestamp = '".&get_time()."' WHERE id = $jobdb_id");
833                 } else {
834                         &main::daemon_log("ERROR: More than one system with mac address '$mac' was found in base '".$main::ldap_base."'!", 1);
835                 }
837                 # Add to ObjectGroup
838                 if(!(scalar grep $_, map {$_ => 1} $ogroup_entry->get_value('member', asref => 1))) {
839                         $ogroup_entry->add (
840                                 'member' => $ldap_entry->dn(),
841                         );
842                         my $ogroup_result = $ogroup_entry->update($ldap_handle);
843                         if ($ogroup_result->code() != 0) {
844                                 &main::daemon_log("ERROR: Updating the ObjectGroup '$ogroup' failed (code '".$ogroup_result->code()."') with '".$ogroup_result->{'errorMessage'}."'!", 1);
845                         }
846                 }
848                 # Finally set gotoMode to active
849                 if(defined($ldap_entry->get_value('gotoMode'))) {
850                         if(!($ldap_entry->get_value('gotoMode') eq 'active')) {
851                                 $ldap_entry->replace(
852                                         'gotoMode' => 'active'
853                                 );
854                                 my $activate_result = $ldap_entry->update($ldap_handle);
855                                 if ($activate_result->code() != 0) {
856                                         &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
857                                 }
858                         }
859                 } else {
860                         $ldap_entry->add(
861                                 'gotoMode' => 'active'
862                         );
863                         my $activate_result = $ldap_entry->update($ldap_handle);
864                         if ($activate_result->code() != 0) {
865                                 &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
866                         }
867                 }
868         };
869         if($@) {
870                 &main::daemon_log("ERROR: activate_new failed with '$@'!", 1);
871         }
873         # Delete job
874         $main::job_db->exec_statement("DELETE FROM jobs WHERE id =  $jobdb_id");
876         # create set_activated_for_installation message for delivery
877     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $target);
878     my $out_msg = &create_xml_string($out_hash);
879         my @out_msg_l = ($out_msg);
881     return @out_msg_l;
885 sub get_dak_keyring {
886     my ($msg, $msg_hash) = @_;
887     my $source = @{$msg_hash->{'source'}}[0];
888     my $target = @{$msg_hash->{'target'}}[0];
889     my $header= @{$msg_hash->{'header'}}[0];
890     my $session_id = @{$msg_hash->{'session_id'}}[0];
892     # build return message with twisted target and source
893     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
894     &add_content2xml_hash($out_hash, "session_id", $session_id);
896     my @keys;
897     my %data;
899     my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
901     my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
902     my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --keyring $keyring";
904     # Check if the keyrings are in place and readable
905     if(
906         &run_as($main::dak_user, "test -r $keyring")->{'resultCode'} != 0
907     ) {
908         &add_content2xml_hash($out_hash, "error", "DAK Keyring is not readable");
909     } else {
910         my $command = "$gpg --list-keys";
911         my $output = &run_as($main::dak_user, $command);
912         &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
914         my $i=0;
915         foreach (@{$output->{'output'}}) {
916             if ($_ =~ m/^pub\s.*$/) {
917                 ($keys[$i]->{'pub'}->{'length'}, $keys[$i]->{'pub'}->{'uid'}, $keys[$i]->{'pub'}->{'created'}) = ($1, $2, $3)
918                 if $_ =~ m/^pub\s*?(\w*?)\/(\w*?)\s(\d{4}-\d{2}-\d{2})/;
919                 $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})\]/;
920                 $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})\]/;
921             } elsif ($_ =~ m/^sub\s.*$/) {
922                 ($keys[$i]->{'sub'}->{'length'}, $keys[$i]->{'sub'}->{'uid'}, $keys[$i]->{'sub'}->{'created'}) = ($1, $2, $3)
923                 if $_ =~ m/^sub\s*?(\w*?)\/(\w*?)\s(\d{4}-\d{2}-\d{2})/;
924                 $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})\]/;
925                 $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})\]/;
926             } elsif ($_ =~ m/^uid\s.*$/) {
927                 push @{$keys[$i]->{'uid'}}, $1 if $_ =~ m/^uid\s*?([^\s].*?)$/;
928             } elsif ($_ =~ m/^$/) {
929                 $i++;
930             }
931         }
932     }
934     my $i=0;
935     foreach my $key (@keys) {
936         #    &main::daemon_log(Dumper($key));
937         &add_content2xml_hash($out_hash, "answer".$i++, $key);
938     }
939     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
940     if (defined $forward_to_gosa) {
941         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
942     }
943     return &create_xml_string($out_hash);
947 sub import_dak_key {
948     my ($msg, $msg_hash) = @_;
949     my $source = @{$msg_hash->{'source'}}[0];
950     my $target = @{$msg_hash->{'target'}}[0];
951     my $header= @{$msg_hash->{'header'}}[0];
952     my $session_id = @{$msg_hash->{'session_id'}}[0];
953     my $key = &decode_base64(@{$msg_hash->{'key'}}[0]);
955     # build return message with twisted target and source
956     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
957     &add_content2xml_hash($out_hash, "session_id", $session_id);
959     my %data;
961     my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
963     my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
964     my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --keyring $keyring";
966     # Check if the keyrings are in place and writable
967     if(
968         &run_as($main::dak_user, "test -w $keyring")->{'resultCode'} != 0
969     ) {
970         &add_content2xml_hash($out_hash, "error", "DAK Keyring is not writable");
971     } else {
972         my $keyfile;
973         open($keyfile, ">/tmp/gosa_si_tmp_dak_key");
974         print $keyfile $key;
975         close($keyfile);
976         my $command = "$gpg --import /tmp/gosa_si_tmp_dak_key";
977         my $output = &run_as($main::dak_user, $command);
978         &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
979         unlink("/tmp/gosa_si_tmp_dak_key");
981         if($output->{'resultCode'} != 0) {
982             &add_content2xml_hash($out_hash, "error", "Import of DAK key failed! Output was '".$output->{'output'}."'");
983         } else {
984             &add_content2xml_hash($out_hash, "answer", "Import of DAK key successfull! Output was '".$output->{'output'}."'");
985         }
986     }
988     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
989     if (defined $forward_to_gosa) {
990         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
991     }
992     return &create_xml_string($out_hash);
996 sub remove_dak_key {
997     my ($msg, $msg_hash) = @_;
998     my $source = @{$msg_hash->{'source'}}[0];
999     my $target = @{$msg_hash->{'target'}}[0];
1000     my $header= @{$msg_hash->{'header'}}[0];
1001     my $session_id = @{$msg_hash->{'session_id'}}[0];
1002     my $key = @{$msg_hash->{'keyid'}}[0];
1003     # build return message with twisted target and source
1004     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
1005     &add_content2xml_hash($out_hash, "session_id", $session_id);
1007     my %data;
1009     my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
1011     my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
1012     my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --homedir ".$main::dak_signing_keys_directory." --keyring $keyring";
1014     # Check if the keyrings are in place and writable
1015     if(
1016         &run_as($main::dak_user, "test -w $keyring")->{'resultCode'} != 0
1017     ) {
1018         &add_content2xml_hash($out_hash, "error", "DAK keyring is not writable");
1019     } else {
1020         # Check if the key is present in the keyring
1021         if(&run_as($main::dak_user, "$gpg --list-keys $key")->{'resultCode'} == 0) {
1022             my $command = "$gpg --batch --yes --delete-key $key";
1023             my $output = &run_as($main::dak_user, $command);
1024             &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
1025         } else {
1026             &add_content2xml_hash($out_hash, "error", "DAK key with id '$key' was not found in keyring");
1027         }
1028     }
1030     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1031     if (defined $forward_to_gosa) {
1032         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1033     }
1034     return &create_xml_string($out_hash);
1038 #sub get_dak_queue {
1039 #    my ($msg, $msg_hash, $session_id) = @_;
1040 #    my %data;
1041 #    my $source = @{$msg_hash->{'source'}}[0];
1042 #    my $target = @{$msg_hash->{'target'}}[0];
1043 #    my $header= @{$msg_hash->{'header'}}[0];
1045 #    my %data;
1047 #    foreach my $dir ("unchecked", "new", "accepted") {
1048 #        foreach my $file(<"$main::dak_queue_directory/$dir/*.changes">) {
1049 #        }
1050 #    }
1052 #    my $out_msg = &build_msg("get_dak_queue", $target, $source, \%data);
1053 #    my @out_msg_l = ($out_msg);
1054 #    return @out_msg_l;
1055 #}
1058 # vim:ts=4:shiftwidth:expandtab
1059 1;