Code

Fixed bug in dak keylist.
[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 = @{$msg_hash->{'users'}};
76         my @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];
253     my ($sql, $res);
254     my $out_msg = $msg;
255     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
256     if( defined $jobdb_id) {
257         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
258         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
259         my $res = $main::job_db->exec_statement($sql_statement);
260     }
262     # send message
263     $sql = "SELECT * FROM $main::known_clients_tn WHERE ((hostname='$target') || (macaddress LIKE '$target'))"; 
264     $res = $main::known_clients_db->exec_statement($sql);
265     my $host_name = @{@$res[0]}[0];
266     my $host_key = @{@$res[0]}[2];
268     my $client_hash = &create_xml_hash("ping", $main::server_address, $host_name);
269     &add_content2xml_hash($client_hash, 'session_id', $session_id); 
270     my $client_msg = &create_xml_string($client_hash);
271     my $error = &main::send_msg_to_target($client_msg, $host_name, $host_key, $header, $session_id);
272     #if ($error != 0) {}
274     my $message_id;
275     my $i = 0;
276     while (1) {
277         $i++;
278         $sql = "SELECT * FROM $main::incoming_tn WHERE headertag='answer_$session_id'";
279         $res = $main::incoming_db->exec_statement($sql);
280         if (ref @$res[0] eq "ARRAY") { 
281             $message_id = @{@$res[0]}[0];
282             last;
283         }
285         # do not run into a endless loop
286         if ($i > 100) { last; }
287         usleep(100000);
288     }
290     my $answer_xml = @{@$res[0]}[3];
291     my %data = ( 'answer_xml'  => 'bin noch da' );
292     my $answer_msg = &build_msg("got_ping", $target, $source, \%data);
293     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
294     if (defined $forward_to_gosa) {
295         $answer_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
296     }
298     $sql = "DELETE FROM $main::incoming_tn WHERE id=$message_id"; 
299     $res = $main::incoming_db->exec_statement($sql);
301     my @answer_msg_l = ( $answer_msg );
302     return @answer_msg_l;
307 sub gen_smb_hash {
308      my ($msg, $msg_hash, $session_id) = @_ ;
309      my $source = @{$msg_hash->{source}}[0];
310      my $target = @{$msg_hash->{target}}[0];
311      my $password = @{$msg_hash->{password}}[0];
313      my %data= ('hash' => join(q[:], ntlmgen $password));
314      my $out_msg = &build_msg("gen_smb_hash", $target, $source, \%data );
315      my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
316      if (defined $forward_to_gosa) {
317          $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
318      }
320      return ( $out_msg );
324 sub network_completition {
325      my ($msg, $msg_hash, $session_id) = @_ ;
326      my $source = @{$msg_hash->{source}}[0];
327      my $target = @{$msg_hash->{target}}[0];
328      my $name = @{$msg_hash->{hostname}}[0];
330      # Can we resolv the name?
331      my %data;
332      if (inet_aton($name)){
333              my $address = inet_ntoa(inet_aton($name));
334              my $p = Net::Ping->new('tcp');
335              my $mac= "";
336              if ($p->ping($address, 1)){
337                $mac = Net::ARP::arp_lookup("", $address);
338              }
340              %data= ('ip' => $address, 'mac' => $mac);
341      } else {
342              %data= ('ip' => '', 'mac' => '');
343      }
345      my $out_msg = &build_msg("network_completition", $target, $source, \%data );
346      my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
347      if (defined $forward_to_gosa) {
348          $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
349      }
351      return ( $out_msg );
355 sub detect_hardware {
356     my ($msg, $msg_hash, $session_id) = @_ ;
357     # just forward msg to client, but dont forget to split off 'gosa_' in header
358     my $source = @{$msg_hash->{source}}[0];
359     my $target = @{$msg_hash->{target}}[0];
360     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
361     if( defined $jobdb_id) {
362         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
363         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
364         my $res = $main::job_db->exec_statement($sql_statement);
365     }
367     my $out_hash = &create_xml_hash("detect_hardware", $source, $target);
368     if( defined $jobdb_id ) { 
369         &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id); 
370     }
371     my $out_msg = &create_xml_string($out_hash);
373     my @out_msg_l = ( $out_msg );
374     return @out_msg_l;
379 sub trigger_reload_ldap_config {
380     my ($msg, $msg_hash, $session_id) = @_ ;
381     my $target = @{$msg_hash->{target}}[0];
383     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
384     if( defined $jobdb_id) {
385         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
386         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
387         my $res = $main::job_db->exec_statement($sql_statement);
388     }
390         my $out_msg = &ClientPackages::new_ldap_config($target, $session_id);
391         my @out_msg_l = ( $out_msg );
393     return @out_msg_l;
397 sub set_activated_for_installation {
398     my ($msg, $msg_hash, $session_id) = @_;
399     my $header = @{$msg_hash->{header}}[0];
400     my $source = @{$msg_hash->{source}}[0];
401     my $target = @{$msg_hash->{target}}[0];
402         my @out_msg_l;
404         # update status of job 
405     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
406     if( defined $jobdb_id) {
407         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
408         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
409         my $res = $main::job_db->exec_statement($sql_statement);
410     }
412         # create set_activated_for_installation message for delivery
413     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $target);
414     if( defined $jobdb_id ) { 
415         &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id); 
416     }
417     my $out_msg = &create_xml_string($out_hash);
418         push(@out_msg_l, $out_msg); 
420     return @out_msg_l;
424 sub trigger_action_faireboot {
425     my ($msg, $msg_hash, $session_id) = @_;
426     my $macaddress = @{$msg_hash->{macaddress}}[0];
427     my $source = @{$msg_hash->{source}}[0];
429     my @out_msg_l;
430     $msg =~ s/<header>gosa_trigger_action_faireboot<\/header>/<header>trigger_action_faireboot<\/header>/;
431     push(@out_msg_l, $msg);
433     &main::change_goto_state('locked', \@{$msg_hash->{macaddress}}, $session_id);
434         &main::change_fai_state('install', \@{$msg_hash->{macaddress}}, $session_id); 
436     # delete all jobs from jobqueue which correspond to fai
437     my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE (macaddress='$macaddress' AND ".
438         "status='processing')";
439     $main::job_db->del_dbentry($sql_statement ); 
440                                              
441     return @out_msg_l;
445 sub trigger_action_lock {
446     my ($msg, $msg_hash, $session_id) = @_;
447     my $macaddress = @{$msg_hash->{macaddress}}[0];
448     my $source = @{$msg_hash->{source}}[0];
450     &main::change_goto_state('locked', \@{$msg_hash->{macaddress}}, $session_id);
451     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
452     if( defined $jobdb_id) {
453         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
454         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
455         my $res = $main::job_db->exec_statement($sql_statement);
456     }
457                                              
458     my @out_msg_l;
459     return @out_msg_l;
463 sub trigger_action_activate {
464     my ($msg, $msg_hash, $session_id) = @_;
465     my $macaddress = @{$msg_hash->{macaddress}}[0];
466     my $source = @{$msg_hash->{source}}[0];
468     &main::change_goto_state('active', \@{$msg_hash->{macaddress}}, $session_id);
469     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
470     if( defined $jobdb_id) {
471         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
472         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
473         my $res = $main::job_db->exec_statement($sql_statement);
474     }
475                                              
476     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $macaddress);
477     if( exists $msg_hash->{'jobdb_id'} ) { 
478         &add_content2xml_hash($out_hash, 'jobdb_id', @{$msg_hash->{'jobdb_id'}}[0]); 
479     }
480     my $out_msg = &create_xml_string($out_hash);
482     return ( $out_msg );
486 sub trigger_action_localboot {
487     my ($msg, $msg_hash, $session_id) = @_;
488     $msg =~ s/<header>gosa_trigger_action_localboot<\/header>/<header>trigger_action_localboot<\/header>/;
489     &main::change_fai_state('localboot', \@{$msg_hash->{macaddress}}, $session_id);
490     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
491     if( defined $jobdb_id) {
492         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
493         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
494         my $res = $main::job_db->exec_statement($sql_statement);
495     }
497     my @out_msg_l = ($msg);  
498     return @out_msg_l;
502 sub trigger_action_halt {
503     my ($msg, $msg_hash, $session_id) = @_;
504     $msg =~ s/<header>gosa_trigger_action_halt<\/header>/<header>trigger_action_halt<\/header>/;
506     &main::change_fai_state('halt', \@{$msg_hash->{macaddress}}, $session_id);
507     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
508     if( defined $jobdb_id) {
509         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
510         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
511         my $res = $main::job_db->exec_statement($sql_statement);
512     }
514     my @out_msg_l = ($msg);  
515     return @out_msg_l;
519 sub trigger_action_reboot {
520     my ($msg, $msg_hash, $session_id) = @_;
521     $msg =~ s/<header>gosa_trigger_action_reboot<\/header>/<header>trigger_action_reboot<\/header>/;
523     &main::change_fai_state('reboot', \@{$msg_hash->{macaddress}}, $session_id);
524     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
525     if( defined $jobdb_id) {
526         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
527         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
528         my $res = $main::job_db->exec_statement($sql_statement);
529     }
531     my @out_msg_l = ($msg);  
532     return @out_msg_l;
536 sub trigger_action_memcheck {
537     my ($msg, $msg_hash, $session_id) = @_ ;
538     $msg =~ s/<header>gosa_trigger_action_memcheck<\/header>/<header>trigger_action_memcheck<\/header>/;
540     &main::change_fai_state('memcheck', \@{$msg_hash->{macaddress}}, $session_id);
541     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
542     if( defined $jobdb_id) {
543         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
544         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
545         my $res = $main::job_db->exec_statement($sql_statement);
546     }
548     my @out_msg_l = ($msg);  
549     return @out_msg_l;
553 sub trigger_action_reinstall {
554     my ($msg, $msg_hash, $session_id) = @_;
555     $msg =~ s/<header>gosa_trigger_action_reinstall<\/header>/<header>trigger_action_reinstall<\/header>/;
557     &main::change_fai_state('reinstall', \@{$msg_hash->{macaddress}}, $session_id);
559     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
560     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
561     my @out_msg_l = ($wake_msg, $msg);  
562     return @out_msg_l;
566 sub trigger_action_update {
567     my ($msg, $msg_hash, $session_id) = @_;
568     $msg =~ s/<header>gosa_trigger_action_update<\/header>/<header>trigger_action_update<\/header>/;
570     &main::change_fai_state('update', \@{$msg_hash->{macaddress}}, $session_id);
572     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
573     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
574     my @out_msg_l = ($wake_msg, $msg);  
575     return @out_msg_l;
579 sub trigger_action_instant_update {
580     my ($msg, $msg_hash, $session_id) = @_;
581     $msg =~ s/<header>gosa_trigger_action_instant_update<\/header>/<header>trigger_action_instant_update<\/header>/;
583     &main::change_fai_state('update', \@{$msg_hash->{macaddress}}, $session_id);
585     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
586     if( defined $jobdb_id) {
587         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
588         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
589         my $res = $main::job_db->exec_statement($sql_statement);
590     }
592     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
593     my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
594     my @out_msg_l = ($wake_msg, $msg);  
595     return @out_msg_l;
599 sub trigger_action_sysinfo {
600     my ($msg, $msg_hash, $session_id) = @_;
601     $msg =~ s/<header>gosa_trigger_action_sysinfo<\/header>/<header>trigger_action_sysinfo<\/header>/;
603     &main::change_fai_state('sysinfo', \@{$msg_hash->{macaddress}}, $session_id);
604     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
605     if( defined $jobdb_id) {
606         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
607         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
608         my $res = $main::job_db->exec_statement($sql_statement);
609     }
611     my @out_msg_l = ($msg);  
612     return @out_msg_l;
616 sub new_key_for_client {
617     my ($msg, $msg_hash, $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     }
625     
626     $msg =~ s/<header>gosa_new_key_for_client<\/header>/<header>new_key<\/header>/;
627     my @out_msg_l = ($msg);  
628     return @out_msg_l;
632 sub trigger_action_rescan {
633     my ($msg, $msg_hash, $session_id) = @_;
635     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
636     if( defined $jobdb_id) {
637         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
638         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
639         my $res = $main::job_db->exec_statement($sql_statement);
640     }
643     $msg =~ s/<header>gosa_trigger_action_rescan<\/header>/<header>trigger_action_rescan<\/header>/;
644     my @out_msg_l = ($msg);  
645     return @out_msg_l;
649 sub trigger_action_wake {
650     my ($msg, $msg_hash, $session_id) = @_;
652     my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
653     if( defined $jobdb_id) {
654         my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
655         &main::daemon_log("$session_id DEBUG: $sql_statement", 7); 
656         my $res = $main::job_db->exec_statement($sql_statement);
657     }
660     my %data = ( 'macAddress'  => \@{$msg_hash->{macaddress}} );
661     my $out_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
662     my @out_msg_l = ($out_msg);  
663     return @out_msg_l;
667 sub get_available_kernel {
668         my ($msg, $msg_hash, $session_id) = @_;
670         my $source = @{$msg_hash->{'source'}}[0];
671         my $target = @{$msg_hash->{'target'}}[0];
672         my $release= @{$msg_hash->{'release'}}[0];
674         my @kernel;
675         # Get Kernel packages for release
676         my $sql_statement = "SELECT * FROM $main::packages_list_tn WHERE distribution='$release' AND package LIKE 'linux\-image\-%'";
677         my $res_hash = $main::packages_list_db->select_dbentry($sql_statement);
678         my %data;
679         my $i=1;
681         foreach my $package (keys %{$res_hash}) {
682                 $data{"answer".$i++}= $data{"answer".$i++}= ${$res_hash}{$package}->{'package'};
683         }
684         $data{"answer".$i++}= "default";
686         my $out_msg = &build_msg("get_available_kernel", $target, $source, \%data);
687         my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
688         if (defined $forward_to_gosa) {
689             $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
690         }
692         return ( $out_msg );
696 sub trigger_activate_new {
697         my ($msg, $msg_hash, $session_id) = @_;
699         my $source = @{$msg_hash->{'source'}}[0];
700         my $target = @{$msg_hash->{'target'}}[0];
701         my $header= @{$msg_hash->{'header'}}[0];
702         my $mac= (defined($msg_hash->{'mac'}))?@{$msg_hash->{'mac'}}[0]:undef;
703         my $ogroup= (defined($msg_hash->{'ogroup'}))?@{$msg_hash->{'ogroup'}}[0]:undef;
704         my $timestamp= (defined($msg_hash->{'timestamp'}))?@{$msg_hash->{'timestamp'}}[0]:undef;
705         my $base= (defined($msg_hash->{'base'}))?@{$msg_hash->{'base'}}[0]:undef;
706         my $hostname= (defined($msg_hash->{'fqdn'}))?@{$msg_hash->{'fqdn'}}[0]:undef;
707         my $ip_address= (defined($msg_hash->{'ip'}))?@{$msg_hash->{'ip'}}[0]:undef;
708         my $dhcp_statement= (defined($msg_hash->{'dhcp'}))?@{$msg_hash->{'dhcp'}}[0]:undef;
709         my $jobdb_id= (defined($msg_hash->{'jobdb_id'}))?@{$msg_hash->{'jobdb_id'}}[0]:undef;
711         my $ldap_handle = &main::get_ldap_handle();
712         my $ldap_entry;
713         my $ogroup_entry;
714         my $changed_attributes_counter = 0;
715         
716         eval {
718                 my $ldap_mesg= $ldap_handle->search(
719                         base => $main::ldap_base,
720                         scope => 'sub',
721                         filter => "(&(objectClass=gosaGroupOfnames)(cn=$ogroup))",
722                 );
723                 if($ldap_mesg->count == 1) {
724                         $ogroup_entry= $ldap_mesg->pop_entry();
725                 } elsif ($ldap_mesg->count == 0) {
726                         &main::daemon_log("ERROR: A GosaGroupOfNames with cn '$ogroup' was not found in base '".$main::ldap_base."'!", 1);
727                 } else {
728                         &main::daemon_log("ERROR: More than one ObjectGroups with cn '$ogroup' was found in base '".$main::ldap_base."'!", 1);
729                 }
731                 # build the base, use optional base parameter or take it from ogroup
732                 if(!(defined($base) && (length($base) > 0))) {
733                                 # Subtract the ObjectGroup cn
734                                 $base = $1 if $ogroup_entry->dn =~ /cn=$ogroup,ou=groups,(.*)$/;
735                 }
737                 # prepend ou=systems (configurable through config)
738                 $base = $main::new_systems_ou.",".$base;
740                 # Search for an existing entry (should be in ou=incoming)
741                 $ldap_mesg= $ldap_handle->search(
742                         base => $main::ldap_base,
743                         scope => 'sub',
744                         filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
745                 );
747                 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
749                 if($ldap_mesg->count == 1) {
750                         &main::daemon_log("DEBUG: One system with mac address '$mac' was found in base '".$main::ldap_base."'!", 6);
751                         # Get the entry from LDAP
752                         $ldap_entry= $ldap_mesg->pop_entry();
754                         if(!($ldap_entry->dn() eq "cn=".$ldap_entry->get_value('cn').",$base")) {
755                                 # Move the entry to the new ou
756                                 $ldap_entry->changetype('moddn');
757                                 $ldap_entry->add(
758                                         newrdn => "cn=".$ldap_entry->get_value('cn'),
759                                         deleteoldrdn => 1,
760                                         newsuperior => $base,
761                                 );
762                         }
764                 } 
766                 $ldap_mesg= $ldap_handle->search(
767                         base => $main::ldap_base,
768                         scope => 'sub',
769                         filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
770                 );
772                 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
774                 if($ldap_mesg->count == 1) {
775                         $ldap_entry= $ldap_mesg->pop_entry();
776                         # Check for needed objectClasses
777                         my $oclasses = $ldap_entry->get_value('objectClass', asref => 1);
778                         foreach my $oclass ("FAIobject", "GOhard") {
779                                 if(!(scalar grep $_ eq $oclass, map {$_ => 1} @$oclasses)) {
780                                         &main::daemon_log("Adding objectClass $oclass", 1);
781                                         $ldap_entry->add(
782                                                 objectClass => $oclass,
783                                         );
784                                         my $oclass_result = $ldap_entry->update($ldap_handle);
785                                 }
786                         }
788                         # Set FAIstate
789                         if(defined($ldap_entry->get_value('FAIstate'))) {
790                                 if(!($ldap_entry->get_value('FAIstate') eq 'install')) {
791                                         $ldap_entry->replace(
792                                                 'FAIstate' => 'install'
793                                         );
794                                         my $replace_result = $ldap_entry->update($ldap_handle);
795                                 }
796                         } else {
797                                 $ldap_entry->add(
798                                         'FAIstate' => 'install'
799                                 );
800                                 my $add_result = $ldap_entry->update($ldap_handle);
801                         }
804                 } elsif ($ldap_mesg->count == 0) {
805                         # TODO: Create a new entry
806                         # $ldap_entry = Net::LDAP::Entry->new();
807                         # $ldap_entry->dn("cn=$mac,$base");
808                         &main::daemon_log("WARNING: No System with mac address '$mac' was found in base '".$main::ldap_base."'! Re-queuing job.", 4);
809                         $main::job_db->exec_statement("UPDATE jobs SET status = 'waiting', timestamp = '".&get_time()."' WHERE id = $jobdb_id");
810                 } else {
811                         &main::daemon_log("ERROR: More than one system with mac address '$mac' was found in base '".$main::ldap_base."'!", 1);
812                 }
814                 # Add to ObjectGroup
815                 if(!(scalar grep $_, map {$_ => 1} $ogroup_entry->get_value('member', asref => 1))) {
816                         $ogroup_entry->add (
817                                 'member' => $ldap_entry->dn(),
818                         );
819                         my $ogroup_result = $ogroup_entry->update($ldap_handle);
820                         if ($ogroup_result->code() != 0) {
821                                 &main::daemon_log("ERROR: Updating the ObjectGroup '$ogroup' failed (code '".$ogroup_result->code()."') with '".$ogroup_result->{'errorMessage'}."'!", 1);
822                         }
823                 }
825                 # Finally set gotoMode to active
826                 if(defined($ldap_entry->get_value('gotoMode'))) {
827                         if(!($ldap_entry->get_value('gotoMode') eq 'active')) {
828                                 $ldap_entry->replace(
829                                         'gotoMode' => 'active'
830                                 );
831                                 my $activate_result = $ldap_entry->update($ldap_handle);
832                                 if ($activate_result->code() != 0) {
833                                         &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
834                                 }
835                         }
836                 } else {
837                         $ldap_entry->add(
838                                 'gotoMode' => 'active'
839                         );
840                         my $activate_result = $ldap_entry->update($ldap_handle);
841                         if ($activate_result->code() != 0) {
842                                 &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
843                         }
844                 }
845         };
846         if($@) {
847                 &main::daemon_log("ERROR: activate_new failed with '$@'!", 1);
848         }
850         # Delete job
851         $main::job_db->exec_statement("DELETE FROM jobs WHERE id =  $jobdb_id");
853         # create set_activated_for_installation message for delivery
854     my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $target);
855     my $out_msg = &create_xml_string($out_hash);
856         my @out_msg_l = ($out_msg);
858     return @out_msg_l;
862 sub get_dak_keyring {
863     my ($msg, $msg_hash) = @_;
864     my $source = @{$msg_hash->{'source'}}[0];
865     my $target = @{$msg_hash->{'target'}}[0];
866     my $header= @{$msg_hash->{'header'}}[0];
867     my $session_id = @{$msg_hash->{'session_id'}}[0];
869     # build return message with twisted target and source
870     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
871     &add_content2xml_hash($out_hash, "session_id", $session_id);
873     my @keys;
874     my %data;
876     my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
878     my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
879     my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --keyring $keyring";
881     # Check if the keyrings are in place and readable
882     if(
883         &run_as($main::dak_user, "test -r $keyring")->{'resultCode'} != 0
884     ) {
885         &add_content2xml_hash($out_hash, "error", "DAK Keyring is not readable");
886     } else {
887         my $command = "$gpg --list-keys";
888         my $output = &run_as($main::dak_user, $command);
889         &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
891         my $i=0;
892         foreach (@{$output->{'output'}}) {
893             if ($_ =~ m/^pub\s.*$/) {
894                 ($keys[$i]->{'pub'}->{'length'}, $keys[$i]->{'pub'}->{'uid'}, $keys[$i]->{'pub'}->{'created'}) = ($1, $2, $3)
895                 if $_ =~ m/^pub\s*?(\w*?)\/(\w*?)\s(\d{4}-\d{2}-\d{2})/;
896                 $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})\]/;
897                 $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})\]/;
898             } elsif ($_ =~ m/^sub\s.*$/) {
899                 ($keys[$i]->{'sub'}->{'length'}, $keys[$i]->{'sub'}->{'uid'}, $keys[$i]->{'sub'}->{'created'}) = ($1, $2, $3)
900                 if $_ =~ m/^sub\s*?(\w*?)\/(\w*?)\s(\d{4}-\d{2}-\d{2})/;
901                 $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})\]/;
902                 $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})\]/;
903             } elsif ($_ =~ m/^uid\s.*$/) {
904                 push @{$keys[$i]->{'uid'}}, $1 if $_ =~ m/^uid\s*?([^\s].*?)$/;
905             } elsif ($_ =~ m/^$/) {
906                 $i++;
907             }
908         }
909     }
911     my $i=0;
912     foreach my $key (@keys) {
913         #    &main::daemon_log(Dumper($key));
914         &add_content2xml_hash($out_hash, "answer".$i++, $key);
915     }
916     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
917     if (defined $forward_to_gosa) {
918         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
919     }
920     return &create_xml_string($out_hash);
924 sub import_dak_key {
925     my ($msg, $msg_hash) = @_;
926     my $source = @{$msg_hash->{'source'}}[0];
927     my $target = @{$msg_hash->{'target'}}[0];
928     my $header= @{$msg_hash->{'header'}}[0];
929     my $session_id = @{$msg_hash->{'session_id'}}[0];
930     my $key = &decode_base64(@{$msg_hash->{'key'}}[0]);
932     # build return message with twisted target and source
933     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
934     &add_content2xml_hash($out_hash, "session_id", $session_id);
936     my %data;
938     my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
940     my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
941     my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --keyring $keyring";
943     # Check if the keyrings are in place and writable
944     if(
945         &run_as($main::dak_user, "test -w $keyring")->{'resultCode'} != 0
946     ) {
947         &add_content2xml_hash($out_hash, "error", "DAK Keyring is not writable");
948     } else {
949         my $keyfile;
950         open($keyfile, ">/tmp/gosa_si_tmp_dak_key");
951         print $keyfile $key;
952         close($keyfile);
953         my $command = "$gpg --import /tmp/gosa_si_tmp_dak_key";
954         my $output = &run_as($main::dak_user, $command);
955         &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
956         unlink("/tmp/gosa_si_tmp_dak_key");
958         if($output->{'resultCode'} != 0) {
959             &add_content2xml_hash($out_hash, "error", "Import of DAK key failed! Output was '".$output->{'output'}."'");
960         } else {
961             &add_content2xml_hash($out_hash, "answer", "Import of DAK key successfull! Output was '".$output->{'output'}."'");
962         }
963     }
965     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
966     if (defined $forward_to_gosa) {
967         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
968     }
969     return &create_xml_string($out_hash);
973 sub remove_dak_key {
974     my ($msg, $msg_hash) = @_;
975     my $source = @{$msg_hash->{'source'}}[0];
976     my $target = @{$msg_hash->{'target'}}[0];
977     my $header= @{$msg_hash->{'header'}}[0];
978     my $session_id = @{$msg_hash->{'session_id'}}[0];
979     my $key = @{$msg_hash->{'keyid'}}[0];
980     # build return message with twisted target and source
981     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
982     &add_content2xml_hash($out_hash, "session_id", $session_id);
984     my %data;
986     my $keyring = $main::dak_signing_keys_directory."/keyring.gpg";
988     my $gpg_cmd = `which gpg`; chomp $gpg_cmd;
989     my $gpg     = "$gpg_cmd --no-default-keyring --no-random-seed --homedir ".$main::dak_signing_keys_directory." --keyring $keyring";
991     # Check if the keyrings are in place and writable
992     if(
993         &run_as($main::dak_user, "test -w $keyring")->{'resultCode'} != 0
994     ) {
995         &add_content2xml_hash($out_hash, "error", "DAK keyring is not writable");
996     } else {
997         # Check if the key is present in the keyring
998         if(&run_as($main::dak_user, "$gpg --list-keys $key")->{'resultCode'} == 0) {
999             my $command = "$gpg --batch --yes --delete-key $key";
1000             my $output = &run_as($main::dak_user, $command);
1001             &main::daemon_log("$session_id DEBUG: ".$output->{'command'}, 7);
1002         } else {
1003             &add_content2xml_hash($out_hash, "error", "DAK key with id '$key' was not found in keyring");
1004         }
1005     }
1007     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1008     if (defined $forward_to_gosa) {
1009         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1010     }
1011     return &create_xml_string($out_hash);
1015 #sub get_dak_queue {
1016 #    my ($msg, $msg_hash, $session_id) = @_;
1017 #    my %data;
1018 #    my $source = @{$msg_hash->{'source'}}[0];
1019 #    my $target = @{$msg_hash->{'target'}}[0];
1020 #    my $header= @{$msg_hash->{'header'}}[0];
1022 #    my %data;
1024 #    foreach my $dir ("unchecked", "new", "accepted") {
1025 #        foreach my $file(<"$main::dak_queue_directory/$dir/*.changes">) {
1026 #        }
1027 #    }
1029 #    my $out_msg = &build_msg("get_dak_queue", $target, $source, \%data);
1030 #    my @out_msg_l = ($out_msg);
1031 #    return @out_msg_l;
1032 #}
1035 # vim:ts=4:shiftwidth:expandtab
1036 1;