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 );
37 @EXPORT = @events;
39 use strict;
40 use warnings;
41 use GOSA::GosaSupportDaemon;
42 use Data::Dumper;
43 use Crypt::SmbHash;
44 use Net::ARP;
45 use Net::Ping;
46 use Socket;
47 use Time::HiRes qw( usleep);
49 BEGIN {}
51 END {}
53 ### Start ######################################################################
55 #&main::read_configfile($main::cfg_file, %cfg_defaults);
57 sub get_events {
58 return \@events;
59 }
61 sub send_user_msg {
63 # msg from gosa
64 # <xml><header>gosa_send_user_msg</header><source>GOSA</source><target>GOSA</target>
65 # <timestamp>20080429151605</timestamp>
66 # <users>andreas.rettenberger</users>
67 # <subject>hallo</subject>
68 # <message>test</message>
69 # <macaddress>GOSA</macaddress>
70 # </xml>
72 my ($msg, $msg_hash, $session_id) = @_ ;
73 my $header = @{$msg_hash->{'header'}}[0];
74 my $source = @{$msg_hash->{'source'}}[0];
75 my $target = @{$msg_hash->{'target'}}[0];
77 #my $subject = &decode_base64(@{$msg_hash->{'subject'}}[0]);
78 my $subject = @{$msg_hash->{'subject'}}[0];
79 my $from = @{$msg_hash->{'from'}}[0];
80 my @users = @{$msg_hash->{'users'}};
81 my @groups = @{$msg_hash->{'groups'}}[0];
82 my $delivery_time = @{$msg_hash->{'delivery_time'}}[0];
83 #my $message = &decode_base64(@{$msg_hash->{'message'}}[0]);
84 my $message = @{$msg_hash->{'message'}}[0];
86 # keep job queue uptodate if necessary
87 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
88 if( defined $jobdb_id) {
89 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
90 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
91 my $res = $main::job_db->exec_statement($sql_statement);
92 }
94 # error handling
95 if (not $delivery_time =~ /^\d{14}$/) {
96 my $error_string = "delivery_time '$delivery_time' is not a valid timestamp, please use format 'yyyymmddhhmmss'";
97 &main::daemon_log("$session_id ERROR: $error_string", 1);
98 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
99 }
101 # add incoming message to messaging_db
102 my $new_msg_id = 1;
103 my $new_msg_id_sql = "SELECT MAX(CAST(id AS INTEGER)) FROM $main::messaging_tn";
104 my $new_msg_id_res = $main::messaging_db->exec_statement($new_msg_id_sql);
105 if (defined @{@{$new_msg_id_res}[0]}[0] ) {
106 $new_msg_id = int(@{@{$new_msg_id_res}[0]}[0]);
107 $new_msg_id += 1;
108 }
110 # highlight user name and group name
111 my @receiver_l;
112 @users = map(push(@receiver_l, "u_$_"), @users);
113 #@groups = map(push(@receiver_l, "g_$_"), @groups);
114 # TODO
115 # handling, was passiert wenn in einer liste nix drin steht
116 # handling von groups hinzufügen
119 my $func_dic = {table=>$main::messaging_tn,
120 primkey=>[],
121 id=>$new_msg_id,
122 subject=>$subject,
123 message_from=>$from,
124 message_to=>join(",", @receiver_l),
125 flag=>"n",
126 direction=>"in",
127 delivery_time=>$delivery_time,
128 message=>$message,
129 timestamp=>&get_time(),
130 };
131 my $res = $main::messaging_db->add_dbentry($func_dic);
132 if (not $res == 0) {
133 &main::daemon_log("$session_id ERROR: gosaTriggered.pm: cannot add message to message_db: $res", 1);
134 } else {
135 &main::daemon_log("$session_id INFO: gosaTriggered.pm: message with subject '$subject' successfully added to message_db", 5);
136 }
138 return;
139 }
141 #sub send_user_msg_OLD {
142 # my ($msg, $msg_hash, $session_id) = @_ ;
143 # my @out_msg_l;
144 # my @user_list;
145 # my @group_list;
146 #
147 # my $header = @{$msg_hash->{'header'}}[0];
148 # my $source = @{$msg_hash->{'source'}}[0];
149 # my $target = @{$msg_hash->{'target'}}[0];
150 # my $message = @{$msg_hash->{'message'}}[0];
151 # if( exists $msg_hash->{'user'} ) { @user_list = @{$msg_hash->{'user'}}; }
152 # if( exists $msg_hash->{'group'} ) { @group_list = @{$msg_hash->{'group'}}; }
153 #
154 # my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
155 # if( defined $jobdb_id) {
156 # my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
157 # &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
158 # my $res = $main::job_db->exec_statement($sql_statement);
159 # }
160 #
161 # # error handling
162 # if( not @user_list && not @group_list ) {
163 # &main::daemon_log("$session_id WARNING: no user-tag or a group-tag specified in 'send_user_msg'", 3);
164 # return ("<xml><header>$header</header><source>GOSA</source><target>GOSA</target>".
165 # "<error_string>no user-tag or a group-tag specified in 'send_user_msg'</error_string></xml>");
166 # }
167 # if( not defined $message ) {
168 # &main::daemon_log("$session_id WARNING: no message-tag specified in 'send_user_msg'", 3);
169 # return ("<xml><header>$header</header><source>GOSA</source><target>GOSA</target>".
170 # "<error_string>no message-tag specified in 'send_user_msg'</error_string></xml>");
171 #
172 # }
173 #
174 # # resolve groups to users
175 # my $ldap_handle = &main::get_ldap_handle($session_id);
176 # if( @group_list ) {
177 # if( not defined $ldap_handle ) {
178 # &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
179 # return ();
180 # }
181 # foreach my $group (@group_list) { # Perform search
182 # my $mesg = $ldap_handle->search(
183 # base => $main::ldap_base,
184 # scope => 'sub',
185 # attrs => ['memberUid'],
186 # filter => "(&(objectClass=posixGroup)(cn=$group)(memberUid=*))");
187 # if($mesg->code) {
188 # &main::daemon_log($mesg->error, 1);
189 # return ();
190 # }
191 # my $entry= $mesg->entry(0);
192 # my @users= $entry->get_value("memberUid");
193 # foreach my $user (@users) { push(@user_list, $user); }
194 # }
195 # }
196 #
197 # # drop multiple users in @user_list
198 # my %seen = ();
199 # foreach my $user (@user_list) {
200 # $seen{$user}++;
201 # }
202 # @user_list = keys %seen;
203 #
204 # # build xml messages sended to client where user is logged in
205 # foreach my $user (@user_list) {
206 # my $sql_statement = "SELECT * FROM $main::login_users_tn WHERE user='$user'";
207 # my $db_res = $main::login_users_db->select_dbentry($sql_statement);
208 #
209 # if(0 == keys(%{$db_res})) {
210 #
211 # } else {
212 # while( my($hit, $content) = each %{$db_res} ) {
213 # my $out_hash = &create_xml_hash('send_user_msg', $main::server_address, $content->{'client'});
214 # &add_content2xml_hash($out_hash, 'message', $message);
215 # &add_content2xml_hash($out_hash, 'user', $user);
216 # if( exists $msg_hash->{'jobdb_id'} ) {
217 # &add_content2xml_hash($out_hash, 'jobdb_id', @{$msg_hash->{'jobdb_id'}}[0]);
218 # }
219 # my $out_msg = &create_xml_string($out_hash);
220 # push(@out_msg_l, $out_msg);
221 # }
222 # }
223 # }
224 #
225 # return @out_msg_l;
226 #}
229 sub recreate_fai_server_db {
230 my ($msg, $msg_hash, $session_id) = @_ ;
231 my $out_msg;
233 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
234 if( defined $jobdb_id) {
235 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
236 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
237 my $res = $main::job_db->exec_statement($sql_statement);
238 }
240 $main::fai_server_db->create_table("new_fai_server", \@main::fai_server_col_names);
241 &main::create_fai_server_db("new_fai_server",undef,"dont", $session_id);
242 $main::fai_server_db->move_table("new_fai_server", $main::fai_server_tn);
244 my @out_msg_l = ( $out_msg );
245 return @out_msg_l;
246 }
249 sub recreate_fai_release_db {
250 my ($msg, $msg_hash, $session_id) = @_ ;
251 my $out_msg;
253 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
254 if( defined $jobdb_id) {
255 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
256 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
257 my $res = $main::job_db->exec_statement($sql_statement);
258 }
260 $main::fai_release_db->create_table("new_fai_release", \@main::fai_release_col_names);
261 &main::create_fai_release_db("new_fai_release", $session_id);
262 $main::fai_release_db->move_table("new_fai_release", $main::fai_release_tn);
264 my @out_msg_l = ( $out_msg );
265 return @out_msg_l;
266 }
269 sub recreate_packages_list_db {
270 my ($msg, $msg_hash, $session_id) = @_ ;
271 my $out_msg;
273 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
274 if( defined $jobdb_id) {
275 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
276 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
277 my $res = $main::job_db->exec_statement($sql_statement);
278 }
280 &main::create_packages_list_db;
282 my @out_msg_l = ( $out_msg );
283 return @out_msg_l;
284 }
287 sub get_login_usr_for_client {
288 my ($msg, $msg_hash, $session_id) = @_ ;
289 my $header = @{$msg_hash->{'header'}}[0];
290 my $source = @{$msg_hash->{'source'}}[0];
291 my $target = @{$msg_hash->{'target'}}[0];
292 my $client = @{$msg_hash->{'client'}}[0];
294 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
295 if( defined $jobdb_id) {
296 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
297 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
298 my $res = $main::job_db->exec_statement($sql_statement);
299 }
301 $header =~ s/^gosa_//;
303 my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$client' OR macaddress LIKE '$client'";
304 my $res = $main::known_clients_db->select_dbentry($sql_statement);
306 my $out_msg = "<xml><header>$header</header><source>$target</source><target>$source</target>";
307 $out_msg .= &db_res2xml($res);
308 $out_msg .= "</xml>";
310 my @out_msg_l = ( $out_msg );
311 return @out_msg_l;
312 }
315 sub get_client_for_login_usr {
316 my ($msg, $msg_hash, $session_id) = @_ ;
317 my $header = @{$msg_hash->{'header'}}[0];
318 my $source = @{$msg_hash->{'source'}}[0];
319 my $target = @{$msg_hash->{'target'}}[0];
321 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
322 if( defined $jobdb_id) {
323 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
324 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
325 my $res = $main::job_db->exec_statement($sql_statement);
326 }
328 my $usr = @{$msg_hash->{'usr'}}[0];
329 $header =~ s/^gosa_//;
331 my $sql_statement = "SELECT * FROM known_clients WHERE login LIKE '%$usr%'";
332 my $res = $main::known_clients_db->select_dbentry($sql_statement);
334 my $out_msg = "<xml><header>$header</header><source>$target</source><target>$source</target>";
335 $out_msg .= &db_res2xml($res);
336 $out_msg .= "</xml>";
337 my @out_msg_l = ( $out_msg );
338 return @out_msg_l;
340 }
343 #sub ping {
344 # my ($msg, $msg_hash, $session_id) = @_ ;
345 # my $out_msg = $msg;
346 # my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
347 # if( defined $jobdb_id) {
348 # my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
349 # &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
350 # my $res = $main::job_db->exec_statement($sql_statement);
351 # }
352 #
353 # $out_msg =~ s/<header>gosa_/<header>/;
354 #
355 # my @out_msg_l = ( $out_msg );
356 # return @out_msg_l;
357 #}
358 sub ping {
359 my ($msg, $msg_hash, $session_id) = @_ ;
360 my ($sql, $res);
361 my $out_msg = $msg;
362 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
363 if( defined $jobdb_id) {
364 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
365 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
366 my $res = $main::job_db->exec_statement($sql_statement);
367 }
369 $out_msg =~ s/<header>gosa_/<header>/;
371 # send message
372 my $header = @{$msg_hash->{header}}[0];
373 my $target = @{$msg_hash->{target}}[0];
375 $sql = "SELECT * FROM $main::known_clients_tn WHERE ((hostname='$target') || (macaddress LIKE '$target'))";
376 $res = $main::known_clients_db->exec_statement($sql);
377 my $host_name = @{@$res[0]}[0];
378 $out_msg =~ s/<target>\S+<\/target>/<target>$host_name<\/target>/;
379 $out_msg =~ s/<source>\S+<\/source>/<source>$main::server_address<\/source>/;
380 $out_msg =~ s/<\/xml>/<session_id>$session_id<\/session_id><\/xml>/;
381 my $host_key = @{@$res[0]}[2];
383 my $error = &main::send_msg_to_target($out_msg, $host_name, $host_key, $header, $session_id);
384 #if ($error != 0) {}
386 my $message_id;
387 while (1) {
388 $sql = "SELECT * FROM $main::incoming_tn WHERE headertag='answer_$session_id'";
389 $res = $main::incoming_db->exec_statement($sql);
390 if (ref @$res[0] eq "ARRAY") {
391 $message_id = @{@$res[0]}[0];
392 last;
393 }
394 usleep(100000);
395 }
396 my $answer_xml = @{@$res[0]}[3];
397 my %data = ( 'answer_xml' => 'bin noch da' );
398 my $answer_msg = &build_msg("got_new_ping", "$main::server_address", "GOSA", \%data);
400 $sql = "DELETE FROM $main::incoming_tn WHERE id=$message_id";
401 $res = $main::incoming_db->exec_statement($sql);
404 my @answer_msg_l = ( $answer_msg );
405 return @answer_msg_l;
406 }
410 sub gen_smb_hash {
411 my ($msg, $msg_hash, $session_id) = @_ ;
412 my $source = @{$msg_hash->{source}}[0];
413 my $target = @{$msg_hash->{target}}[0];
414 my $password = @{$msg_hash->{password}}[0];
416 my %data= ('hash' => join(q[:], ntlmgen $password));
417 my $out_msg = &build_msg("gen_smb_hash", $target, $source, \%data );
418 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
419 if (defined $forward_to_gosa) {
420 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
421 }
423 return ( $out_msg );
424 }
427 sub network_completition {
428 my ($msg, $msg_hash, $session_id) = @_ ;
429 my $source = @{$msg_hash->{source}}[0];
430 my $target = @{$msg_hash->{target}}[0];
431 my $name = @{$msg_hash->{hostname}}[0];
433 # Can we resolv the name?
434 my %data;
435 if (inet_aton($name)){
436 my $address = inet_ntoa(inet_aton($name));
437 my $p = Net::Ping->new('tcp');
438 my $mac= "";
439 if ($p->ping($address, 1)){
440 $mac = Net::ARP::arp_lookup("", $address);
441 }
443 %data= ('ip' => $address, 'mac' => $mac);
444 } else {
445 %data= ('ip' => '', 'mac' => '');
446 }
448 my $out_msg = &build_msg("network_completition", $target, $source, \%data );
449 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
450 if (defined $forward_to_gosa) {
451 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
452 }
454 return ( $out_msg );
455 }
458 sub detect_hardware {
459 my ($msg, $msg_hash, $session_id) = @_ ;
460 # just forward msg to client, but dont forget to split off 'gosa_' in header
461 my $source = @{$msg_hash->{source}}[0];
462 my $target = @{$msg_hash->{target}}[0];
463 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
464 if( defined $jobdb_id) {
465 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
466 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
467 my $res = $main::job_db->exec_statement($sql_statement);
468 }
470 my $out_hash = &create_xml_hash("detect_hardware", $source, $target);
471 if( defined $jobdb_id ) {
472 &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id);
473 }
474 my $out_msg = &create_xml_string($out_hash);
476 my @out_msg_l = ( $out_msg );
477 return @out_msg_l;
479 }
482 sub trigger_reload_ldap_config {
483 my ($msg, $msg_hash, $session_id) = @_ ;
484 my $target = @{$msg_hash->{target}}[0];
486 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
487 if( defined $jobdb_id) {
488 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
489 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
490 my $res = $main::job_db->exec_statement($sql_statement);
491 }
493 my $out_msg = &ClientPackages::new_ldap_config($target, $session_id);
494 my @out_msg_l = ( $out_msg );
496 return @out_msg_l;
497 }
500 sub set_activated_for_installation {
501 my ($msg, $msg_hash, $session_id) = @_;
502 my $header = @{$msg_hash->{header}}[0];
503 my $source = @{$msg_hash->{source}}[0];
504 my $target = @{$msg_hash->{target}}[0];
505 my @out_msg_l;
507 # update status of job
508 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
509 if( defined $jobdb_id) {
510 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
511 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
512 my $res = $main::job_db->exec_statement($sql_statement);
513 }
515 # create set_activated_for_installation message for delivery
516 my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $target);
517 if( defined $jobdb_id ) {
518 &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id);
519 }
520 my $out_msg = &create_xml_string($out_hash);
521 push(@out_msg_l, $out_msg);
523 return @out_msg_l;
524 }
527 sub trigger_action_faireboot {
528 my ($msg, $msg_hash, $session_id) = @_;
529 my $macaddress = @{$msg_hash->{target}}[0];
530 my $source = @{$msg_hash->{source}}[0];
532 my @out_msg_l;
533 $msg =~ s/<header>gosa_trigger_action_faireboot<\/header>/<header>trigger_action_faireboot<\/header>/;
534 push(@out_msg_l, $msg);
536 &main::change_goto_state('locked', \@{$msg_hash->{target}}, $session_id);
537 &main::change_fai_state('install', \@{$msg_hash->{target}}, $session_id);
539 # delete all jobs from jobqueue which correspond to fai
540 my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE (macaddress='$macaddress' AND ".
541 "status='processing')";
542 $main::job_db->del_dbentry($sql_statement );
544 return @out_msg_l;
545 }
548 sub trigger_action_lock {
549 my ($msg, $msg_hash, $session_id) = @_;
550 my $macaddress = @{$msg_hash->{target}}[0];
551 my $source = @{$msg_hash->{source}}[0];
553 &main::change_goto_state('locked', \@{$msg_hash->{target}}, $session_id);
554 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
555 if( defined $jobdb_id) {
556 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
557 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
558 my $res = $main::job_db->exec_statement($sql_statement);
559 }
561 my @out_msg_l;
562 return @out_msg_l;
563 }
566 sub trigger_action_activate {
567 my ($msg, $msg_hash, $session_id) = @_;
568 my $macaddress = @{$msg_hash->{target}}[0];
569 my $source = @{$msg_hash->{source}}[0];
571 &main::change_goto_state('active', \@{$msg_hash->{target}}, $session_id);
572 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
573 if( defined $jobdb_id) {
574 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
575 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
576 my $res = $main::job_db->exec_statement($sql_statement);
577 }
579 my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $macaddress);
580 if( exists $msg_hash->{'jobdb_id'} ) {
581 &add_content2xml_hash($out_hash, 'jobdb_id', @{$msg_hash->{'jobdb_id'}}[0]);
582 }
583 my $out_msg = &create_xml_string($out_hash);
585 return ( $out_msg );
586 }
589 sub trigger_action_localboot {
590 my ($msg, $msg_hash, $session_id) = @_;
591 $msg =~ s/<header>gosa_trigger_action_localboot<\/header>/<header>trigger_action_localboot<\/header>/;
592 &main::change_fai_state('localboot', \@{$msg_hash->{target}}, $session_id);
593 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
594 if( defined $jobdb_id) {
595 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
596 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
597 my $res = $main::job_db->exec_statement($sql_statement);
598 }
600 my @out_msg_l = ($msg);
601 return @out_msg_l;
602 }
605 sub trigger_action_halt {
606 my ($msg, $msg_hash, $session_id) = @_;
607 $msg =~ s/<header>gosa_trigger_action_halt<\/header>/<header>trigger_action_halt<\/header>/;
609 &main::change_fai_state('halt', \@{$msg_hash->{target}}, $session_id);
610 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
611 if( defined $jobdb_id) {
612 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
613 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
614 my $res = $main::job_db->exec_statement($sql_statement);
615 }
617 my @out_msg_l = ($msg);
618 return @out_msg_l;
619 }
622 sub trigger_action_reboot {
623 my ($msg, $msg_hash, $session_id) = @_;
624 $msg =~ s/<header>gosa_trigger_action_reboot<\/header>/<header>trigger_action_reboot<\/header>/;
626 &main::change_fai_state('reboot', \@{$msg_hash->{target}}, $session_id);
627 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
628 if( defined $jobdb_id) {
629 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
630 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
631 my $res = $main::job_db->exec_statement($sql_statement);
632 }
634 my @out_msg_l = ($msg);
635 return @out_msg_l;
636 }
639 sub trigger_action_memcheck {
640 my ($msg, $msg_hash, $session_id) = @_ ;
641 $msg =~ s/<header>gosa_trigger_action_memcheck<\/header>/<header>trigger_action_memcheck<\/header>/;
643 &main::change_fai_state('memcheck', \@{$msg_hash->{target}}, $session_id);
644 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
645 if( defined $jobdb_id) {
646 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
647 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
648 my $res = $main::job_db->exec_statement($sql_statement);
649 }
651 my @out_msg_l = ($msg);
652 return @out_msg_l;
653 }
656 sub trigger_action_reinstall {
657 my ($msg, $msg_hash, $session_id) = @_;
658 $msg =~ s/<header>gosa_trigger_action_reinstall<\/header>/<header>trigger_action_reinstall<\/header>/;
660 &main::change_fai_state('reinstall', \@{$msg_hash->{target}}, $session_id);
662 my %data = ( 'macAddress' => \@{$msg_hash->{target}} );
663 my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
664 my @out_msg_l = ($wake_msg, $msg);
665 return @out_msg_l;
666 }
669 sub trigger_action_update {
670 my ($msg, $msg_hash, $session_id) = @_;
671 $msg =~ s/<header>gosa_trigger_action_update<\/header>/<header>trigger_action_update<\/header>/;
673 &main::change_fai_state('update', \@{$msg_hash->{target}}, $session_id);
675 my %data = ( 'macAddress' => \@{$msg_hash->{target}} );
676 my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
677 my @out_msg_l = ($wake_msg, $msg);
678 return @out_msg_l;
679 }
682 sub trigger_action_instant_update {
683 my ($msg, $msg_hash, $session_id) = @_;
684 $msg =~ s/<header>gosa_trigger_action_instant_update<\/header>/<header>trigger_action_instant_update<\/header>/;
686 &main::change_fai_state('update', \@{$msg_hash->{target}}, $session_id);
688 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
689 if( defined $jobdb_id) {
690 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
691 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
692 my $res = $main::job_db->exec_statement($sql_statement);
693 }
695 my %data = ( 'macAddress' => \@{$msg_hash->{target}} );
696 my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
697 my @out_msg_l = ($wake_msg, $msg);
698 return @out_msg_l;
699 }
702 sub trigger_action_sysinfo {
703 my ($msg, $msg_hash, $session_id) = @_;
704 $msg =~ s/<header>gosa_trigger_action_sysinfo<\/header>/<header>trigger_action_sysinfo<\/header>/;
706 &main::change_fai_state('sysinfo', \@{$msg_hash->{target}}, $session_id);
707 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
708 if( defined $jobdb_id) {
709 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
710 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
711 my $res = $main::job_db->exec_statement($sql_statement);
712 }
714 my @out_msg_l = ($msg);
715 return @out_msg_l;
716 }
719 sub new_key_for_client {
720 my ($msg, $msg_hash, $session_id) = @_;
722 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
723 if( defined $jobdb_id) {
724 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
725 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
726 my $res = $main::job_db->exec_statement($sql_statement);
727 }
729 $msg =~ s/<header>gosa_new_key_for_client<\/header>/<header>new_key<\/header>/;
730 my @out_msg_l = ($msg);
731 return @out_msg_l;
732 }
735 sub trigger_action_rescan {
736 my ($msg, $msg_hash, $session_id) = @_;
738 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
739 if( defined $jobdb_id) {
740 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
741 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
742 my $res = $main::job_db->exec_statement($sql_statement);
743 }
746 $msg =~ s/<header>gosa_trigger_action_rescan<\/header>/<header>trigger_action_rescan<\/header>/;
747 my @out_msg_l = ($msg);
748 return @out_msg_l;
749 }
752 sub trigger_action_wake {
753 my ($msg, $msg_hash, $session_id) = @_;
755 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
756 if( defined $jobdb_id) {
757 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
758 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
759 my $res = $main::job_db->exec_statement($sql_statement);
760 }
763 my %data = ( 'macAddress' => \@{$msg_hash->{target}} );
764 my $out_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
765 my @out_msg_l = ($out_msg);
766 return @out_msg_l;
767 }
770 sub get_available_kernel {
771 my ($msg, $msg_hash, $session_id) = @_;
773 my $source = @{$msg_hash->{'source'}}[0];
774 my $target = @{$msg_hash->{'target'}}[0];
775 my $release= @{$msg_hash->{'release'}}[0];
777 my @kernel;
778 # Get Kernel packages for release
779 my $sql_statement = "SELECT * FROM $main::packages_list_tn WHERE distribution='$release' AND package LIKE 'linux\-image\-%'";
780 my $res_hash = $main::packages_list_db->select_dbentry($sql_statement);
781 my %data;
782 my $i=1;
784 foreach my $package (keys %{$res_hash}) {
785 $data{"answer".$i++}= $data{"answer".$i++}= ${$res_hash}{$package}->{'package'};
786 }
787 $data{"answer".$i++}= "default";
789 my $out_msg = &build_msg("get_available_kernel", $target, $source, \%data);
790 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
791 if (defined $forward_to_gosa) {
792 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
793 }
795 return ( $out_msg );
796 }
799 sub trigger_activate_new {
800 my ($msg, $msg_hash, $session_id) = @_;
802 my $source = @{$msg_hash->{'source'}}[0];
803 my $target = @{$msg_hash->{'target'}}[0];
804 my $header= @{$msg_hash->{'header'}}[0];
805 my $mac= (defined($msg_hash->{'mac'}))?@{$msg_hash->{'mac'}}[0]:undef;
806 my $ogroup= (defined($msg_hash->{'ogroup'}))?@{$msg_hash->{'ogroup'}}[0]:undef;
807 my $timestamp= (defined($msg_hash->{'timestamp'}))?@{$msg_hash->{'timestamp'}}[0]:undef;
808 my $base= (defined($msg_hash->{'base'}))?@{$msg_hash->{'base'}}[0]:undef;
809 my $hostname= (defined($msg_hash->{'fqdn'}))?@{$msg_hash->{'fqdn'}}[0]:undef;
810 my $ip_address= (defined($msg_hash->{'ip'}))?@{$msg_hash->{'ip'}}[0]:undef;
811 my $dhcp_statement= (defined($msg_hash->{'dhcp'}))?@{$msg_hash->{'dhcp'}}[0]:undef;
812 my $jobdb_id= (defined($msg_hash->{'jobdb_id'}))?@{$msg_hash->{'jobdb_id'}}[0]:undef;
814 my $ldap_handle = &main::get_ldap_handle();
815 my $ldap_entry;
816 my $ogroup_entry;
817 my $changed_attributes_counter = 0;
819 eval {
821 my $ldap_mesg= $ldap_handle->search(
822 base => $main::ldap_base,
823 scope => 'sub',
824 filter => "(&(objectClass=gosaGroupOfnames)(cn=$ogroup))",
825 );
826 if($ldap_mesg->count == 1) {
827 $ogroup_entry= $ldap_mesg->pop_entry();
828 } elsif ($ldap_mesg->count == 0) {
829 &main::daemon_log("ERROR: A GosaGroupOfNames with cn '$ogroup' was not found in base '".$main::ldap_base."'!", 1);
830 } else {
831 &main::daemon_log("ERROR: More than one ObjectGroups with cn '$ogroup' was found in base '".$main::ldap_base."'!", 1);
832 }
834 # build the base, use optional base parameter or take it from ogroup
835 if(!(defined($base) && (length($base) > 0))) {
836 # Subtract the ObjectGroup cn
837 $base = $1 if $ogroup_entry->dn =~ /cn=$ogroup,ou=groups,(.*)$/;
838 }
840 # prepend ou=systems
841 $base = "ou=systems,".$base;
843 # Search for an existing entry (should be in ou=incoming)
844 $ldap_mesg= $ldap_handle->search(
845 base => $main::ldap_base,
846 scope => 'sub',
847 filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
848 );
850 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
852 if($ldap_mesg->count == 1) {
853 &main::daemon_log("DEBUG: One system with mac address '$mac' was found in base '".$main::ldap_base."'!", 6);
854 # Get the entry from LDAP
855 $ldap_entry= $ldap_mesg->pop_entry();
857 if(!($ldap_entry->dn() eq "cn=".$ldap_entry->get_value('cn').",$base")) {
858 # Move the entry to the new ou
859 $ldap_entry->changetype('moddn');
860 $ldap_entry->add(
861 newrdn => "cn=".$ldap_entry->get_value('cn'),
862 deleteoldrdn => 1,
863 newsuperior => $base,
864 );
865 }
867 }
869 $ldap_mesg= $ldap_handle->search(
870 base => $main::ldap_base,
871 scope => 'sub',
872 filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
873 );
875 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
877 if($ldap_mesg->count == 1) {
878 $ldap_entry= $ldap_mesg->pop_entry();
879 # Check for needed objectClasses
880 my $oclasses = $ldap_entry->get_value('objectClass', asref => 1);
881 foreach my $oclass ("FAIobject", "GOhard") {
882 if(!(scalar grep $_ eq $oclass, map {$_ => 1} @$oclasses)) {
883 &main::daemon_log("Adding objectClass $oclass", 1);
884 $ldap_entry->add(
885 objectClass => $oclass,
886 );
887 my $oclass_result = $ldap_entry->update($ldap_handle);
888 }
889 }
891 # Set FAIstate
892 if(defined($ldap_entry->get_value('FAIstate'))) {
893 if(!($ldap_entry->get_value('FAIstate') eq 'install')) {
894 $ldap_entry->replace(
895 'FAIstate' => 'install'
896 );
897 my $replace_result = $ldap_entry->update($ldap_handle);
898 }
899 } else {
900 $ldap_entry->add(
901 'FAIstate' => 'install'
902 );
903 my $add_result = $ldap_entry->update($ldap_handle);
904 }
907 } elsif ($ldap_mesg->count == 0) {
908 # TODO: Create a new entry
909 # $ldap_entry = Net::LDAP::Entry->new();
910 # $ldap_entry->dn("cn=$mac,$base");
911 &main::daemon_log("WARNING: No System with mac address '$mac' was found in base '".$main::ldap_base."'! Re-queuing job.", 4);
912 $main::job_db->exec_statement("UPDATE jobs SET status = 'waiting', timestamp = '".&get_time()."' WHERE id = $jobdb_id");
913 } else {
914 &main::daemon_log("ERROR: More than one system with mac address '$mac' was found in base '".$main::ldap_base."'!", 1);
915 }
917 # Add to ObjectGroup
918 if(!(scalar grep $_, map {$_ => 1} $ogroup_entry->get_value('member', asref => 1))) {
919 $ogroup_entry->add (
920 'member' => $ldap_entry->dn(),
921 );
922 my $ogroup_result = $ogroup_entry->update($ldap_handle);
923 if ($ogroup_result->code() != 0) {
924 &main::daemon_log("ERROR: Updating the ObjectGroup '$ogroup' failed (code '".$ogroup_result->code()."') with '".$ogroup_result->{'errorMessage'}."'!", 1);
925 }
926 }
928 # Finally set gotoMode to active
929 if(defined($ldap_entry->get_value('gotoMode'))) {
930 if(!($ldap_entry->get_value('gotoMode') eq 'active')) {
931 $ldap_entry->replace(
932 'gotoMode' => 'active'
933 );
934 my $activate_result = $ldap_entry->update($ldap_handle);
935 if ($activate_result->code() != 0) {
936 &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
937 }
938 }
939 } else {
940 $ldap_entry->add(
941 'gotoMode' => 'active'
942 );
943 my $activate_result = $ldap_entry->update($ldap_handle);
944 if ($activate_result->code() != 0) {
945 &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
946 }
947 }
948 };
949 if($@) {
950 &main::daemon_log("ERROR: activate_new failed with '$@'!", 1);
951 }
953 # Delete job
954 $main::job_db->exec_statement("DELETE FROM jobs WHERE id = $jobdb_id");
956 my %data;
957 my $out_msg = &build_msg("activate_new", $target, $source, \%data);
958 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
959 if (defined $forward_to_gosa) {
960 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
961 }
963 return ( $out_msg );
964 }
967 1;